From 49979d091d1847823c064301da1ec173619ddd92 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Fri, 1 Jul 2011 11:34:26 +0200 Subject: asus-wmi: fix hwmon/pwm1 The code was completly broken, and should never had been sent to the kernel. That's what happens when you write code without hardware to test it. Cc: stable@kernel.org Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-wmi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 65b66aa44c7..bcb9fb41ddc 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -797,8 +797,8 @@ exit: * Hwmon device */ static ssize_t asus_hwmon_pwm1(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, + char *buf) { struct asus_wmi *asus = dev_get_drvdata(dev); u32 value; @@ -809,7 +809,7 @@ static ssize_t asus_hwmon_pwm1(struct device *dev, if (err < 0) return err; - value |= 0xFF; + value &= 0xFF; if (value == 1) /* Low Speed */ value = 85; @@ -869,7 +869,7 @@ static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, * - reverved bits are non-zero * - sfun and presence bit are not set */ - if (value != ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 + if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT))) ok = false; } @@ -904,6 +904,7 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus) pr_err("Could not register asus hwmon device\n"); return PTR_ERR(hwmon); } + dev_set_drvdata(hwmon, asus); asus->hwmon_device = hwmon; result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group); if (result) -- cgit v1.2.3-70-g09d2 From c4453f6a7ceff330ff37a9712ee8305fc3f8e9b6 Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Fri, 1 Jul 2011 11:34:27 +0200 Subject: asus-wmi: Add callback for hotkey filtering This is required for the T101MT home key, which behaves differently than other hotkeys. Signed-off-by: Seth Forshee Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-wmi.c | 12 +++++++++++- drivers/platform/x86/asus-wmi.h | 6 ++++++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index bcb9fb41ddc..cea9fdcad64 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -1061,6 +1061,8 @@ static void asus_wmi_notify(u32 value, void *context) acpi_status status; int code; int orig_code; + unsigned int key_value = 1; + bool autorelease = 1; status = wmi_get_event_data(value, &response); if (status != AE_OK) { @@ -1076,6 +1078,13 @@ static void asus_wmi_notify(u32 value, void *context) code = obj->integer.value; orig_code = code; + if (asus->driver->key_filter) { + asus->driver->key_filter(asus->driver, &code, &key_value, + &autorelease); + if (code == ASUS_WMI_KEY_IGNORE) + goto exit; + } + if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) code = NOTIFY_BRNUP_MIN; else if (code >= NOTIFY_BRNDOWN_MIN && @@ -1085,7 +1094,8 @@ static void asus_wmi_notify(u32 value, void *context) if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) { if (!acpi_video_backlight_support()) asus_wmi_backlight_notify(asus, orig_code); - } else if (!sparse_keymap_report_event(asus->inputdev, code, 1, true)) + } else if (!sparse_keymap_report_event(asus->inputdev, code, + key_value, autorelease)) pr_info("Unknown key %x pressed\n", code); exit: diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h index c044522c876..4da61033bcb 100644 --- a/drivers/platform/x86/asus-wmi.h +++ b/drivers/platform/x86/asus-wmi.h @@ -29,6 +29,8 @@ #include +#define ASUS_WMI_KEY_IGNORE (-1) + struct module; struct key_entry; struct asus_wmi; @@ -44,6 +46,10 @@ struct asus_wmi_driver { const struct key_entry *keymap; const char *input_name; const char *input_phys; + /* Returns new code, value, and autorelease values in arguments. + * Return ASUS_WMI_KEY_IGNORE in code if event should be ignored. */ + void (*key_filter) (struct asus_wmi_driver *driver, int *code, + unsigned int *value, bool *autorelease); int (*probe) (struct platform_device *device); void (*quirks) (struct asus_wmi_driver *driver); -- cgit v1.2.3-70-g09d2 From 39bbde059973d3337ae5f2fae5097d52599415e4 Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Mon, 4 Jul 2011 09:49:20 +0200 Subject: asus-wmi: Enable autorepeat for hotkey input device The T101MT Home/Express Gate key autorepeats in hardware, but sparse-keymap does not support hardware autorepeat. Enable the input core's software autorepeat to emulate the hardware behavior. Normal hotkeys are autoreleased, so the behavior of these keys will not be affected. Signed-off-by: Seth Forshee Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-wmi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index cea9fdcad64..0fce7de77b1 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -205,6 +205,7 @@ static int asus_wmi_input_init(struct asus_wmi *asus) asus->inputdev->phys = asus->driver->input_phys; asus->inputdev->id.bustype = BUS_HOST; asus->inputdev->dev.parent = &asus->platform_device->dev; + set_bit(EV_REP, asus->inputdev->evbit); err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL); if (err) -- cgit v1.2.3-70-g09d2 From 57d5c8e742dbb8cdc794d9e0fee769c9533072af Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Fri, 1 Jul 2011 11:34:30 +0200 Subject: asus-wmi: second part of the version starts at 16 not 8 Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 0fce7de77b1..fa2b395145a 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -1246,7 +1246,7 @@ static int asus_wmi_platform_init(struct asus_wmi *asus) /* We don't know yet what to do with this version... */ if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) { - pr_info("BIOS WMI version: %d.%d", rv >> 8, rv & 0xFF); + pr_info("BIOS WMI version: %d.%d", rv >> 16, rv & 0xFF); asus->spec = rv; } -- cgit v1.2.3-70-g09d2 From e9809c0b9670656855655d8ed6dc33718ec12ba2 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Fri, 1 Jul 2011 11:34:31 +0200 Subject: asus-wmi: add keyboard backlight support Based on a patch from Nate Weibley. . Cc: Nate Weibley Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-wmi.c | 130 ++++++++++++++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 17 deletions(-) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index fa2b395145a..83a7a8101fd 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -66,6 +66,8 @@ MODULE_LICENSE("GPL"); #define NOTIFY_BRNUP_MAX 0x1f #define NOTIFY_BRNDOWN_MIN 0x20 #define NOTIFY_BRNDOWN_MAX 0x2e +#define NOTIFY_KBD_BRTUP 0xc4 +#define NOTIFY_KBD_BRTDWN 0xc5 /* WMI Methods */ #define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */ @@ -174,8 +176,11 @@ struct asus_wmi { struct led_classdev tpd_led; int tpd_led_wk; + struct led_classdev kbd_led; + int kbd_led_wk; struct workqueue_struct *led_workqueue; struct work_struct tpd_led_work; + struct work_struct kbd_led_work; struct asus_rfkill wlan; struct asus_rfkill bluetooth; @@ -360,30 +365,79 @@ static enum led_brightness tpd_led_get(struct led_classdev *led_cdev) return read_tpd_led_state(asus); } -static int asus_wmi_led_init(struct asus_wmi *asus) +static void kbd_led_update(struct work_struct *work) { - int rv; + int ctrl_param = 0; + struct asus_wmi *asus; - if (read_tpd_led_state(asus) < 0) - return 0; + asus = container_of(work, struct asus_wmi, kbd_led_work); - asus->led_workqueue = create_singlethread_workqueue("led_workqueue"); - if (!asus->led_workqueue) - return -ENOMEM; - INIT_WORK(&asus->tpd_led_work, tpd_led_update); + /* + * bits 0-2: level + * bit 7: light on/off + */ + if (asus->kbd_led_wk > 0) + ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F); - asus->tpd_led.name = "asus::touchpad"; - asus->tpd_led.brightness_set = tpd_led_set; - asus->tpd_led.brightness_get = tpd_led_get; - asus->tpd_led.max_brightness = 1; + asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL); +} - rv = led_classdev_register(&asus->platform_device->dev, &asus->tpd_led); - if (rv) { - destroy_workqueue(asus->led_workqueue); - return rv; +static int kbd_led_read(struct asus_wmi *asus, int *level, int *env) +{ + int retval; + + /* + * bits 0-2: level + * bit 7: light on/off + * bit 8-10: environment (0: dark, 1: normal, 2: light) + * bit 17: status unknown + */ + retval = asus_wmi_get_devstate_bits(asus, ASUS_WMI_DEVID_KBD_BACKLIGHT, + 0xFFFF); + + if (retval == 0x8000) + retval = -ENODEV; + + if (retval >= 0) { + if (level) + *level = retval & 0x80 ? retval & 0x7F : 0; + if (env) + *env = (retval >> 8) & 0x7F; + retval = 0; } - return 0; + return retval; +} + +static void kbd_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct asus_wmi *asus; + + asus = container_of(led_cdev, struct asus_wmi, kbd_led); + + if (value > asus->kbd_led.max_brightness) + value = asus->kbd_led.max_brightness; + else if (value < 0) + value = 0; + + asus->kbd_led_wk = value; + queue_work(asus->led_workqueue, &asus->kbd_led_work); +} + +static enum led_brightness kbd_led_get(struct led_classdev *led_cdev) +{ + struct asus_wmi *asus; + int retval, value; + + asus = container_of(led_cdev, struct asus_wmi, kbd_led); + + retval = kbd_led_read(asus, &value, NULL); + + if (retval < 0) + return retval; + + return value; } static void asus_wmi_led_exit(struct asus_wmi *asus) @@ -394,6 +448,48 @@ static void asus_wmi_led_exit(struct asus_wmi *asus) destroy_workqueue(asus->led_workqueue); } +static int asus_wmi_led_init(struct asus_wmi *asus) +{ + int rv = 0; + + asus->led_workqueue = create_singlethread_workqueue("led_workqueue"); + if (!asus->led_workqueue) + return -ENOMEM; + + if (read_tpd_led_state(asus) >= 0) { + INIT_WORK(&asus->tpd_led_work, tpd_led_update); + + asus->tpd_led.name = "asus::touchpad"; + asus->tpd_led.brightness_set = tpd_led_set; + asus->tpd_led.brightness_get = tpd_led_get; + asus->tpd_led.max_brightness = 1; + + rv = led_classdev_register(&asus->platform_device->dev, + &asus->tpd_led); + if (rv) + goto error; + } + + if (kbd_led_read(asus, NULL, NULL) >= 0) { + INIT_WORK(&asus->kbd_led_work, kbd_led_update); + + asus->kbd_led.name = "asus::kbd_backlight"; + asus->kbd_led.brightness_set = kbd_led_set; + asus->kbd_led.brightness_get = kbd_led_get; + asus->kbd_led.max_brightness = 3; + + rv = led_classdev_register(&asus->platform_device->dev, + &asus->kbd_led); + } + +error: + if (rv) + asus_wmi_led_exit(asus); + + return rv; +} + + /* * PCI hotplug (for wlan rfkill) */ -- cgit v1.2.3-70-g09d2 From 8fe8c25ef92ffc773a49c4b0dab2938a6fd64489 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Fri, 1 Jul 2011 11:34:32 +0200 Subject: asus-wmi: fix section mismatch Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 83a7a8101fd..41a96f2b136 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -1712,7 +1712,7 @@ static int asus_wmi_probe(struct platform_device *pdev) static bool used; -int asus_wmi_register_driver(struct asus_wmi_driver *driver) +int __init_or_module asus_wmi_register_driver(struct asus_wmi_driver *driver) { struct platform_driver *platform_driver; struct platform_device *platform_device; -- cgit v1.2.3-70-g09d2 From af965e973276b015d1b7d9ee78ed8d8df9d6bc98 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Fri, 1 Jul 2011 11:34:34 +0200 Subject: asus-wmi: fix keyboard backlight detection Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-wmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 41a96f2b136..4b0384e140f 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -395,8 +395,9 @@ static int kbd_led_read(struct asus_wmi *asus, int *level, int *env) retval = asus_wmi_get_devstate_bits(asus, ASUS_WMI_DEVID_KBD_BACKLIGHT, 0xFFFF); + /* Unknown status is considered as off */ if (retval == 0x8000) - retval = -ENODEV; + retval = 0; if (retval >= 0) { if (level) -- cgit v1.2.3-70-g09d2 From 79ec1172c29ed521f1652b0b44dceb84ba115541 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Fri, 1 Jul 2011 11:34:35 +0200 Subject: asus-wmi: add some device ids Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-wmi.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 4b0384e140f..e60385df4af 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -95,6 +95,7 @@ MODULE_LICENSE("GPL"); /* Wireless */ #define ASUS_WMI_DEVID_HW_SWITCH 0x00010001 #define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002 +#define ASUS_WMI_DEVID_CWAP 0x00010003 #define ASUS_WMI_DEVID_WLAN 0x00010011 #define ASUS_WMI_DEVID_BLUETOOTH 0x00010013 #define ASUS_WMI_DEVID_GPS 0x00010015 @@ -104,6 +105,12 @@ MODULE_LICENSE("GPL"); /* Leds */ /* 0x000200XX and 0x000400XX */ +#define ASUS_WMI_DEVID_LED1 0x00020011 +#define ASUS_WMI_DEVID_LED2 0x00020012 +#define ASUS_WMI_DEVID_LED3 0x00020013 +#define ASUS_WMI_DEVID_LED4 0x00020014 +#define ASUS_WMI_DEVID_LED5 0x00020015 +#define ASUS_WMI_DEVID_LED6 0x00020016 /* Backlight and Brightness */ #define ASUS_WMI_DEVID_BACKLIGHT 0x00050011 -- cgit v1.2.3-70-g09d2 From 6118b8adb50c23714d5be089965082bbbb48d831 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Fri, 1 Jul 2011 11:34:36 +0200 Subject: asus-wmi: add thermal sensor Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-wmi.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index e60385df4af..d01f767c7b6 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -930,7 +931,26 @@ static ssize_t asus_hwmon_pwm1(struct device *dev, return sprintf(buf, "%d\n", value); } +static ssize_t asus_hwmon_temp1(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct asus_wmi *asus = dev_get_drvdata(dev); + u32 value; + int err; + + err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_THERMAL_CTRL, &value); + + if (err < 0) + return err; + + value = KELVIN_TO_CELSIUS((value & 0xFFFF)) * 1000; + + return sprintf(buf, "%d\n", value); +} + static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, asus_hwmon_pwm1, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL, 0); static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) @@ -941,6 +961,7 @@ static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); static struct attribute *hwmon_attributes[] = { &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_name.dev_attr.attr, NULL }; -- cgit v1.2.3-70-g09d2 From e02431d6f5e8f1023ce0cfbaf70ddf4afae924d8 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Fri, 1 Jul 2011 11:34:37 +0200 Subject: asus-wmi: check for temp1 presence Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-wmi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index d01f767c7b6..e50872632c5 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -967,7 +967,7 @@ static struct attribute *hwmon_attributes[] = { }; static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, - struct attribute *attr, int idx) + struct attribute *attr, int idx) { struct device *dev = container_of(kobj, struct device, kobj); struct platform_device *pdev = to_platform_device(dev->parent); @@ -978,6 +978,8 @@ static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, if (attr == &sensor_dev_attr_pwm1.dev_attr.attr) dev_id = ASUS_WMI_DEVID_FAN_CTRL; + else if (attr == &sensor_dev_attr_temp1_input.dev_attr.attr) + dev_id = ASUS_WMI_DEVID_THERMAL_CTRL; if (dev_id != -1) { int err = asus_wmi_get_devstate(asus, dev_id, &value); @@ -998,6 +1000,10 @@ static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT))) ok = false; + } else if (dev_id == ASUS_WMI_DEVID_THERMAL_CTRL) { + /* If value is zero, something is clearly wrong */ + if (value == 0) + ok = false; } return ok ? attr->mode : 0; -- cgit v1.2.3-70-g09d2 From 3df5fdadf6400373a696bb14e27d4771e5f6afb3 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Fri, 1 Jul 2011 11:34:38 +0200 Subject: asus-wmi: return proper value in store_cpufv() Cc: stable@kernel.org Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-wmi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index e50872632c5..3b9fb91e25f 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -1307,14 +1307,18 @@ ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER); static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - int value; + int value, rv; if (!count || sscanf(buf, "%i", &value) != 1) return -EINVAL; if (value < 0 || value > 2) return -EINVAL; - return asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); + rv = asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); + if (rv < 0) + return rv; + + return count; } static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv); -- cgit v1.2.3-70-g09d2 From fddbfed595b307f9dddc7a86ddfbcbcb80141e28 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Fri, 1 Jul 2011 11:34:39 +0200 Subject: asus-wmi: add CWAP support and clarify the meaning of WAPF bits ref: http://dev.iksaif.net/projects/3/wiki/Asus-laptop_WAPF Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-laptop.c | 9 ++++----- drivers/platform/x86/asus-nb-wmi.c | 27 +++++++++++++++++++++++---- drivers/platform/x86/asus-wmi.c | 6 ++++++ drivers/platform/x86/asus-wmi.h | 1 + drivers/platform/x86/eeepc-wmi.c | 1 + 5 files changed, 35 insertions(+), 9 deletions(-) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index d65df92e2ac..fa6d7ec68b2 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -70,11 +70,10 @@ MODULE_LICENSE("GPL"); * WAPF defines the behavior of the Fn+Fx wlan key * The significance of values is yet to be found, but * most of the time: - * 0x0 will do nothing - * 0x1 will allow to control the device with Fn+Fx key. - * 0x4 will send an ACPI event (0x88) while pressing the Fn+Fx key - * 0x5 like 0x1 or 0x4 - * So, if something doesn't work as you want, just try other values =) + * Bit | Bluetooth | WLAN + * 0 | Hardware | Hardware + * 1 | Hardware | Software + * 4 | Software | Software */ static uint wapf = 1; module_param(wapf, uint, 0444); diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index 0580d99b079..b0859d4183e 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -38,6 +38,24 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID); +/* + * WAPF defines the behavior of the Fn+Fx wlan key + * The significance of values is yet to be found, but + * most of the time: + * Bit | Bluetooth | WLAN + * 0 | Hardware | Hardware + * 1 | Hardware | Software + * 4 | Software | Software + */ +static uint wapf; +module_param(wapf, uint, 0444); +MODULE_PARM_DESC(wapf, "WAPF value"); + +static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) +{ + driver->wapf = wapf; +} + static const struct key_entry asus_nb_wmi_keymap[] = { { KE_KEY, 0x30, { KEY_VOLUMEUP } }, { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, @@ -53,16 +71,16 @@ static const struct key_entry asus_nb_wmi_keymap[] = { { KE_KEY, 0x51, { KEY_WWW } }, { KE_KEY, 0x55, { KEY_CALC } }, { KE_KEY, 0x5C, { KEY_F15 } }, /* Power Gear key */ - { KE_KEY, 0x5D, { KEY_WLAN } }, - { KE_KEY, 0x5E, { KEY_WLAN } }, - { KE_KEY, 0x5F, { KEY_WLAN } }, + { KE_KEY, 0x5D, { KEY_WLAN } }, /* Wireless console Toggle */ + { KE_KEY, 0x5E, { KEY_WLAN } }, /* Wireless console Enable */ + { KE_KEY, 0x5F, { KEY_WLAN } }, /* Wireless console Disable */ { KE_KEY, 0x60, { KEY_SWITCHVIDEOMODE } }, { KE_KEY, 0x61, { KEY_SWITCHVIDEOMODE } }, { KE_KEY, 0x62, { KEY_SWITCHVIDEOMODE } }, { KE_KEY, 0x63, { KEY_SWITCHVIDEOMODE } }, { KE_KEY, 0x6B, { KEY_TOUCHPAD_TOGGLE } }, - { KE_KEY, 0x7E, { KEY_BLUETOOTH } }, { KE_KEY, 0x7D, { KEY_BLUETOOTH } }, + { KE_KEY, 0x7E, { KEY_BLUETOOTH } }, { KE_KEY, 0x82, { KEY_CAMERA } }, { KE_KEY, 0x88, { KEY_RFKILL } }, { KE_KEY, 0x8A, { KEY_PROG1 } }, @@ -81,6 +99,7 @@ static struct asus_wmi_driver asus_nb_wmi_driver = { .keymap = asus_nb_wmi_keymap, .input_name = "Asus WMI hotkeys", .input_phys = ASUS_NB_WMI_FILE "/input0", + .quirks = asus_nb_wmi_quirks, }; diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 3b9fb91e25f..8787dfacf11 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -1413,6 +1413,12 @@ static int asus_wmi_platform_init(struct asus_wmi *asus) return -ENODEV; } + /* CWAP allow to define the behavior of the Fn+F2 key, + * this method doesn't seems to be present on Eee PCs */ + if (asus->driver->wapf >= 0) + asus_wmi_set_devstate(ASUS_WMI_DEVID_CWAP, + asus->driver->wapf, NULL); + return asus_wmi_sysfs_init(asus->platform_device); } diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h index 4da61033bcb..8147c10161c 100644 --- a/drivers/platform/x86/asus-wmi.h +++ b/drivers/platform/x86/asus-wmi.h @@ -37,6 +37,7 @@ struct asus_wmi; struct asus_wmi_driver { bool hotplug_wireless; + int wapf; const char *name; struct module *owner; diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index f41a977efa9..9f6e64302b4 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c @@ -166,6 +166,7 @@ static void eeepc_dmi_check(struct asus_wmi_driver *driver) static void eeepc_wmi_quirks(struct asus_wmi_driver *driver) { driver->hotplug_wireless = hotplug_wireless; + driver->wapf = -1; eeepc_dmi_check(driver); } -- cgit v1.2.3-70-g09d2 From 43be8bde1fdfbe3f4dedfd04ca4f9d6dd1e04b46 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Fri, 1 Jul 2011 11:34:40 +0200 Subject: asus-wmi: add gps rfkill support Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-wmi.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 8787dfacf11..57514deb8e2 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -194,6 +194,7 @@ struct asus_wmi { struct asus_rfkill bluetooth; struct asus_rfkill wimax; struct asus_rfkill wwan3g; + struct asus_rfkill gps; struct hotplug_slot *hotplug_slot; struct mutex hotplug_lock; @@ -835,6 +836,11 @@ static void asus_wmi_rfkill_exit(struct asus_wmi *asus) rfkill_destroy(asus->wwan3g.rfkill); asus->wwan3g.rfkill = NULL; } + if (asus->gps.rfkill) { + rfkill_unregister(asus->gps.rfkill); + rfkill_destroy(asus->gps.rfkill); + asus->gps.rfkill = NULL; + } } static int asus_wmi_rfkill_init(struct asus_wmi *asus) @@ -869,6 +875,12 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus) if (result && result != -ENODEV) goto exit; + result = asus_new_rfkill(asus, &asus->gps, "asus-gps", + RFKILL_TYPE_GPS, ASUS_WMI_DEVID_GPS); + + if (result && result != -ENODEV) + goto exit; + if (!asus->driver->hotplug_wireless) goto exit; @@ -1721,6 +1733,10 @@ static int asus_hotk_restore(struct device *device) bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WWAN3G); rfkill_set_sw_state(asus->wwan3g.rfkill, bl); } + if (asus->gps.rfkill) { + bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPS); + rfkill_set_sw_state(asus->gps.rfkill, bl); + } return 0; } -- cgit v1.2.3-70-g09d2 From a912d329102aa13c572989c6adc103685c9d24ae Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Fri, 1 Jul 2011 11:34:41 +0200 Subject: asus-wmi: add uwb rfkill support Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus-wmi.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers/platform/x86/asus-wmi.c') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 57514deb8e2..95cba9ebf6c 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -195,6 +195,7 @@ struct asus_wmi { struct asus_rfkill wimax; struct asus_rfkill wwan3g; struct asus_rfkill gps; + struct asus_rfkill uwb; struct hotplug_slot *hotplug_slot; struct mutex hotplug_lock; @@ -841,6 +842,11 @@ static void asus_wmi_rfkill_exit(struct asus_wmi *asus) rfkill_destroy(asus->gps.rfkill); asus->gps.rfkill = NULL; } + if (asus->uwb.rfkill) { + rfkill_unregister(asus->uwb.rfkill); + rfkill_destroy(asus->uwb.rfkill); + asus->uwb.rfkill = NULL; + } } static int asus_wmi_rfkill_init(struct asus_wmi *asus) @@ -881,6 +887,12 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus) if (result && result != -ENODEV) goto exit; + result = asus_new_rfkill(asus, &asus->uwb, "asus-uwb", + RFKILL_TYPE_UWB, ASUS_WMI_DEVID_UWB); + + if (result && result != -ENODEV) + goto exit; + if (!asus->driver->hotplug_wireless) goto exit; @@ -1737,6 +1749,10 @@ static int asus_hotk_restore(struct device *device) bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPS); rfkill_set_sw_state(asus->gps.rfkill, bl); } + if (asus->uwb.rfkill) { + bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_UWB); + rfkill_set_sw_state(asus->uwb.rfkill, bl); + } return 0; } -- cgit v1.2.3-70-g09d2