From 4684ffb6d290ca21897ce1f794d3ce1b106d20ed Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mathieu=20B=C3=A9rard?= Date: Sat, 11 Nov 2006 15:36:50 +0000 Subject: [PATCH] * Fix missing mutex usage in nbsmi hotkeys handling * Implement bluetooth handling for ectype 14 (ACPI backend) * Update changelog --- acpi.c | 128 +++++++++++++++++++++++++++++++++++++++----------- bluetooth.c | 11 +++-- doc/ChangeLog | 1 + nbsmi.c | 4 +- wireless.c | 5 +- 5 files changed, 110 insertions(+), 39 deletions(-) diff --git a/acpi.c b/acpi.c index 02dd3e6..c3f2489 100644 --- a/acpi.c +++ b/acpi.c @@ -56,6 +56,7 @@ static char ec_dev_list[][20] = { #define TOSH_BT_DISABLE_USB "DUSB" #define TOSH_BT_POWER_ON "BTPO" #define TOSH_BT_POWER_OFF "BTPF" +#define TOSH_BT_STATUS "BTST" /* * ACPI driver for Toshiba Bluetooth device @@ -79,16 +80,16 @@ static struct acpi_driver omnibook_bt_driver = { struct acpi_backend_data { acpi_handle ec_handle; /* Handle on ACPI EC device */ acpi_handle bt_handle; /* Handle on ACPI BT device */ + unsigned has_antr_antw:1; /* Are there ANTR/ANTW methods in the EC device ? */ }; /* - * Probe for expected ACPI device - * FIXME we check only the ACPI device and not the associated methods + * Probe for expected ACPI devices */ static int omnibook_acpi_init(const struct omnibook_operation *io_op) { int retval = 0; - acpi_handle dev_handle; + acpi_handle dev_handle, method_handle; int i; struct acpi_backend_data *priv_data = io_op->backend->data; @@ -123,6 +124,10 @@ static int omnibook_acpi_init(const struct omnibook_operation *io_op) goto error1; } + if((acpi_get_handle( dev_handle, "ANTR", &method_handle) == AE_OK) && + (acpi_get_handle( dev_handle, "ANTW", &method_handle) == AE_OK)) + priv_data->has_antr_antw = 1; + io_op->backend->data = (void *) priv_data; /* attempt to register Toshiba bluetooth ACPI driver */ @@ -162,6 +167,9 @@ static void omnibook_acpi_exit(const struct omnibook_operation *io_op) kref_put(&io_op->backend->kref, omnibook_acpi_free); } +/* forward declaration */ +struct omnibook_backend acpi_backend; + /* * Execute an ACPI method which return either an integer or nothing * (acpi_evaluate_object wrapper) @@ -173,6 +181,8 @@ static int omnibook_acpi_execute(acpi_handle dev_handle, char *method, const int struct acpi_buffer buff; union acpi_object arg, out_objs[1]; + WARN_ON(!mutex_is_locked(&acpi_backend.mutex)); + if (param) { args_list.count = 1; args_list.pointer = &arg; @@ -201,8 +211,31 @@ static int omnibook_acpi_execute(acpi_handle dev_handle, char *method, const int return 0; } -/* forward declaration */ -struct omnibook_backend acpi_backend; +/* + * Set Bluetooth device state using the Toshiba BT device + */ +static int set_bt_status(const struct acpi_backend_data *priv_data, unsigned int state) +{ + int retval = 0; + + if(state) { + retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_ACTIVATE_USB, NULL, NULL); + if(retval) + goto out; + retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_POWER_ON, NULL, NULL); + if(retval) + goto out; + } else { + retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_DISABLE_USB, NULL, NULL); + if(retval) + goto out; + retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_POWER_OFF, NULL, NULL); + if(retval) + goto out; + } + out: + return retval; +} static int omnibook_acpi_bt_add(struct acpi_device *device) { @@ -215,28 +248,47 @@ static int omnibook_acpi_bt_add(struct acpi_device *device) /* Save handle in backend private data structure. ugly. */ priv_data->bt_handle = device->handle; - omnibook_acpi_execute(device->handle, TOSH_BT_ACTIVATE_USB, NULL, NULL); - omnibook_acpi_execute(device->handle, TOSH_BT_POWER_ON, NULL, NULL); - return 0; + return set_bt_status(priv_data, 1); } static int omnibook_acpi_bt_remove(struct acpi_device *device, int type) { + int retval; struct acpi_backend_data *priv_data = acpi_backend.data; dprintk("Disabling Toshiba Bluetooth ACPI device.\n"); + retval = set_bt_status(priv_data, 0); priv_data->bt_handle = NULL; - omnibook_acpi_execute(device->handle, TOSH_BT_DISABLE_USB, NULL, NULL); - omnibook_acpi_execute(device->handle, TOSH_BT_POWER_OFF, NULL, NULL); - return 0; + return retval; } +/* + * Get Bluetooth status using the BTST method + */ +static int get_bt_status(const struct acpi_backend_data *priv_data, unsigned int *state) +{ + int retval = 0; + int raw_state; + + if ((retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_STATUS, 0, &raw_state))) + return retval; -static int omnibook_acpi_get_wireless(const struct omnibook_operation *io_op, unsigned int *state) + printk(O_INFO "BTST raw_state: %x\n", raw_state); + + /* FIXME: raw_state => state translation */ + *state = BT_EX; + + return retval; +} + +/* + * Get the Bluetooth + Wireless status using the ANTR method + * FIXME: what if ANTR and BTST disagree ? we thrust ANTR for now + */ +static int get_wireless_status(const struct acpi_backend_data *priv_data, unsigned int *state) { int retval = 0; int raw_state; - struct acpi_backend_data *priv_data = io_op->backend->data; if ((retval = omnibook_acpi_execute(priv_data->ec_handle, GET_WIRELESS_METHOD, 0, &raw_state))) return retval; @@ -252,31 +304,51 @@ static int omnibook_acpi_get_wireless(const struct omnibook_operation *io_op, un 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; -static int omnibook_acpi_set_wireless(const struct omnibook_operation *io_op, unsigned int state) + /* use BTST (BT device) if we don't have ANTR/ANTW (EC device) */ + 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); + else + retval = -ENODEV; + + return retval; +} + +/* + * Set the Bluetooth + Wireless status using the ANTW method + */ +static int set_wireless_status(const struct acpi_backend_data *priv_data, unsigned int state) { - int retval = 0; + int retval; int raw_state; - struct acpi_backend_data *priv_data = io_op->backend->data; - char *method; raw_state = !!(state & WIFI_STA); /* bit 0 */ raw_state |= !!(state & BT_STA) << 0x1; /* bit 1 */ dprintk("set_wireless raw_state: %x\n", raw_state); - if ((retval = omnibook_acpi_execute(priv_data->ec_handle, SET_WIRELESS_METHOD, &raw_state, NULL))) - return retval; + retval = omnibook_acpi_execute(priv_data->ec_handle, SET_WIRELESS_METHOD, &raw_state, NULL); - /* BT device appears to need more work*/ - if(priv_data->bt_handle) { - method = (state & BT_STA) ? TOSH_BT_POWER_ON : TOSH_BT_POWER_OFF; - if ((retval = omnibook_acpi_execute(priv_data->bt_handle, method, NULL, NULL))) - return retval; - method = (state & BT_STA) ? TOSH_BT_ACTIVATE_USB : TOSH_BT_DISABLE_USB; - if ((retval = omnibook_acpi_execute(priv_data->bt_handle, method, NULL, NULL))) - return retval; - } + return retval; +} + +static int omnibook_acpi_set_wireless(const struct omnibook_operation *io_op, unsigned int state) +{ + int retval; + struct acpi_backend_data *priv_data = io_op->backend->data; + + if(priv_data->has_antr_antw) + retval = set_wireless_status(priv_data, state); + else if(priv_data->bt_handle) + retval = set_bt_status(priv_data, (state & BT_STA)); + else + retval = -ENODEV; return retval; } diff --git a/bluetooth.c b/bluetooth.c index acb0e5b..d839837 100644 --- a/bluetooth.c +++ b/bluetooth.c @@ -84,10 +84,11 @@ static int __init omnibook_bt_init(struct omnibook_operation *io_op) return retval; } -/* - * To avoid duplication the table is in wireless.c - */ -extern struct omnibook_tbl wireless_table[]; +static struct omnibook_tbl wireless_table[] __initdata = { + {TSM30X | TSA105, {ACPI,}}, /* stubs to select backend */ + {TSM40, {SMI,}}, /* stubs to select backend */ + {0,} +}; static struct omnibook_feature __declared_feature bt_driver = { .name = "bluetooth", @@ -95,7 +96,7 @@ static struct omnibook_feature __declared_feature bt_driver = { .read = omnibook_bt_read, .write = omnibook_bt_write, .init = omnibook_bt_init, - .ectypes = TSM30X | TSM40, + .ectypes = TSM30X | TSM40 | TSA105, .tbl = wireless_table, }; diff --git a/doc/ChangeLog b/doc/ChangeLog index c29f791..609480e 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -14,6 +14,7 @@ Changelog file for omnibook package: HP Pavilion ze4500 (ectype 7) Toshiba Satellite 1130 (ectype 1) Toshiba Satellite A75 (ectype 12) + Toshiba Tecra A4 (ectype 13) 2.20060921 Mathieu Bérard * The minimal required kernel version is now 2.6.9 (kref API) diff --git a/nbsmi.c b/nbsmi.c index c8da23b..94bb6e2 100644 --- a/nbsmi.c +++ b/nbsmi.c @@ -652,14 +652,14 @@ static int adjust_brighness(int delta) static const struct omnibook_operation last_scan_op = SIMPLE_BYTE(SMI,SMI_GET_FN_LAST_SCAN,0); /* - * Workqueue hanlder for Fn hotkeys + * Workqueue handler for Fn hotkeys */ static void omnibook_handle_fnkey(void* data) { int i; u8 gen_scan; - if(nbsmi_smi_read_command(&last_scan_op, &gen_scan)) + if(backend_byte_read(&last_scan_op, &gen_scan)) return; dprintk("detected scancode %x.\n", gen_scan); diff --git a/wireless.c b/wireless.c index aad5ca9..2ae6eaf 100644 --- a/wireless.c +++ b/wireless.c @@ -88,10 +88,7 @@ static int __init omnibook_wifi_init(struct omnibook_operation *io_op) return retval; } -/* - * Shared with bluetooth.c - */ -struct omnibook_tbl wireless_table[] __initdata = { +static struct omnibook_tbl wireless_table[] __initdata = { {TSM30X, {ACPI,}}, /* stubs to select backend */ {TSM40, {SMI,}}, /* stubs to select backend */ {0,} -- 2.43.5