Removal of the old sysfs file will be left for a future patch. Also, I don't own the hardware, so this patch is compile tested only (though mostly based on the working acer-wmi code). While we're at it, fix the broken Kconfig description. Signed-off-by: Carlos Corbacho <carlos@xxxxxxxxxxxxxxxxxxx> --- drivers/misc/Kconfig | 5 ++- drivers/misc/tc1100-wmi.c | 76 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index cce9202..1caa81b 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -208,12 +208,13 @@ config FUJITSU_LAPTOP_DEBUG config TC1100_WMI tristate "HP Compaq TC1100 Tablet WMI Extras (EXPERIMENTAL)" depends on X86 && !X86_64 + depends on RFKILL depends on EXPERIMENTAL depends on ACPI select ACPI_WMI ---help--- - This is a driver for the WMI extensions (wireless and bluetooth power - control) of the HP Compaq TC1100 tablet. + This is a driver for the WMI extensions (wireless power control and + jogdial mode) of the HP Compaq TC1100 tablet. config HP_WMI tristate "HP WMI extras" diff --git a/drivers/misc/tc1100-wmi.c b/drivers/misc/tc1100-wmi.c index f25e4c9..ed49269 100644 --- a/drivers/misc/tc1100-wmi.c +++ b/drivers/misc/tc1100-wmi.c @@ -1,7 +1,7 @@ /* * HP Compaq TC1100 Tablet WMI Extras Driver * - * Copyright (C) 2007 Carlos Corbacho <carlos@xxxxxxxxxxxxxxxxxxx> + * Copyright (C) 2007-2008 Carlos Corbacho <carlos@xxxxxxxxxxxxxxxxxxx> * Copyright (C) 2004 Jamey Hicks <jamey.hicks@xxxxxx> * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@xxxxxxxxx> * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@xxxxxxxxx> @@ -28,7 +28,9 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> +#include <linux/rfkill.h> #include <linux/types.h> +#include <linux/workqueue.h> #include <acpi/acpi.h> #include <acpi/actypes.h> #include <acpi/acpi_bus.h> @@ -73,6 +75,8 @@ struct tc1100_data { static struct tc1100_data suspend_data; +static struct rfkill *wireless_rfkill; + /* -------------------------------------------------------------------------- Device Management -------------------------------------------------------------------------- */ @@ -151,6 +155,71 @@ static int set_state(u32 *in, u8 instance) } /* -------------------------------------------------------------------------- + Rfkill + -------------------------------------------------------------------------- */ + +static void tc1100_rfkill_update(struct work_struct *ignored); +static DECLARE_DELAYED_WORK(tc1100_rfkill_work, tc1100_rfkill_update); +static void tc1100_rfkill_update(struct work_struct *ignored) +{ + u32 state; + int status; + + status = get_state(&state, TC1100_INSTANCE_WIRELESS); + if (!status) + rfkill_force_state(wireless_rfkill, state ? + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED); + + schedule_delayed_work(&tc1100_rfkill_work, round_jiffies_relative(HZ)); +} + +static int tc1100_rfkill_set(void *data, enum rfkill_state new_state) +{ + u32 state; + int status; + + state = (u32) (new_state == RFKILL_STATE_UNBLOCKED); + status = set_state(&state, TC1100_INSTANCE_WIRELESS); + if (status) + return -ENODEV; + return 0; +} + +static int tc1100_rfkill_init(struct device *dev) +{ + int err; + u32 state; + + wireless_rfkill = rfkill_allocate(dev, RFKILL_TYPE_WLAN); + if (!wireless_rfkill) + return -ENOMEM; + wireless_rfkill->name = "tc1100-wireless"; + get_state(&state, TC1100_INSTANCE_WIRELESS); + wireless_rfkill->state = state ? RFKILL_STATE_UNBLOCKED : + RFKILL_STATE_SOFT_BLOCKED; + wireless_rfkill->toggle_radio = tc1100_rfkill_set; + wireless_rfkill->user_claim_unsupported = 1; + + err = rfkill_register(wireless_rfkill); + if (err) { + kfree(wireless_rfkill->data); + rfkill_free(wireless_rfkill); + return err; + } + + schedule_delayed_work(&tc1100_rfkill_work, round_jiffies_relative(HZ)); + + return 0; +} + +static void tc1100_rfkill_exit(void) +{ + cancel_delayed_work_sync(&tc1100_rfkill_work); + rfkill_unregister(wireless_rfkill); + return; +} + +/* -------------------------------------------------------------------------- FS Interface (/sys) -------------------------------------------------------------------------- */ @@ -218,6 +287,10 @@ static int tc1100_probe(struct platform_device *device) { int result = 0; + result = tc1100_rfkill_init(&device->dev); + if (result) + return result; + result = add_fs(); return result; } @@ -225,6 +298,7 @@ static int tc1100_probe(struct platform_device *device) static int tc1100_remove(struct platform_device *device) { + tc1100_rfkill_exit(); remove_fs(); return 0; } -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html