#ifdef CONFIG_ACPI
#include <acpi/acpi_drivers.h>
+#include <linux/workqueue.h>
+
+/* copied from drivers/input/serio/i8042-io.h */
+#define I8042_KBD_PHYS_DESC "isa0060/serio0"
/*
* ACPI backend masks and strings
#define GET_WIRELESS_METHOD "ANTR"
#define SET_WIRELESS_METHOD "ANTW"
-#define WLEX_MASK 0x4
+#define WLEX_MASK 0x4
#define WLAT_MASK 0x1
#define BTEX_MASK 0x8
#define BTAT_MASK 0x2
acpi_handle bt_handle; /* Handle on ACPI BT device */
unsigned has_antr_antw:1; /* Are there ANTR/ANTW methods in the EC device ? */
unsigned has_doss_dosw:1; /* Are there DOSS/DOSW methods in the EC device ? */
+ struct input_dev *acpi_input_dev;
+ struct work_struct fnkey_work;
};
+/*
+ * Hotkeys workflow:
+ * 1. Fn+Foo pressed
+ * 2. Scancode 0x6e generated by kbd controller
+ * 3. Scancode 0x6e caught by omnibook input handler
+ * 4. TOHK Got keycode of last actually pressed Fn key
+ * 5. acpi_scan_table used to associate a detected keycode with a generated one
+ * 6. Generated keycode issued using the omnibook input device
+ */
+
+/*
+ * The input handler should only bind with the standard AT keyboard.
+ * XXX: Scancode 0x6e won't be detected if the keyboard has already been
+ * grabbed (the Xorg event input driver do that)
+ */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+static int hook_connect(struct input_handler *handler,
+ struct input_dev *dev,
+ const struct input_device_id *id)
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
+static struct input_handle *hook_connect(struct input_handler *handler,
+ struct input_dev *dev,
+ const struct input_device_id *id)
+#else
+static struct input_handle *hook_connect(struct input_handler *handler,
+ struct input_dev *dev,
+ struct input_device_id *id)
+#endif
+{
+ struct input_handle *handle;
+ int error;
+
+ /* the 0x0001 vendor magic number is found in atkbd.c */
+ if(!(dev->id.bustype == BUS_I8042 && dev->id.vendor == 0x0001))
+ goto out_nobind;
+
+ if(!strstr(dev->phys, I8042_KBD_PHYS_DESC))
+ goto out_nobind;
+
+ dprintk("hook_connect for device %s.\n", dev->name);
+
+ if(dev->grab)
+ printk(O_WARN "Input device is grabbed by %s, Fn hotkeys won't work.\n",
+ dev->grab->name);
+
+ handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+ if (!handle)
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+ return -ENOMEM;
+#else
+ return NULL;
+#endif
+
+ handle->dev = dev;
+ handle->handler = handler;
+ handle->name = "omnibook_scancode_hook";
+ handle->private = handler->private;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+ error = input_register_handle(handle);
+ if (error) {
+ dprintk("register_handle failed\n");
+ goto out_nobind_free;
+ }
+ error = input_open_device(handle);
+ if (error) {
+ dprintk("register_handle failed\n");
+ input_unregister_handle(handle);
+ goto out_nobind_free;
+ }
+
+#else
+ status=input_open_device(handle);
+ if (error==0) dprintk("Input device opened\n");
+ else {
+ dprintk("opening input device failed\n");
+ goto out_nobind_free;
+ }
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+ return 0;
+out_nobind_free:
+ kfree(handle);
+out_nobind:
+ return -ENODEV;
+#else
+ return handle;
+out_nobind_free:
+ kfree(handle);
+out_nobind:
+ return NULL;
+#endif
+}
+
+static void hook_disconnect(struct input_handle *handle)
+{
+ dprintk("hook_disconnect.\n");
+ input_close_device(handle);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+ input_unregister_handle(handle);
+#endif
+ kfree(handle);
+}
+
+/*
+ * Hook for scancode 0x6e. Actual handling is done in a workqueue.
+ */
+static void hook_event(struct input_handle *handle, unsigned int event_type,
+ unsigned int event_code, int value)
+{
+ if (event_type == EV_MSC && event_code == MSC_SCAN && value == ACPI_FN_SCAN)
+ schedule_work(&((struct acpi_backend_data *)handle->private)->fnkey_work);
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
+static const struct input_device_id hook_ids[] = {
+#else
+static struct input_device_id hook_ids[] = {
+#endif
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
+ .evbit = { BIT(EV_KEY) },
+ },
+ { }, /* Terminating entry */
+};
+
+static struct input_handler hook_handler = {
+ .event = hook_event,
+ .connect = hook_connect,
+ .disconnect = hook_disconnect,
+ .name = OMNIBOOK_MODULE_NAME,
+ .id_table = hook_ids,
+};
+
+/*
+ * Detected scancode to keycode table
+ */
+static const struct {
+ unsigned int scancode;
+ unsigned int keycode;
+} acpi_scan_table[] = {
+ { HCI_FN, KEY_RESERVED},
+ { HCI_MUTE, KEY_MUTE},
+ { HCI_BREAK, KEY_COFFEE},
+ { HCI_1, KEY_ZOOMOUT},
+ { HCI_2, KEY_ZOOMIN},
+ { HCI_SPACE, KEY_ZOOM},
+ { HCI_BSM, KEY_PROG1},
+ { HCI_SUSPEND, KEY_SLEEP},
+ { HCI_HIBERNATE, KEY_SUSPEND},
+ { HCI_BRIGHTNESSDOWN, KEY_BRIGHTNESSDOWN},
+ { HCI_BRIGHTNESSUP, KEY_BRIGHTNESSUP},
+ { HCI_WLAN, KEY_WLAN},
+ { HCI_TOUCHPAD, KEY_PROG2},
+ { 0, 0},
+};
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+static void omnibook_handle_fnkey(struct work_struct *work);
+#else
+static void omnibook_handle_fnkey(void* data);
+#endif
+
+/*
+ * Register the input handler and the input device in the input subsystem
+ */
+static int register_input_subsystem(struct acpi_backend_data *priv_data)
+{
+ int i, retval = 0;
+ struct input_dev *acpi_input_dev;
+
+ acpi_input_dev = input_allocate_device();
+ if (!acpi_input_dev) {
+ retval = -ENOMEM;
+ goto out;
+ }
+
+ acpi_input_dev->name = "Omnibook ACPI scancode generator";
+ acpi_input_dev->phys = "omnibook/input0";
+ acpi_input_dev->id.bustype = BUS_HOST;
+
+ set_bit(EV_KEY, acpi_input_dev->evbit);
+
+ for(i=0 ; i < ARRAY_SIZE(acpi_scan_table); i++)
+ set_bit(acpi_scan_table[i].keycode, acpi_input_dev->keybit);
+
+ retval = input_register_device(acpi_input_dev);
+ if(retval) {
+ input_free_device(acpi_input_dev);
+ goto out;
+ }
+
+ priv_data->acpi_input_dev = acpi_input_dev;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+ INIT_WORK(&priv_data->fnkey_work, *omnibook_handle_fnkey);
+#else
+ INIT_WORK(&priv_data->fnkey_work, *omnibook_handle_fnkey, priv_data);
+#endif
+
+
+ hook_handler.private = priv_data;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
+ retval = input_register_handler(&hook_handler);
+#else
+ input_register_handler(&hook_handler);
+#endif
+
+ out:
+ return retval;
+}
+
/*
* Probe for expected ACPI devices
*/
(acpi_get_handle( dev_handle, SET_DISPLAY_METHOD, &method_handle) == AE_OK))
priv_data->has_doss_dosw = 1;
+ retval = register_input_subsystem(priv_data);
+ if(retval)
+ goto error1;
+
io_op->backend->data = (void *) priv_data;
mutex_unlock(&io_op->backend->mutex);
static void omnibook_acpi_free(struct kref *ref)
{
struct omnibook_backend *backend;
+ struct acpi_backend_data *priv_data;
+
backend = container_of(ref, struct omnibook_backend, kref);
+ priv_data = backend->data;
+
dprintk("ACPI backend not used anymore: disposing\n");
dprintk("ptr addr: %p driver name: %s\n",&omnibook_bt_driver, omnibook_bt_driver.name);
acpi_bus_unregister_driver(&omnibook_bt_driver);
+
+ flush_scheduled_work();
+ input_unregister_handler(&hook_handler);
+ input_unregister_device(priv_data->acpi_input_dev);
mutex_lock(&backend->mutex);
kfree(backend->data);
return 0;
}
+/* Function taken from toshiba_acpi */
+static acpi_status hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
+{
+ struct acpi_object_list params;
+ union acpi_object in_objs[HCI_WORDS];
+ struct acpi_buffer results;
+ union acpi_object out_objs[HCI_WORDS + 1];
+ acpi_status status;
+ int i;
+
+ params.count = HCI_WORDS;
+ params.pointer = in_objs;
+ for (i = 0; i < HCI_WORDS; ++i) {
+ in_objs[i].type = ACPI_TYPE_INTEGER;
+ in_objs[i].integer.value = in[i];
+ }
+
+ results.length = sizeof(out_objs);
+ results.pointer = out_objs;
+
+ status = acpi_evaluate_object(NULL, (char *)METHOD_HCI, ¶ms,
+ &results);
+ if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) {
+ for (i = 0; i < out_objs->package.count; ++i) {
+ out[i] = out_objs->package.elements[i].integer.value;
+ }
+ }
+
+ return status;
+}
+
/*
* Set Bluetooth device state using the Toshiba BT device
*/
int retval;
struct acpi_backend_data *priv_data = acpi_backend.data;
- dprintk("Enabling found Toshiba Bluetooth ACPI device.\n");
+ dprintk("Enabling Toshiba Bluetooth ACPI device.\n");
strcpy(acpi_device_name(device), TOSHIBA_ACPI_DEVICE_NAME);
strcpy(acpi_device_class(device), TOSHIBA_ACPI_BT_CLASS);
return retval;
}
+static int get_tsx205_wireless_status(const struct acpi_backend_data *priv_data, unsigned int *state)
+{
+ int retval = 0;
+ int raw_state;
+ u32 in[HCI_WORDS] = { HCI_GET, HCI_RF_CONTROL, 0, HCI_WIRELESS_CHECK, 0, 0 };
+ u32 out[HCI_WORDS];
+
+ hci_raw(in, out);
+
+ /* Now let's check the killswitch */
+ if ((retval = omnibook_acpi_execute(priv_data->ec_handle, TSX205_KILLSW_METHOD, NULL, &raw_state)))
+ return retval;
+
+ dprintk("get_wireless raw_state: %x\n", out[2]);
+
+ *state = ((out[2] & 0xff)) ? WIFI_EX : 0;
+ *state |= (raw_state) ? WIFI_STA : 0;
+ *state |= (!raw_state) ? KILLSWITCH : 0;
+
+ /* And finally BT */
+ if ((retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_STATUS, NULL, &raw_state)))
+ return retval;
+
+ *state |= BT_EX;
+ *state |= ((raw_state & TOSH_BT_USB_MASK) && (raw_state & TOSH_BT_POWER_MASK)) ? BT_STA : 0;
+
+ return retval;
+}
+
static int omnibook_acpi_get_wireless(const struct omnibook_operation *io_op, unsigned int *state)
{
int retval;
struct acpi_backend_data *priv_data = io_op->backend->data;
/* use BTST (BT device) if we don't have ANTR/ANTW (EC device) */
- if(priv_data->has_antr_antw)
+ if (omnibook_ectype & TSX205)
+ retval = get_tsx205_wireless_status(priv_data, state);
+ else if (priv_data->has_antr_antw)
retval = get_wireless_status(priv_data, state);
else if(priv_data->bt_handle)
retval = get_bt_status(priv_data, state);
return retval;
}
+static int set_tsx205_wireless_status(const struct acpi_backend_data *priv_data, unsigned int state)
+{
+ int retval;
+ int raw_state = !!(state & WIFI_STA);
+
+ dprintk("set_wireless raw_state: %x\n", raw_state);
+
+ u32 in[HCI_WORDS] = { HCI_SET, HCI_RF_CONTROL, raw_state, HCI_WIRELESS_POWER, 0, 0 };
+ u32 out[HCI_WORDS];
+ hci_raw(in, out);
+
+ raw_state |= !!(state & BT_STA) << 0x1; /* bit 1 */
+
+ /* BT status */
+ retval = set_bt_status(priv_data->bt_handle, state);
+
+ return retval;
+}
+
static int omnibook_acpi_set_wireless(const struct omnibook_operation *io_op, unsigned int state)
{
int retval = -ENODEV;
struct acpi_backend_data *priv_data = io_op->backend->data;
-
- /* First try the ANTR/ANTW methods */
+
+ /* First try the TSX205 methods */
+ if(omnibook_ectype & TSX205)
+ retval = set_tsx205_wireless_status(priv_data, state);
+
+ /* Then try the ANTR/ANTW methods */
if(priv_data->has_antr_antw)
- retval = set_wireless_status(priv_data, state);
+ retval = set_wireless_status(priv_data, state);
/* Then try the bluetooth ACPI device if present */
if(priv_data->bt_handle)
return omnibook_acpi_execute(priv_data->ec_handle, SET_THROTTLE_METHOD, &state, NULL);
}
+/*
+ * Fn+foo hotkeys handling
+ */
+static int omnibook_hci_get_hotkeys(const struct omnibook_operation *io_op, unsigned int *state)
+{
+ u32 in[HCI_WORDS] = { HCI_GET, HCI_HOTKEY_EVENT, 0, 0, 0, 0 };
+ u32 out[HCI_WORDS];
+ acpi_status status = hci_raw(in, out);
+
+ if (status != AE_OK)
+ return HCI_FAILURE;
+
+ dprintk("get_hotkeys raw_state: %x\n", out[2]);
+
+ *state = (out[2] & ACPI_FN_MASK) ? HKEY_FN : 0;
+
+ return 0;
+}
+
+static int omnibook_hci_set_hotkeys(const struct omnibook_operation *io_op, unsigned int state)
+{
+ u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 };
+ u32 out[HCI_WORDS];
+ in[0] = HCI_SET;
+ in[1] = HCI_HOTKEY_EVENT;
+ in[2] = (state & HKEY_FN) ? 1 : 0;
+ acpi_status status = hci_raw(in, out);
+
+ dprintk("set_hotkeys (Fn interface) raw_state: %x\n", in[2]);
+
+ return (status == AE_OK) ? out[0] : HCI_FAILURE;
+}
+
+static int omnibook_acpi_get_events(unsigned int *state)
+{
+ int i;
+ struct acpi_buffer results;
+ union acpi_object out_objs[1];
+ acpi_handle handle;
+ acpi_status status;
+
+ for (i = 0; i < ARRAY_SIZE(ec_dev_list); i++) {
+ status = acpi_get_handle(NULL, ec_dev_list[i], &handle);
+ if (status == AE_OK)
+ break;
+ }
+
+ results.length = sizeof(out_objs);
+ results.pointer = out_objs;
+
+ status = acpi_evaluate_object(handle, (char *)TSX205_EVENTS_METHOD, 0, &results);
+ *state = out_objs[0].integer.value;
+ *state &= ~0x80;
+
+ return status;
+}
+
+/*
+ * Adjust the lcd backlight level by delta.
+ * Used for Fn+F6/F7 keypress
+ */
+static int adjust_brighness(int delta)
+{
+ struct omnibook_feature *lcd_feature = omnibook_find_feature("lcd");
+ struct omnibook_operation *io_op;
+ int retval = 0;
+ u8 brgt;
+
+ if(!lcd_feature)
+ return -ENODEV;
+
+ io_op = lcd_feature->io_op;
+
+ mutex_lock(&io_op->backend->mutex);
+
+ if(( retval = __backend_byte_read(io_op, &brgt)))
+ goto out;
+
+ dprintk("Fn-F6/F7 pressed: adjusting britghtnes.\n");
+
+ if (((int) brgt + delta) < 0)
+ brgt = 0;
+ else if ((brgt + delta) > omnibook_max_brightness)
+ brgt = omnibook_max_brightness;
+ else
+ brgt += delta;
+
+ retval = __backend_byte_write(io_op, brgt);
+
+ out:
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+/*
+ * Workqueue handler for Fn hotkeys
+ */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+static void omnibook_handle_fnkey(struct work_struct *work)
+#else
+static void omnibook_handle_fnkey(void* data)
+#endif
+{
+ int i;
+ u32 gen_scan;
+ struct input_dev *input_dev;
+ acpi_status status;
+
+ status = omnibook_acpi_get_events(&gen_scan);
+ if (status != AE_OK)
+ return;
+
+ dprintk("detected scancode 0x%x.\n", gen_scan);
+ switch(gen_scan) {
+ case HCI_BRIGHTNESSDOWN:
+ adjust_brighness(-1);
+ break;
+ case HCI_BRIGHTNESSUP:
+ adjust_brighness(+1);
+ break;
+ }
+
+ for (i = 0 ; i < ARRAY_SIZE(acpi_scan_table); i++) {
+ if ( gen_scan == acpi_scan_table[i].scancode && gen_scan != KEY_RESERVED) {
+ dprintk("generating keycode %i.\n", acpi_scan_table[i].keycode);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+ input_dev = container_of(work, struct acpi_backend_data, fnkey_work)->acpi_input_dev;
+#else
+ input_dev = ((struct acpi_backend_data *) data)->acpi_input_dev;
+#endif
+ omnibook_report_key(input_dev, acpi_scan_table[i].keycode);
+ break;
+ }
+ }
+}
struct omnibook_backend acpi_backend = {
.name = "acpi",
+ .hotkeys_read_cap = HKEY_FN,
+ .hotkeys_write_cap = HKEY_FN,
.init = omnibook_acpi_init,
.exit = omnibook_acpi_exit,
.aerial_get = omnibook_acpi_get_wireless,
.display_set = omnibook_acpi_set_display,
.throttle_get = omnibook_acpi_get_throttle,
.throttle_set = omnibook_acpi_set_throttle,
+ .hotkeys_get = omnibook_hci_get_hotkeys,
+ .hotkeys_set = omnibook_hci_set_hotkeys,
};
#else /* CONFIG_ACPI */
}
static struct omnibook_tbl blank_table[] __initdata = {
- {TSM70, {CDI, 0, TSM100_BLANK_INDEX, 0, TSM100_LCD_OFF, TSM100_LCD_ON}},
+ {TSM70 | TSX205, {CDI, 0, TSM100_BLANK_INDEX, 0, TSM100_LCD_OFF, TSM100_LCD_ON}},
{XE3GF | XE3GC | AMILOD | TSP10 | TSM70 | TSM30X,
COMMAND(KBC, OMNIBOOK_KBC_CMD_LCD_OFF, OMNIBOOK_KBC_CMD_LCD_ON)},
{OB500 | OB6000 | XE2, {PIO, OB500_GPO1, OB500_GPO1, 0, -OB500_BKLT_MASK, OB500_BKLT_MASK}},
.init = omnibook_console_blank_init,
.exit = omnibook_console_blank_cleanup,
.ectypes =
- XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE2 | AMILOD | TSP10 | TSM70 | TSM30X,
+ XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE2 | AMILOD | TSP10 | TSM70 | TSM30X | TSX205,
.tbl = blank_table,
};
}
static struct omnibook_tbl wireless_table[] __initdata = {
- {TSM70 | TSA105, {ACPI,}}, /* stubs to select backend */
- {TSM40, {SMI,}}, /* stubs to select backend */
+ {TSM70 | TSA105 | TSX205, {ACPI,}}, /* stubs to select backend */
+ {TSM40, {SMI,}}, /* stubs to select backend */
{0,}
};
.read = omnibook_bt_read,
.write = omnibook_bt_write,
.init = omnibook_bt_init,
- .ectypes = TSM70 | TSM40 | TSA105,
+ .ectypes = TSM70 | TSM40 | TSA105 | TSX205,
.tbl = wireless_table,
};
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_30, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_4, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
{PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SB400, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
{0,}, /* End of list */
};
case PCI_DEVICE_ID_INTEL_ICH7_1:
case PCI_DEVICE_ID_INTEL_ICH7_30:
case PCI_DEVICE_ID_INTEL_ICH7_31:
+ case PCI_DEVICE_ID_INTEL_ICH8_4: /* ICH8 */
pci_read_config_dword(lpc_bridge, INTEL_LPC_GEN4_DEC, &(value.dword));
pci_reg_state.dword = value.dword;
value.dword = 0x3CFF21;
case PCI_DEVICE_ID_INTEL_ICH7_1:
case PCI_DEVICE_ID_INTEL_ICH7_30:
case PCI_DEVICE_ID_INTEL_ICH7_31:
+ case PCI_DEVICE_ID_INTEL_ICH8_4: /* ICH8 */
pci_write_config_dword(lpc_bridge, INTEL_LPC_GEN4_DEC, pci_reg_state.dword);
break;
default: /* All other Intel chipset */
int i;
/* ectypes other than TSM70 have no business with this backend */
- if (!(omnibook_ectype & TSM70))
+ if (!(omnibook_ectype & (TSM70 | TSX205)))
return -ENODEV;
if (io_op->backend->already_failed) {
static void omnibook_cdimode_exit(const struct omnibook_operation *io_op)
{
/* ectypes other than TSM70 have no business with this backend */
- BUG_ON(!(omnibook_ectype & TSM70));
+ BUG_ON(!(omnibook_ectype & (TSM70 | TSX205)));
dprintk("Trying to dispose cdimode\n");
kref_put(&io_op->backend->kref, cdimode_free);
}
}
static struct omnibook_tbl cooling_table[] __initdata = {
- {TSM70, {CDI, 0, TSM70_FN_INDEX, 0, 0, 0 }},
+ {TSM70 | TSX205, {CDI, 0, TSM70_FN_INDEX, 0, 0, 0 }},
{0,}
};
.write = omnibook_cooling_write,
.init = omnibook_cooling_init,
.exit = omnibook_cooling_exit,
- .ectypes = TSM70,
+ .ectypes = TSM70 | TSX205,
.tbl = cooling_table,
};
fix compiler warning about use uninitialized variable
* Applied patch from Danny Kukawka <dkukawka@suse.de> to
fix build the driver on older kernel versions
+* Applied patch from Azael Avalos <coproscefalo@gmail.com>
+ to add support to Satellite X205 and other laptops based on
+ ICH8
2.20070211 Mathieu BĂ©rard <math_b@users.sourceforge.net>
* Disable Acer support, acerhk module should provided better
/*
* For most models the reading is a bool
* It as to be inverted on all but OB6000|OB6100|OB4150|AMILOD
- * TSP10|XE3GF return an integer
+ * TSP10|XE3GF|TSX205 return an integer
*/
- if (omnibook_ectype & (TSP10 | XE3GF))
+ if (omnibook_ectype & (TSP10 | XE3GF | TSX205))
retval = fan;
else if (omnibook_ectype & (OB6000 | OB6100 | OB4150 | AMILOD))
retval = !!fan;
{
int i, retval = 0;
- if (!(omnibook_ectype & (XE3GF | TSP10))) {
+ if (!(omnibook_ectype & (XE3GF | TSP10 | TSX205))) {
retval = omnibook_apply_write_mask(io_op, 0);
return retval;
} else {
}
static struct omnibook_tbl fan_table[] __initdata = {
- {XE3GF | TSP10, {EC, XE3GF_FSRD, XE3GF_FSRD, 0, XE3GF_FAN_ON_MASK, 0}},
+ {XE3GF | TSP10 | TSM70 | TSX205, {EC, XE3GF_FSRD, XE3GF_FSRD, 0, XE3GF_FAN_ON_MASK, 0}},
{OB500,
{PIO, OB500_GPO1, OB500_GPO1, OB500_FAN_OFF_MASK, -OB500_FAN_ON_MASK, OB500_FAN_OFF_MASK}},
{OB510,
.read = omnibook_fan_read,
.write = omnibook_fan_write,
.init = omnibook_fan_init,
- .ectypes = XE3GF | OB500 | OB510 | OB6000 | OB6100 | OB4150 | XE2 | AMILOD | TSP10,
+ .ectypes = XE3GF | OB500 | OB510 | OB6000 | OB6100 | OB4150 | XE2 | AMILOD | TSP10 | TSX205,
.tbl = fan_table,
};
int (*aerial_get) (const struct omnibook_operation *, unsigned int *);
int (*aerial_set) (const struct omnibook_operation *, unsigned int);
int (*hotkeys_get) (const struct omnibook_operation *, unsigned int *);
- int (*hotkeys_set) (const struct omnibook_operation *, unsigned int);
+ 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 *);
#define SMI_FN_SCAN 0x6d /* Fn key scancode */
#define SMI_DOCK_SCAN 0x6e /* Dock scancode */
+
+/* Toshiba HCI method and constants */
+#define METHOD_HCI "\\_SB.VALZ.SPFC"
+#define HCI_WORDS 6
+
+#define HCI_GET 0xfe00
+#define HCI_SET 0xff00
+
+#define HCI_HOTKEY_EVENT 0x001e
+#define HCI_RF_CONTROL 0x0056
+
+#define HCI_ENABLE 0x0001
+#define HCI_DISABLE 0x0000
+
+#define HCI_WIRELESS_CHECK 0x0001
+#define HCI_WIRELESS_POWER 0x0200
+
+#define HCI_SUCCESS 0x0000
+#define HCI_FAILURE 0x1000
+#define HCI_NOT_SUPPORTED 0x8000
+
+/* Toshiba Satellite X205 methods */
+#define TSX205_EVENTS_METHOD "TOHK"
+#define TSX205_KILLSW_METHOD "KLSW"
+
+#define ACPI_FN_MASK 0x01
+#define ACPI_FN_SCAN 0x6e /* Fn key scancode */
+
+/* HCI key definitions */
+#define HCI_FN 0x100
+#define HCI_MUTE 0x101
+#define HCI_1 0x102
+#define HCI_2 0x103
+#define HCI_SPACE 0x139
+#define HCI_BREAK 0x13b
+#define HCI_BSM 0x13c
+#define HCI_SUSPEND 0x13d
+#define HCI_HIBERNATE 0x13e
+#define HCI_BRIGHTNESSDOWN 0x140
+#define HCI_BRIGHTNESSUP 0x141
+#define HCI_WLAN 0x142
+#define HCI_TOUCHPAD 0x143
*/
static int hotkeys_get_save(struct omnibook_operation *io_op, unsigned int *state)
{
-
unsigned int read_state = 0;
int retval = 0;
*state = (read_state & io_op->backend->hotkeys_read_cap) +
(io_op->backend->hotkeys_state & ~io_op->backend->hotkeys_read_cap);
-
out:
mutex_unlock(&io_op->backend->mutex);
return 0;
(read_state & mask) ? "enabled" : "disabled");
}
-
return len;
}
COMMAND(KBC,OMNIBOOK_KBC_CMD_ONETOUCH_ENABLE,OMNIBOOK_KBC_CMD_ONETOUCH_DISABLE)},
{TSM70, {CDI,}},
{TSM40, {SMI,}},
+ {TSX205, {ACPI,}},
{0,}
};
.resume = omnibook_hotkeys_resume,
.ectypes =
XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE4500 | AMILOD | TSP10 | TSM70 | TSM30X |
- TSM40,
+ TSM40 | TSX205,
.tbl = hotkeys_table,
};
},
.driver_data = (void*) TSM40
},
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite X205-S9800",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite X205"),
+ },
+ .driver_data = (void*) TSX205
+ },
{
.callback = dmi_matched,
.ident = "Toshiba Tecra S1",
* TSM70
* TSM40
* TSA105
+ * TSX205
*/
- if (omnibook_ectype & (XE3GF | TSM70 | TSM30X | TSM40 | TSA105))
+ if (omnibook_ectype & (XE3GF | TSM70 | TSM30X | TSM40 | TSA105 | TSX205))
omnibook_max_brightness = 7;
else {
omnibook_max_brightness = 10;
}
static struct omnibook_tbl lcd_table[] __initdata = {
- {TSM70, {CDI, TSM70_LCD_READ, TSM70_LCD_WRITE, 0, 0, 0}},
+ {TSM70 | TSX205, {CDI, TSM70_LCD_READ, TSM70_LCD_WRITE, 0, 0, 0}},
{TSM40, {SMI, SMI_GET_LCD_BRIGHTNESS, SMI_SET_LCD_BRIGHTNESS, 0, 0, 0}},
{XE3GF | TSP10 | TSM70 | TSM30X, SIMPLE_BYTE(EC, XE3GF_BRTS, XE3GF_BRTS_MASK)},
{XE3GC, SIMPLE_BYTE(EC, XE3GC_BTVL, XE3GC_BTVL_MASK)},
.write = omnibook_brightness_write,
.init = omnibook_brightness_init,
.exit = omnibook_brightness_cleanup,
- .ectypes = XE3GF | XE3GC | AMILOD | TSP10 | TSM70 | TSM30X | TSM40 | TSA105,
+ .ectypes = XE3GF | XE3GC | AMILOD | TSP10 | TSM70 | TSM30X | TSM40 | TSA105 | TSX205,
.tbl = lcd_table,
};
XE2 = (1<<8), /* 9 HP OmniBook XE2 */
AMILOD = (1<<9), /* 10 Fujitsu Amilo D */
TSP10 = (1<<10), /* 11 Toshiba Satellite P10, P15, P20 and compatible */
- TSM70 = (1<<11), /* 12 Toshiba Satellite M40X, M70 and compatible */
+ TSM70 = (1<<11), /* 12 Toshiba Satellite M40X, M70 and compatible */
TSM40 = (1<<12), /* 13 Toshiba Satellite M40, M45 and Tecra S1 */
- TSA105 = (1<<13), /* 14 Toshiba Satellite A105 and compatible (Real support is MISSING) */
- TSM30X = (1<<14) /* 15 Toshiba Stallite M30X and compatible */
+ TSA105 = (1<<13), /* 14 Toshiba Satellite A105 and compatible (Real support is MISSING) */
+ TSM30X = (1<<14), /* 15 Toshiba Stallite M30X and compatible */
+ TSX205 = (1<<15) /* 16 Toshiba Stallite X205 and compatible */
} omnibook_ectype;
-#define ALL_ECTYPES XE3GF|XE3GC|OB500|OB510|OB6000|OB6100|XE4500|OB4150|XE2|AMILOD|TSP10|TSM70|TSM40|TSA105|TSM30X
+#define ALL_ECTYPES XE3GF|XE3GC|OB500|OB510|OB6000|OB6100|XE4500|OB4150|XE2|AMILOD|TSP10|TSM70|TSM40|TSA105|TSM30X|TSX205
/*
* This represent a feature provided by this module
struct omnibook_operation;
struct omnibook_feature {
- char *name; /* Name */
- int enabled; /* Set from module parameter */
+ char *name; /* Name */
+ int enabled; /* Set from module parameter */
int (*read) (char *,struct omnibook_operation *); /* Procfile read function */
- int (*write) (char *,struct omnibook_operation *);/* Procfile write function */
- int (*init) (struct omnibook_operation *); /* Specific Initialization function */
- void (*exit) (struct omnibook_operation *); /* Specific Cleanup function */
- int (*suspend) (struct omnibook_operation *); /* PM Suspend function */
- int (*resume) (struct omnibook_operation *); /* PM Resume function */
- int ectypes; /* Type(s) of EC we support for this feature (bitmask) */
+ int (*write) (char *,struct omnibook_operation *); /* Procfile write function */
+ int (*init) (struct omnibook_operation *); /* Specific Initialization function */
+ void (*exit) (struct omnibook_operation *); /* Specific Cleanup function */
+ int (*suspend) (struct omnibook_operation *); /* PM Suspend function */
+ int (*resume) (struct omnibook_operation *); /* PM Resume function */
+ int ectypes; /* Type(s) of EC we support for this feature (bitmask) */
struct omnibook_tbl *tbl;
struct omnibook_operation *io_op;
struct list_head list;
* Hotkeys state backend neutral masks
*/
enum {
- HKEY_ONETOUCH = (1<<0), /* 1 Ontetouch button scancode generation */
- HKEY_MULTIMEDIA = (1<<1), /* 2 "Multimedia hotkeys" scancode generation */
- HKEY_FN = (1<<2), /* 4 Fn + foo hotkeys scancode generation */
- HKEY_STICK = (1<<3), /* 8 Stick key (Fn locked/unlocked on keypress) */
- HKEY_TWICE_LOCK = (1<<4), /* 16 Press Fn twice to lock */
- HKEY_DOCK = (1<<5), /* 32 (Un)Dock events scancode generation */
- HKEY_FNF5 = (1<<6), /* 64 Fn + F5 (toggle display) is enabled */
+ HKEY_ONETOUCH = (1<<0), /* 1 Ontetouch button scancode generation */
+ HKEY_MULTIMEDIA = (1<<1), /* 2 "Multimedia hotkeys" scancode generation */
+ HKEY_FN = (1<<2), /* 4 Fn + foo hotkeys scancode generation */
+ HKEY_STICK = (1<<3), /* 8 Stick key (Fn locked/unlocked on keypress) */
+ HKEY_TWICE_LOCK = (1<<4), /* 16 Press Fn twice to lock */
+ HKEY_DOCK = (1<<5), /* 32 (Un)Dock events scancode generation */
+ HKEY_FNF5 = (1<<6), /* 64 Fn + F5 (toggle display) is enabled */
};
#define HKEY_LAST_SHIFT 6
}
static struct omnibook_tbl temp_table[] __initdata = {
- {XE3GF | TSP10 | TSM70 | TSM30X, SIMPLE_BYTE(EC, XE3GF_CTMP, 0)},
+ {XE3GF | TSP10 | TSM70 | TSM30X | TSX205, SIMPLE_BYTE(EC, XE3GF_CTMP, 0)},
{XE3GC | AMILOD, SIMPLE_BYTE(EC, XE3GC_CTMP, 0)},
{OB500 | OB510 | OB6000 | OB6100 | XE4500 | XE2, SIMPLE_BYTE(EC, OB500_CTMP, 0)},
{OB4150, SIMPLE_BYTE(EC, OB4150_TMP, 0)},
.read = omnibook_temperature_read,
.ectypes =
XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE4500 | OB4150 | XE2 | AMILOD | TSP10
- | TSM70 | TSM30X,
+ | TSM70 | TSM30X | TSX205,
.tbl = temp_table,
};
static struct omnibook_tbl throttle_table[] __initdata = {
- {TSM70, {ACPI,}},
+ {TSM70 | TSX205, {ACPI,}},
{0,}
};
.enabled = 1,
.read = omnibook_throttle_read,
.write = omnibook_throttle_write,
- .ectypes = TSM70,
+ .ectypes = TSM70 | TSX205,
.tbl = throttle_table,
};
}
static struct omnibook_tbl wireless_table[] __initdata = {
- {TSM70, {ACPI,}}, /* stubs to select backend */
- {TSM40, {SMI,}}, /* stubs to select backend */
+ {TSM70 | TSX205, {ACPI,}}, /* stubs to select backend */
+ {TSM40, {SMI,}}, /* stubs to select backend */
{0,}
};
.read = omnibook_wifi_read,
.write = omnibook_wifi_write,
.init = omnibook_wifi_init,
- .ectypes = TSM70 | TSM40,
+ .ectypes = TSM70 | TSM40 | TSX205,
.tbl = wireless_table,
};