diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-11-14 17:20:46 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-11-14 17:20:46 -0500 |
commit | 5ae93760cbedda64eab0a7012cc3785c32399641 (patch) | |
tree | 234554665182ca5f391e081de2a7339b2640ff27 | |
parent | e57c641ffb75b90c7f7637916e390dc837b70917 (diff) | |
parent | 0cdbcd6d3ebeffa7d1a475ed7a294315cd046a11 (diff) |
Merge tag 'platform-drivers-x86-v3.18-3' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86
Pull x86 platform drivers fixlets from Darren Hart:
"Just two patches to remove hp_accel events from the keyboard bus
stream via an i8042 filter"
* tag 'platform-drivers-x86-v3.18-3' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86:
platform: hp_accel: Add SERIO_I8042 as a dependency since it now includes i8042.h/serio.h
platform: hp_accel: add a i8042 filter to remove HPQ6000 data from kb bus stream
-rw-r--r-- | drivers/platform/x86/Kconfig | 1 | ||||
-rw-r--r-- | drivers/platform/x86/hp_accel.c | 44 |
2 files changed, 45 insertions, 0 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 4dcfb7116a04..a2eabe6ff9ad 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -202,6 +202,7 @@ config TC1100_WMI | |||
202 | config HP_ACCEL | 202 | config HP_ACCEL |
203 | tristate "HP laptop accelerometer" | 203 | tristate "HP laptop accelerometer" |
204 | depends on INPUT && ACPI | 204 | depends on INPUT && ACPI |
205 | depends on SERIO_I8042 | ||
205 | select SENSORS_LIS3LV02D | 206 | select SENSORS_LIS3LV02D |
206 | select NEW_LEDS | 207 | select NEW_LEDS |
207 | select LEDS_CLASS | 208 | select LEDS_CLASS |
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 13e14ec1d3d7..6bec745b6b92 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <linux/leds.h> | 37 | #include <linux/leds.h> |
38 | #include <linux/atomic.h> | 38 | #include <linux/atomic.h> |
39 | #include <linux/acpi.h> | 39 | #include <linux/acpi.h> |
40 | #include <linux/i8042.h> | ||
41 | #include <linux/serio.h> | ||
40 | #include "../../misc/lis3lv02d/lis3lv02d.h" | 42 | #include "../../misc/lis3lv02d/lis3lv02d.h" |
41 | 43 | ||
42 | #define DRIVER_NAME "hp_accel" | 44 | #define DRIVER_NAME "hp_accel" |
@@ -73,6 +75,13 @@ static inline void delayed_sysfs_set(struct led_classdev *led_cdev, | |||
73 | 75 | ||
74 | /* HP-specific accelerometer driver ------------------------------------ */ | 76 | /* HP-specific accelerometer driver ------------------------------------ */ |
75 | 77 | ||
78 | /* e0 25, e0 26, e0 27, e0 28 are scan codes that the accelerometer with acpi id | ||
79 | * HPQ6000 sends through the keyboard bus */ | ||
80 | #define ACCEL_1 0x25 | ||
81 | #define ACCEL_2 0x26 | ||
82 | #define ACCEL_3 0x27 | ||
83 | #define ACCEL_4 0x28 | ||
84 | |||
76 | /* For automatic insertion of the module */ | 85 | /* For automatic insertion of the module */ |
77 | static const struct acpi_device_id lis3lv02d_device_ids[] = { | 86 | static const struct acpi_device_id lis3lv02d_device_ids[] = { |
78 | {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */ | 87 | {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */ |
@@ -294,6 +303,35 @@ static void lis3lv02d_enum_resources(struct acpi_device *device) | |||
294 | printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n"); | 303 | printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n"); |
295 | } | 304 | } |
296 | 305 | ||
306 | static bool hp_accel_i8042_filter(unsigned char data, unsigned char str, | ||
307 | struct serio *port) | ||
308 | { | ||
309 | static bool extended; | ||
310 | |||
311 | if (str & I8042_STR_AUXDATA) | ||
312 | return false; | ||
313 | |||
314 | if (data == 0xe0) { | ||
315 | extended = true; | ||
316 | return true; | ||
317 | } else if (unlikely(extended)) { | ||
318 | extended = false; | ||
319 | |||
320 | switch (data) { | ||
321 | case ACCEL_1: | ||
322 | case ACCEL_2: | ||
323 | case ACCEL_3: | ||
324 | case ACCEL_4: | ||
325 | return true; | ||
326 | default: | ||
327 | serio_interrupt(port, 0xe0, 0); | ||
328 | return false; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | return false; | ||
333 | } | ||
334 | |||
297 | static int lis3lv02d_add(struct acpi_device *device) | 335 | static int lis3lv02d_add(struct acpi_device *device) |
298 | { | 336 | { |
299 | int ret; | 337 | int ret; |
@@ -326,6 +364,11 @@ static int lis3lv02d_add(struct acpi_device *device) | |||
326 | if (ret) | 364 | if (ret) |
327 | return ret; | 365 | return ret; |
328 | 366 | ||
367 | /* filter to remove HPQ6000 accelerometer data | ||
368 | * from keyboard bus stream */ | ||
369 | if (strstr(dev_name(&device->dev), "HPQ6000")) | ||
370 | i8042_install_filter(hp_accel_i8042_filter); | ||
371 | |||
329 | INIT_WORK(&hpled_led.work, delayed_set_status_worker); | 372 | INIT_WORK(&hpled_led.work, delayed_set_status_worker); |
330 | ret = led_classdev_register(NULL, &hpled_led.led_classdev); | 373 | ret = led_classdev_register(NULL, &hpled_led.led_classdev); |
331 | if (ret) { | 374 | if (ret) { |
@@ -343,6 +386,7 @@ static int lis3lv02d_remove(struct acpi_device *device) | |||
343 | if (!device) | 386 | if (!device) |
344 | return -EINVAL; | 387 | return -EINVAL; |
345 | 388 | ||
389 | i8042_remove_filter(hp_accel_i8042_filter); | ||
346 | lis3lv02d_joystick_disable(&lis3_dev); | 390 | lis3lv02d_joystick_disable(&lis3_dev); |
347 | lis3lv02d_poweroff(&lis3_dev); | 391 | lis3lv02d_poweroff(&lis3_dev); |
348 | 392 | ||