]> Devoid-pointer.net GitWeb - omnibook.git/commitdiff
* Merge experimental branch changes (235:HEAD) back to trunk
authorMathieu Bérard <mathieu.berard@crans.org>
Sun, 4 Feb 2007 02:11:15 +0000 (02:11 +0000)
committerMathieu Bérard <mathieu.berard@crans.org>
Sun, 4 Feb 2007 02:11:15 +0000 (02:11 +0000)
  But don't merge fan feature for TSM70, as it is not yet ready

Makefile
acpi.c
cooling.c [new file with mode: 0644]
doc/ChangeLog
dump.c
hardware.h
muteled.c
omnibook.h
pio.c
throttling.c [new file with mode: 0644]
touchpad.c

index 71ec838c972792f9042ab23113c97b3cb03905ac..bc4b2fd98ab2e821c3b7d7ab86a3b54eb217109a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -48,9 +48,9 @@ EXTRA_LDFLAGS +=  $(src)/sections.lds
 
 
 OBJS   = init.o lib.o ec.o kbc.o pio.o compal.o acpi.o nbsmi.o \
-          ac.o battery.o blank.o bluetooth.o display.o dock.o dump.o \
-         fan.o fan_policy.o hotkeys.o info.o lcd.o muteled.o polling.o \
-         temperature.o touchpad.o wireless.o
+          ac.o battery.o blank.o bluetooth.o cooling.o display.o dock.o \
+         dump.o fan.o fan_policy.o hotkeys.o info.o lcd.o muteled.o \
+         polling.o temperature.o touchpad.o wireless.o throttling.o 
 
 obj-m         += $(MODULE_NAME).o
 omnibook-objs := $(OBJS)
diff --git a/acpi.c b/acpi.c
index f9117fa888f0c2497e3a9a77c31ce255833382a8..457939c32a1deb40249f4808c44c2f5bdea46fed 100644 (file)
--- a/acpi.c
+++ b/acpi.c
@@ -44,6 +44,9 @@
 #define        CRT_CSTE        0x2
 #define        TVO_CSTE        0x4
 
