From: Julien Valroff Date: Mon, 9 Mar 2009 17:17:06 +0000 (+0000) Subject: Applied patch from Azael Avalos to add support to Satellite... X-Git-Url: https://gitweb.devoid-pointer.net/?a=commitdiff_plain;h=a6473f966b2e060e09ffc42c9371f0b4709caca9;p=omnibook.git Applied patch from Azael Avalos to add support to Satellite X205 and other laptops based on ICH8 --- diff --git a/acpi.c b/acpi.c index db370da..2e21d6f 100644 --- a/acpi.c +++ b/acpi.c @@ -21,6 +21,10 @@ #ifdef CONFIG_ACPI #include +#include + +/* copied from drivers/input/serio/i8042-io.h */ +#define I8042_KBD_PHYS_DESC "isa0060/serio0" /* * ACPI backend masks and strings @@ -28,7 +32,7 @@ #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 @@ -107,8 +111,224 @@ struct acpi_backend_data { 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 */ @@ -158,6 +378,10 @@ static int omnibook_acpi_init(const struct omnibook_operation *io_op) (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); @@ -187,12 +411,20 @@ static int omnibook_acpi_init(const struct omnibook_operation *io_op) 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); @@ -250,6 +482,37 @@ static int omnibook_acpi_execute(acpi_handle dev_handle, char *method, const int 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 */ @@ -281,7 +544,7 @@ static int omnibook_acpi_bt_add(struct acpi_device *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); @@ -351,13 +614,44 @@ static int get_wireless_status(const struct acpi_backend_data *priv_data, unsign 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); @@ -385,14 +679,37 @@ static int set_wireless_status(const struct acpi_backend_data *priv_data, unsign 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) @@ -502,9 +819,146 @@ static int omnibook_acpi_set_throttle(const struct omnibook_operation *io_op, un 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, @@ -513,6 +967,8 @@ struct omnibook_backend acpi_backend = { .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 */ diff --git a/blank.c b/blank.c index 414e4c8..1bad34c 100644 --- a/blank.c +++ b/blank.c @@ -113,7 +113,7 @@ static void __exit omnibook_console_blank_cleanup(struct omnibook_operation *io_ } 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}}, @@ -129,7 +129,7 @@ static struct omnibook_feature __declared_feature blank_driver = { .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, }; diff --git a/bluetooth.c b/bluetooth.c index 07f9a4d..1095eec 100644 --- a/bluetooth.c +++ b/bluetooth.c @@ -85,8 +85,8 @@ static int __init omnibook_bt_init(struct omnibook_operation *io_op) } 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,} }; @@ -96,7 +96,7 @@ static struct omnibook_feature __declared_feature bt_driver = { .read = omnibook_bt_read, .write = omnibook_bt_write, .init = omnibook_bt_init, - .ectypes = TSM70 | TSM40 | TSA105, + .ectypes = TSM70 | TSM40 | TSA105 | TSX205, .tbl = wireless_table, }; diff --git a/compal.c b/compal.c index 7162a5e..52a52a5 100644 --- a/compal.c +++ b/compal.c @@ -91,6 +91,7 @@ const struct pci_device_id lpc_bridge_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 */ }; @@ -189,6 +190,7 @@ static int enable_cdimode(void) 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; @@ -278,6 +280,7 @@ static void clear_cdimode_pci(void) 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 */ @@ -303,7 +306,7 @@ static int omnibook_cdimode_init(const struct omnibook_operation *io_op) 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) { @@ -404,7 +407,7 @@ static void cdimode_free(struct kref *ref) 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); } diff --git a/cooling.c b/cooling.c index 486aa86..a9a935e 100644 --- a/cooling.c +++ b/cooling.c @@ -76,7 +76,7 @@ static void __exit omnibook_cooling_exit(struct omnibook_operation *io_op) } 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,} }; @@ -87,7 +87,7 @@ struct omnibook_feature __declared_feature cooling_driver = { .write = omnibook_cooling_write, .init = omnibook_cooling_init, .exit = omnibook_cooling_exit, - .ectypes = TSM70, + .ectypes = TSM70 | TSX205, .tbl = cooling_table, }; diff --git a/doc/ChangeLog b/doc/ChangeLog index 1487257..2b330cc 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -9,6 +9,9 @@ Changelog file for omnibook package: fix compiler warning about use uninitialized variable * Applied patch from Danny Kukawka to fix build the driver on older kernel versions +* Applied patch from Azael Avalos + to add support to Satellite X205 and other laptops based on + ICH8 2.20070211 Mathieu Bérard * Disable Acer support, acerhk module should provided better diff --git a/fan.c b/fan.c index 1587227..d812993 100644 --- a/fan.c +++ b/fan.c @@ -35,10 +35,10 @@ static int omnibook_get_fan(struct omnibook_operation *io_op) /* * 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; @@ -57,7 +57,7 @@ static int omnibook_fan_off(struct omnibook_operation *io_op) { 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 { @@ -156,7 +156,7 @@ static int __init omnibook_fan_init(struct omnibook_operation *io_op) } 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, @@ -174,7 +174,7 @@ static struct omnibook_feature __declared_feature fan_driver = { .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, }; diff --git a/hardware.h b/hardware.h index 16f8e8a..dcf627d 100644 --- a/hardware.h +++ b/hardware.h @@ -67,7 +67,7 @@ struct omnibook_backend { 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 *); @@ -534,3 +534,45 @@ static inline int omnibook_toggle(const struct omnibook_operation *io_op, int to #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 diff --git a/hotkeys.c b/hotkeys.c index f3bd263..7d541e1 100644 --- a/hotkeys.c +++ b/hotkeys.c @@ -50,7 +50,6 @@ static int hotkeys_set_save(struct omnibook_operation *io_op, unsigned int state */ static int hotkeys_get_save(struct omnibook_operation *io_op, unsigned int *state) { - unsigned int read_state = 0; int retval = 0; @@ -66,7 +65,6 @@ static int hotkeys_get_save(struct omnibook_operation *io_op, unsigned int *stat *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; @@ -129,7 +127,6 @@ static int omnibook_hotkeys_read(char *buffer, struct omnibook_operation *io_op) (read_state & mask) ? "enabled" : "disabled"); } - return len; } @@ -172,6 +169,7 @@ static struct omnibook_tbl hotkeys_table[] __initdata = { COMMAND(KBC,OMNIBOOK_KBC_CMD_ONETOUCH_ENABLE,OMNIBOOK_KBC_CMD_ONETOUCH_DISABLE)}, {TSM70, {CDI,}}, {TSM40, {SMI,}}, + {TSX205, {ACPI,}}, {0,} }; @@ -186,7 +184,7 @@ static struct omnibook_feature __declared_feature hotkeys_driver = { .resume = omnibook_hotkeys_resume, .ectypes = XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE4500 | AMILOD | TSP10 | TSM70 | TSM30X | - TSM40, + TSM40 | TSX205, .tbl = hotkeys_table, }; diff --git a/laptop.h b/laptop.h index 1c29b8b..dd0a198 100644 --- a/laptop.h +++ b/laptop.h @@ -779,6 +779,15 @@ static struct dmi_system_id omnibook_ids[] __initdata = { }, .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", diff --git a/lcd.c b/lcd.c index 43a3871..7702ea6 100644 --- a/lcd.c +++ b/lcd.c @@ -133,8 +133,9 @@ static int __init omnibook_brightness_init(struct omnibook_operation *io_op) * 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; @@ -180,7 +181,7 @@ static void __exit omnibook_brightness_cleanup(struct omnibook_operation *io_op) } 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)}, @@ -196,7 +197,7 @@ static struct omnibook_feature __declared_feature lcd_driver = { .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, }; diff --git a/omnibook.h b/omnibook.h index 49c4c41..db81114 100644 --- a/omnibook.h +++ b/omnibook.h @@ -38,13 +38,14 @@ extern enum omnibook_ectype_t { 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 @@ -53,15 +54,15 @@ extern enum omnibook_ectype_t { 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; @@ -82,13 +83,13 @@ enum { * 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 diff --git a/temperature.c b/temperature.c index 862e9bf..b27b611 100644 --- a/temperature.c +++ b/temperature.c @@ -33,7 +33,7 @@ static int omnibook_temperature_read(char *buffer, struct omnibook_operation *io } 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)}, @@ -46,7 +46,7 @@ static struct omnibook_feature __declared_feature temperature_driver = { .read = omnibook_temperature_read, .ectypes = XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE4500 | OB4150 | XE2 | AMILOD | TSP10 - | TSM70 | TSM30X, + | TSM70 | TSM30X | TSX205, .tbl = temp_table, }; diff --git a/throttling.c b/throttling.c index e2f6900..31d7f6e 100644 --- a/throttling.c +++ b/throttling.c @@ -64,7 +64,7 @@ static int omnibook_throttle_write(char *buffer, struct omnibook_operation *io_o static struct omnibook_tbl throttle_table[] __initdata = { - {TSM70, {ACPI,}}, + {TSM70 | TSX205, {ACPI,}}, {0,} }; @@ -73,7 +73,7 @@ struct omnibook_feature __declared_feature throttle_driver = { .enabled = 1, .read = omnibook_throttle_read, .write = omnibook_throttle_write, - .ectypes = TSM70, + .ectypes = TSM70 | TSX205, .tbl = throttle_table, }; diff --git a/wireless.c b/wireless.c index 81500ad..71b0c41 100644 --- a/wireless.c +++ b/wireless.c @@ -89,8 +89,8 @@ static int __init omnibook_wifi_init(struct omnibook_operation *io_op) } 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,} }; @@ -100,7 +100,7 @@ static struct omnibook_feature __declared_feature wifi_driver = { .read = omnibook_wifi_read, .write = omnibook_wifi_write, .init = omnibook_wifi_init, - .ectypes = TSM70 | TSM40, + .ectypes = TSM70 | TSM40 | TSX205, .tbl = wireless_table, };