diff options
| author | Takashi Iwai <tiwai@suse.de> | 2014-11-27 12:40:51 +0100 | 
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2014-11-27 12:40:51 +0100 | 
| commit | acf403ecc4155153e5e2c1640be90fc166e56ba7 (patch) | |
| tree | e9655b84776cec00a4da077f5dd1e336dfd9c7c0 /drivers/platform/x86/hp_accel.c | |
| parent | 69eba10e606a80665f8573221fec589430d9d1cb (diff) | |
| parent | b61f90eac1ff9d1b30497e611aba4651d4066706 (diff) | |
Merge branch 'topic/usb-resume' into for-next
Merge the proper mixer resume support for quirk codes.
Diffstat (limited to 'drivers/platform/x86/hp_accel.c')
| -rw-r--r-- | drivers/platform/x86/hp_accel.c | 44 | 
1 files changed, 44 insertions, 0 deletions
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 @@  #include <linux/leds.h>  #include <linux/atomic.h>  #include <linux/acpi.h> +#include <linux/i8042.h> +#include <linux/serio.h>  #include "../../misc/lis3lv02d/lis3lv02d.h"  #define DRIVER_NAME     "hp_accel" @@ -73,6 +75,13 @@ static inline void delayed_sysfs_set(struct led_classdev *led_cdev,  /* HP-specific accelerometer driver ------------------------------------ */ +/* e0 25, e0 26, e0 27, e0 28 are scan codes that the accelerometer with acpi id + * HPQ6000 sends through the keyboard bus */ +#define ACCEL_1 0x25 +#define ACCEL_2 0x26 +#define ACCEL_3 0x27 +#define ACCEL_4 0x28 +  /* For automatic insertion of the module */  static const struct acpi_device_id lis3lv02d_device_ids[] = {  	{"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */ @@ -294,6 +303,35 @@ static void lis3lv02d_enum_resources(struct acpi_device *device)  		printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n");  } +static bool hp_accel_i8042_filter(unsigned char data, unsigned char str, +				  struct serio *port) +{ +	static bool extended; + +	if (str & I8042_STR_AUXDATA) +		return false; + +	if (data == 0xe0) { +		extended = true; +		return true; +	} else if (unlikely(extended)) { +		extended = false; + +		switch (data) { +		case ACCEL_1: +		case ACCEL_2: +		case ACCEL_3: +		case ACCEL_4: +			return true; +		default: +			serio_interrupt(port, 0xe0, 0); +			return false; +		} +	} + +	return false; +} +  static int lis3lv02d_add(struct acpi_device *device)  {  	int ret; @@ -326,6 +364,11 @@ static int lis3lv02d_add(struct acpi_device *device)  	if (ret)  		return ret; +	/* filter to remove HPQ6000 accelerometer data +	 * from keyboard bus stream */ +	if (strstr(dev_name(&device->dev), "HPQ6000")) +		i8042_install_filter(hp_accel_i8042_filter); +  	INIT_WORK(&hpled_led.work, delayed_set_status_worker);  	ret = led_classdev_register(NULL, &hpled_led.led_classdev);  	if (ret) { @@ -343,6 +386,7 @@ static int lis3lv02d_remove(struct acpi_device *device)  	if (!device)  		return -EINVAL; +	i8042_remove_filter(hp_accel_i8042_filter);  	lis3lv02d_joystick_disable(&lis3_dev);  	lis3lv02d_poweroff(&lis3_dev);  | 