+#define GET_THROTTLE_METHOD "THRO"
+#define        SET_THROTTLE_METHOD "CLCK"
+
 static char ec_dev_list[][20] = {
        "\\_SB.PCI0.LPCB.EC0",
        "\\_SB.PCI0.LPC0.EC0",
@@ -52,11 +55,11 @@ static char ec_dev_list[][20] = {
 #define TOSHIBA_ACPI_BT_CLASS "bluetooth"
 #define TOSHIBA_ACPI_DEVICE_NAME "bluetooth adapter"
 
-#define TOSH_BT_ACTIVATE_USB "AUSB"
-#define TOSH_BT_DISABLE_USB  "DUSB"
-#define TOSH_BT_POWER_ON     "BTPO"
-#define TOSH_BT_POWER_OFF    "BTPF"
-#define TOSH_BT_STATUS      "BTST"
+#define TOSH_BT_ACTIVATE_USB   "AUSB"
+#define TOSH_BT_DISABLE_USB    "DUSB"
+#define TOSH_BT_POWER_ON       "BTPO"
+#define TOSH_BT_POWER_OFF      "BTPF"
+#define TOSH_BT_STATUS         "BTST"
 #define        TOSH_BT_KSST_MASK       0x1
 #define        TOSH_BT_USB_MASK        0x40
 #define        TOSH_BT_POWER_MASK      0x80
@@ -175,6 +178,7 @@ struct omnibook_backend acpi_backend;
 
 /*
  * Execute an ACPI method which return either an integer or nothing
+ * and that require 0 or 1 numerical argument
  * (acpi_evaluate_object wrapper)
  */
 static int omnibook_acpi_execute(acpi_handle dev_handle, char *method, const int *param, int *result)
@@ -246,7 +250,7 @@ static int omnibook_acpi_bt_add(struct acpi_device *device)
        
        dprintk("Enabling found Toshiba Bluetooth ACPI device.\n");
        strcpy(acpi_device_name(device), TOSHIBA_ACPI_DEVICE_NAME);
-        strcpy(acpi_device_class(device), TOSHIBA_ACPI_BT_CLASS);
+       strcpy(acpi_device_class(device), TOSHIBA_ACPI_BT_CLASS);
 
        /* Save handle in backend private data structure. ugly. */
        priv_data->bt_handle = device->handle;
@@ -273,7 +277,7 @@ static int get_bt_status(const struct acpi_backend_data *priv_data, unsigned int
        int retval = 0;
        int raw_state;
 
-       if ((retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_STATUS, 0, &raw_state)))
+       if ((retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_STATUS, NULL, &raw_state)))
                return retval;
 
        dprintk("BTST raw_state: %x\n", raw_state);
@@ -293,7 +297,7 @@ static int get_wireless_status(const struct acpi_backend_data *priv_data, unsign
        int retval = 0;
        int raw_state;
 
-       if ((retval = omnibook_acpi_execute(priv_data->ec_handle, GET_WIRELESS_METHOD, 0, &raw_state)))
+       if ((retval = omnibook_acpi_execute(priv_data->ec_handle, GET_WIRELESS_METHOD, NULL, &raw_state)))
                return retval;
 
        dprintk("get_wireless raw_state: %x\n", raw_state);
@@ -363,7 +367,7 @@ static int omnibook_acpi_get_display(const struct omnibook_operation *io_op, uns
        int raw_state = 0;
        struct acpi_backend_data *priv_data = io_op->backend->data;
        
-       retval = omnibook_acpi_execute(priv_data->ec_handle, GET_DISPLAY_METHOD, 0, &raw_state);
+       retval = omnibook_acpi_execute(priv_data->ec_handle, GET_DISPLAY_METHOD, NULL, &raw_state);
        if (retval < 0)
                return retval;
 
@@ -419,6 +423,40 @@ static int omnibook_acpi_set_display(const struct omnibook_operation *io_op, uns
        return DISPLAY_LCD_ON | DISPLAY_CRT_ON | DISPLAY_TVO_ON;
 }
 
+static int omnibook_acpi_get_throttle(const struct omnibook_operation *io_op, unsigned int *state)
+{
+       int retval;
+       int thtl_en = 0, thtl_dty = 0;
+       int param;
+       struct acpi_backend_data *priv_data = io_op->backend->data;
+       
+       param = 0;
+       /* Read THEN aka THTL_EN in ICH6M datasheets */
+       retval = omnibook_acpi_execute(priv_data->ec_handle, GET_THROTTLE_METHOD, &param, &thtl_en); 
+       if ( thtl_en == 0 ) {
+               *state = 0;
+               return retval;
+       }
+       param = 1;
+       /* Read DUTY aka THTL_DTY in ICH6M datasheets */
+       retval = omnibook_acpi_execute(priv_data->ec_handle, GET_THROTTLE_METHOD, &param, &thtl_dty);
+       WARN_ON(thtl_dty > 7); /* We shouldn't encounter more than 7 throttling level */
+       *state = 8 - thtl_dty; /* THTL_DTY and ACPI T-state are reverse mapped */
+       return retval;
+}
+
+static int omnibook_acpi_set_throttle(const struct omnibook_operation *io_op, unsigned int state)
+{
+       struct acpi_backend_data *priv_data = io_op->backend->data;
+       /* THTL_DTY and ACPI T-state are reverse mapped */
+       /* throttling.c already clamped state between 0 and 7 */
+       if (state) 
+               state = 8 - state;
+
+       return omnibook_acpi_execute(priv_data->ec_handle, SET_THROTTLE_METHOD, &state, NULL);
+}
+
+
 struct omnibook_backend acpi_backend = {
        .name = "acpi",
        .init = omnibook_acpi_init,
@@ -427,6 +465,8 @@ struct omnibook_backend acpi_backend = {
        .aerial_set = omnibook_acpi_set_wireless,
        .display_get = omnibook_acpi_get_display,
        .display_set = omnibook_acpi_set_display,
+       .throttle_get = omnibook_acpi_get_throttle,
+       .throttle_set = omnibook_acpi_set_throttle,
 };
 
 #else                          /* CONFIG_ACPI */
diff --git a/cooling.c b/cooling.c
new file mode 100644 (file)
index 0000000..e2054c6
--- /dev/null
+++ b/cooling.c
@@ -0,0 +1,85 @@
+/*
+ * colling.c -- cooling methods feature
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * Written by Mathieu Bérard <mathieu.berard@crans.org>, 2007
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+static int omnibook_cooling_read(char *buffer, struct omnibook_operation *io_op)
+{
+       int len = 0;
+
+       if(mutex_lock_interruptible(&io_op->backend->mutex))
+               return -ERESTARTSYS;
+
+       len += sprintf(buffer + len, "Cooling method : %s\n", 
+                       io_op->backend->cooling_state ? "Performance"  : "Powersave" );
+
+       mutex_unlock(&io_op->backend->mutex);
+       return len;
+}
+
+static int omnibook_cooling_write(char *buffer, struct omnibook_operation *io_op)
+{
+       int retval = 0;
+
+       if (*buffer == '0') {
+               retval = backend_byte_write(io_op, 
+                               TSM70_COOLING_OFFSET + TSM70_COOLING_POWERSAVE);
+       } else if (*buffer == '1') {
+               retval = backend_byte_write(io_op,
+                               TSM70_COOLING_OFFSET + TSM70_COOLING_PERF);
+       } else {
+               return -EINVAL;
+       }
+
+       return retval;
+}
+
+static int __init omnibook_cooling_init(struct omnibook_operation *io_op)
+{
+       mutex_lock(&io_op->backend->mutex);
+       /* XXX: Assumed default cooling method: performance */
+       io_op->backend->cooling_state = TSM70_COOLING_PERF;
+       mutex_unlock(&io_op->backend->mutex);
+       return 0;
+}
+
+static void __exit omnibook_cooling_exit(struct omnibook_operation *io_op)
+{
+       /* Set back cooling method to performance */    
+       backend_byte_write(io_op, TSM70_COOLING_OFFSET + TSM70_COOLING_PERF);
+}
+
+static struct omnibook_tbl cooling_table[] __initdata = {
+       {TSM70, {CDI, 0, TSM70_FN_INDEX, 0, 0, 0 }},
+       {0,}
+};
+
+struct omnibook_feature __declared_feature cooling_driver = {
+       .name = "cooling",
+       .enabled = 1,
+       .read = omnibook_cooling_read,
+       .write = omnibook_cooling_write,
+       .init = omnibook_cooling_init,
+       .exit = omnibook_cooling_exit,
+       .ectypes = TSM70,
+       .tbl = cooling_table,
+};
+
+module_param_named(cooling, cooling_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(cooling, "Use 0 to disable, 1 to enable CPU cooling method control");
+
+/* End of file */
index d9f6887c4f0d88ab62cb600f5f9f0bda8686d0b2..ea3840f693e4bbdd814695999829f354ded63ade 100644 (file)
@@ -27,6 +27,14 @@ Changelog file for omnibook package:
   The state of the Toshiba M35X is unknown and is assigned to TSM70, one
   should send a bug report if that fail.
   Fix bugs 1617818 and 1605278
+* New features for TSM70 class laptops:
+  -Cooling method control (can tune fan behaviour to 'Save power' or
+   to 'Maximize performance') provided in /proc/omnibook/cooling 
+  -CPU Throttling status&control (also known as ACPI T-States) should
+   be supported out of the box via /proc/acpi/processor/CPU0/throttling
+   but at least Toshiba Satellite M70 as a deficient ACPI FADT table
+   which prevent than, thus a custom access to ACPI Throttling is 
+   provided in /proc/omnibook/throttling
 
 2.20060921 Mathieu Bérard <math_b@users.sourceforge.net>
 * The minimal required kernel version is now 2.6.9 (kref API)
diff --git a/dump.c b/dump.c
index ae552814107633806a3df8c6ed3f296abd844753..ff959e96a8d127b9702d22e3912d176b1ae5f5bd 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -34,11 +34,15 @@ static int ecdump_read(char *buffer, struct omnibook_operation *io_op)
            sprintf(buffer + len,
                    "EC      " " +00 +01 +02 +03 +04 +05 +06 +07"
                    " +08 +09 +0a +0b +0c +0d +0e +0f\n");
+
+       if(mutex_lock_interruptible(&io_op->backend->mutex))
+                       return -ERESTARTSYS;
+
        for (i = 0; i < 255; i += 16) {
                len += sprintf(buffer + len, "EC 0x%02x:", i);
                for (j = 0; j < 16; j++) {
                        io_op->read_addr = i +j;
-                       if (backend_byte_read(io_op, &v))
+                       if (__backend_byte_read(io_op, &v))
                                break;
                        if (v != ecdump_regs[i + j])
                                len += sprintf(buffer + len, " *%02x", v);
@@ -51,6 +55,8 @@ static int ecdump_read(char *buffer, struct omnibook_operation *io_op)
                        break;
        }
 
+       mutex_unlock(&io_op->backend->mutex);
+
        /* These are way too dangerous to advertise openly... */
 #if 0
        len +=
index 7a046cc421a321c2623ae923f8ac248118b68450..16f8e8aea7ba494caa3529c0c49e6cb6362b0419 100644 (file)
@@ -12,7 +12,7 @@
  * General Public License for more details.
  *
  * Written by Soós Péter <sp@osb.hu>, 2002-2004
- * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006-2007
  */
 
 #include <linux/acpi.h>
@@ -55,7 +55,9 @@ struct omnibook_backend {
 
        /* Public data fields, access with mutex held */
        unsigned int hotkeys_state;     /* saved hotkeys state */
-       unsigned int misc_state;        /* various status bit: touchpad and muteled */
+       unsigned int touchpad_state;    /* saved touchpad state */
+       unsigned int muteled_state;     /* saved muteled state */
+       unsigned int cooling_state;     /* saved cooling method state */
 
        /* Public function pointers */
        int (*init) (const struct omnibook_operation *); 
@@ -68,6 +70,8 @@ struct omnibook_backend {
        int (*hotkeys_set) (const struct omnibook_operation *, unsigned int); 
        int (*display_get) (const struct omnibook_operation *, unsigned int *);
        int (*display_set) (const struct omnibook_operation *, unsigned int);
+       int (*throttle_get) (const struct omnibook_operation *, unsigned int *);
+       int (*throttle_set) (const struct omnibook_operation *, unsigned int);
 
        /* Private fields, never to be accessed outside backend code */
        struct kref kref;       /* Reference counter of this backend */
@@ -133,6 +137,7 @@ static inline int __backend_##func##_set(const struct omnibook_operation *io_op,
 helper_func(aerial)
 helper_func(hotkeys)
 helper_func(display)
+helper_func(throttle)
 
 static inline int backend_byte_read(const struct omnibook_operation *io_op, u8 *data)
 {
@@ -502,6 +507,9 @@ static inline int omnibook_toggle(const struct omnibook_operation *io_op, int to
 #define TSM100_BLANK_INDEX     0x59
 #define        TSM100_LCD_ON           0xe1
 #define        TSM100_LCD_OFF          0xe2
+#define TSM70_COOLING_OFFSET   0xb0
+#define TSM70_COOLING_POWERSAVE        0x0
+#define TSM70_COOLING_PERF     0x2
 
 /* Toshiba SMI funtions and constants*/
 #define SMI_FN_PRESSED         0x8f
index 751b8ef2cb629c4b88992ca17839ce50a5a455e0..a21793a50bff54559b0b44081f41e3fdada70b9d 100644 (file)
--- a/muteled.c
+++ b/muteled.c
@@ -30,8 +30,7 @@ static int omnibook_muteled_set(struct omnibook_operation *io_op, int status)
                goto out;
        }
 
-       io_op->backend->misc_state = 
-               (io_op->backend->misc_state & ~MUTELED) | (MUTELED * !!status);
+       io_op->backend->muteled_state = !!status;
 
        out:
        mutex_unlock(&io_op->backend->mutex);
@@ -49,7 +48,7 @@ static int omnibook_muteled_read(char *buffer, struct omnibook_operation *io_op)
                return -ERESTARTSYS;
        len +=
            sprintf(buffer + len, "Last mute LED action was an %s command.\n",
-                   (io_op->backend->misc_state & MUTELED) ? "on" : "off");
+                   io_op->backend->touchpad_state ? "on" : "off");
 
        mutex_unlock(&io_op->backend->mutex);
        return len;
@@ -77,7 +76,7 @@ static int omnibook_muteled_resume(struct omnibook_operation *io_op)
 {      
        int retval;
        mutex_lock(&io_op->backend->mutex);
-       retval = __omnibook_toggle(io_op, !!(io_op->backend->misc_state & MUTELED));
+       retval = __omnibook_toggle(io_op, !!io_op->backend->touchpad_state);
        mutex_unlock(&io_op->backend->mutex);
        return retval;
 }
index d9348e876dafa2345f90e3b86484bcda05ee64cb..31a727fbcb0377e6970e52d691468778c412eb32 100644 (file)
@@ -100,15 +100,6 @@ enum {
 
 #define HKEY_LAST_SHIFT 6
 
-/*
- * Various status bits
- */
-enum {
-       MUTELED = (1<<0), /* Mute LED status */
-       TOUCHPAD = (1<<1), /* Touchpad status */
-};
-
-
 /*
  * Display state backend neutral masks
  * _ON masks = port is powered up and running
diff --git a/pio.c b/pio.c
index 4e197e97b43b799e253312042e15cbac1044f0d2..312811efdf791aa286316b16942a38bf024305be 100644 (file)
--- a/pio.c
+++ b/pio.c
@@ -138,7 +138,6 @@ static void omnibook_pio_exit(const struct omnibook_operation *io_op)
        if (match)
                kref_put(&match->refcount, omnibook_free_port);
 
-       match = NULL;
        match = omnibook_match_port(io_op->backend->data, io_op->write_addr);
        if (match)
                kref_put(&match->refcount, omnibook_free_port);
diff --git a/throttling.c b/throttling.c
new file mode 100644 (file)
index 0000000..e2f6900
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * throttling.c --CPU throttling control feature
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * Written by Mathieu Bérard <mathieu.berard@crans.org>, 2007
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+/*
+ * Throttling level/rate mapping found in ICH6M datasheets
+ * the output is set to mimic the one of /proc/acpi/cpu/CPU0/throttling
+ * XXX: We always assume that there are 8 T-States and one processor.
+ */
+static const int trate[8] = { 0, 12, 25, 37, 50, 62, 75, 87 };
+
+static int omnibook_throttle_read(char *buffer, struct omnibook_operation *io_op)
+{
+       int len = 0;
+       int tstate = 0;
+       int retval, i;
+
+       retval = backend_throttle_get(io_op, &tstate);
+       if (retval < 0)
+               return retval;
+
+       len += sprintf(buffer + len, "state count:             8\n");
+        len += sprintf(buffer + len, "active state:            T%d\n", tstate);
+       for (i = 0; i < 8; i += 1)
+       {
+               len += sprintf(buffer + len, "   %cT%d:                  %02d%%\n",
+                       (i == tstate ? '*' : ' '),
+                       i,
+                       trate[i]);
+       }
+
+       return len;
+}
+
+static int omnibook_throttle_write(char *buffer, struct omnibook_operation *io_op)
+{
+       int retval = 0;
+       int data;
+       char *endp;
+
+       data = simple_strtoul(buffer, &endp, 10);
+       if ((endp == buffer) || (data > 7)) /* There are 8 throttling levels */
+               return -EINVAL;
+       else
+               retval = backend_throttle_set(io_op, data);
+       
+       return retval;
+}
+
+
+static struct omnibook_tbl throttle_table[] __initdata = {
+       {TSM70, {ACPI,}},
+       {0,}
+};
+
+struct omnibook_feature __declared_feature throttle_driver = {
+       .name = "throttling",
+       .enabled = 1,
+       .read = omnibook_throttle_read,
+       .write = omnibook_throttle_write,
+       .ectypes = TSM70,
+       .tbl = throttle_table,
+};
+
+module_param_named(throttle, throttle_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(throttle, "Use 0 to disable, 1 to enable CPU throttling control");
+
+/* End of file */
index f3a7f5ba557d087775451ac1278dbfa0de1a5b95..b95e2ecb5cc62b9b8034204090f7a834e180d9a2 100644 (file)
@@ -30,8 +30,7 @@ static int omnibook_touchpad_set(struct omnibook_operation *io_op, int status)
                goto out;
        }
 
-       io_op->backend->misc_state = 
-               (io_op->backend->misc_state & ~TOUCHPAD) | (TOUCHPAD * !!status);
+       io_op->backend->touchpad_state = !!status;
 
        out:
        mutex_unlock(&io_op->backend->mutex);
@@ -45,7 +44,7 @@ static int omnibook_touchpad_resume(struct omnibook_operation *io_op)
 {
        int retval;
        mutex_lock(&io_op->backend->mutex);
-       retval = __omnibook_toggle(io_op, !!(io_op->backend->misc_state & TOUCHPAD));
+       retval = __omnibook_toggle(io_op, !!io_op->backend->touchpad_state);
        mutex_unlock(&io_op->backend->mutex);
        return retval;
 }
@@ -62,7 +61,7 @@ static int omnibook_touchpad_read(char *buffer, struct omnibook_operation *io_op
 
        len +=
            sprintf(buffer + len, "Last touchpad action was an %s command.\n",
-                   (io_op->backend->misc_state & TOUCHPAD) ? "enable" : "disable");
+                   io_op->backend->touchpad_state ? "enable" : "disable");
 
        mutex_unlock(&io_op->backend->mutex);
        return len;
@@ -88,7 +87,7 @@ static int __init omnibook_touchpad_init(struct omnibook_operation *io_op)
 {
        mutex_lock(&io_op->backend->mutex);
        /* Touchpad is assumed to be enabled by default */
-       io_op->backend->misc_state |= TOUCHPAD;
+       io_op->backend->touchpad_state = 1;
        mutex_unlock(&io_op->backend->mutex);
        return 0;
 }