Commit 5ae93760cbedda64eab0a7012cc3785c32399641
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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
Showing 2 changed files Side-by-side Diff
drivers/platform/x86/Kconfig
drivers/platform/x86/hp_accel.c
... | ... | @@ -37,6 +37,8 @@ |
37 | 37 | #include <linux/leds.h> |
38 | 38 | #include <linux/atomic.h> |
39 | 39 | #include <linux/acpi.h> |
40 | +#include <linux/i8042.h> | |
41 | +#include <linux/serio.h> | |
40 | 42 | #include "../../misc/lis3lv02d/lis3lv02d.h" |
41 | 43 | |
42 | 44 | #define DRIVER_NAME "hp_accel" |
... | ... | @@ -73,6 +75,13 @@ |
73 | 75 | |
74 | 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 | 85 | /* For automatic insertion of the module */ |
77 | 86 | static const struct acpi_device_id lis3lv02d_device_ids[] = { |
78 | 87 | {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */ |
... | ... | @@ -294,6 +303,35 @@ |
294 | 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 | 335 | static int lis3lv02d_add(struct acpi_device *device) |
298 | 336 | { |
299 | 337 | int ret; |
... | ... | @@ -326,6 +364,11 @@ |
326 | 364 | if (ret) |
327 | 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 | 372 | INIT_WORK(&hpled_led.work, delayed_set_status_worker); |
330 | 373 | ret = led_classdev_register(NULL, &hpled_led.led_classdev); |
331 | 374 | if (ret) { |
... | ... | @@ -343,6 +386,7 @@ |
343 | 386 | if (!device) |
344 | 387 | return -EINVAL; |
345 | 388 | |
389 | + i8042_remove_filter(hp_accel_i8042_filter); | |
346 | 390 | lis3lv02d_joystick_disable(&lis3_dev); |
347 | 391 | lis3lv02d_poweroff(&lis3_dev); |
348 | 392 |