Commit c9194b99 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid

Pull HID fixes from Jiri Kosina:

 - regression fix (sleeping while atomic) for cp2112, from Johan Hovold

 - regression fix for proximity handling under certain circumstances in
   Wacom driver, from Jason Gerecke

 - functional fix for Logitech Rumblepad 2, from Ardinartsev Nikita

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
  HID: cp2112: fix gpio-callback error handling
  HID: cp2112: fix sleep-while-atomic
  HID: hid-lg: Fix immediate disconnection of Logitech Rumblepad 2
  HID: usbhid: Quirk a AMI virtual mouse and keyboard with ALWAYS_POLL
  HID: wacom: Fix poor prox handling in 'wacom_pl_irq'
parents 415f9b71 8e9faa15
...@@ -168,7 +168,7 @@ struct cp2112_device { ...@@ -168,7 +168,7 @@ struct cp2112_device {
atomic_t xfer_avail; atomic_t xfer_avail;
struct gpio_chip gc; struct gpio_chip gc;
u8 *in_out_buffer; u8 *in_out_buffer;
spinlock_t lock; struct mutex lock;
struct gpio_desc *desc[8]; struct gpio_desc *desc[8];
bool gpio_poll; bool gpio_poll;
...@@ -186,10 +186,9 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset) ...@@ -186,10 +186,9 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
struct cp2112_device *dev = gpiochip_get_data(chip); struct cp2112_device *dev = gpiochip_get_data(chip);
struct hid_device *hdev = dev->hdev; struct hid_device *hdev = dev->hdev;
u8 *buf = dev->in_out_buffer; u8 *buf = dev->in_out_buffer;
unsigned long flags;
int ret; int ret;
spin_lock_irqsave(&dev->lock, flags); mutex_lock(&dev->lock);
ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf, ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT, CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT,
...@@ -213,8 +212,8 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset) ...@@ -213,8 +212,8 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
ret = 0; ret = 0;
exit: exit:
spin_unlock_irqrestore(&dev->lock, flags); mutex_unlock(&dev->lock);
return ret <= 0 ? ret : -EIO; return ret < 0 ? ret : -EIO;
} }
static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value) static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
...@@ -222,10 +221,9 @@ static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value) ...@@ -222,10 +221,9 @@ static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
struct cp2112_device *dev = gpiochip_get_data(chip); struct cp2112_device *dev = gpiochip_get_data(chip);
struct hid_device *hdev = dev->hdev; struct hid_device *hdev = dev->hdev;
u8 *buf = dev->in_out_buffer; u8 *buf = dev->in_out_buffer;
unsigned long flags;
int ret; int ret;
spin_lock_irqsave(&dev->lock, flags); mutex_lock(&dev->lock);
buf[0] = CP2112_GPIO_SET; buf[0] = CP2112_GPIO_SET;
buf[1] = value ? 0xff : 0; buf[1] = value ? 0xff : 0;
...@@ -237,7 +235,7 @@ static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value) ...@@ -237,7 +235,7 @@ static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
if (ret < 0) if (ret < 0)
hid_err(hdev, "error setting GPIO values: %d\n", ret); hid_err(hdev, "error setting GPIO values: %d\n", ret);
spin_unlock_irqrestore(&dev->lock, flags); mutex_unlock(&dev->lock);
} }
static int cp2112_gpio_get_all(struct gpio_chip *chip) static int cp2112_gpio_get_all(struct gpio_chip *chip)
...@@ -245,10 +243,9 @@ static int cp2112_gpio_get_all(struct gpio_chip *chip) ...@@ -245,10 +243,9 @@ static int cp2112_gpio_get_all(struct gpio_chip *chip)
struct cp2112_device *dev = gpiochip_get_data(chip); struct cp2112_device *dev = gpiochip_get_data(chip);
struct hid_device *hdev = dev->hdev; struct hid_device *hdev = dev->hdev;
u8 *buf = dev->in_out_buffer; u8 *buf = dev->in_out_buffer;
unsigned long flags;
int ret; int ret;
spin_lock_irqsave(&dev->lock, flags); mutex_lock(&dev->lock);
ret = hid_hw_raw_request(hdev, CP2112_GPIO_GET, buf, ret = hid_hw_raw_request(hdev, CP2112_GPIO_GET, buf,
CP2112_GPIO_GET_LENGTH, HID_FEATURE_REPORT, CP2112_GPIO_GET_LENGTH, HID_FEATURE_REPORT,
...@@ -262,7 +259,7 @@ static int cp2112_gpio_get_all(struct gpio_chip *chip) ...@@ -262,7 +259,7 @@ static int cp2112_gpio_get_all(struct gpio_chip *chip)
ret = buf[1]; ret = buf[1];
exit: exit:
spin_unlock_irqrestore(&dev->lock, flags); mutex_unlock(&dev->lock);
return ret; return ret;
} }
...@@ -284,10 +281,9 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip, ...@@ -284,10 +281,9 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
struct cp2112_device *dev = gpiochip_get_data(chip); struct cp2112_device *dev = gpiochip_get_data(chip);
struct hid_device *hdev = dev->hdev; struct hid_device *hdev = dev->hdev;
u8 *buf = dev->in_out_buffer; u8 *buf = dev->in_out_buffer;
unsigned long flags;
int ret; int ret;
spin_lock_irqsave(&dev->lock, flags); mutex_lock(&dev->lock);
ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf, ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT, CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT,
...@@ -308,7 +304,7 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip, ...@@ -308,7 +304,7 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
goto fail; goto fail;
} }
spin_unlock_irqrestore(&dev->lock, flags); mutex_unlock(&dev->lock);
/* /*
* Set gpio value when output direction is already set, * Set gpio value when output direction is already set,
...@@ -319,7 +315,7 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip, ...@@ -319,7 +315,7 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
return 0; return 0;
fail: fail:
spin_unlock_irqrestore(&dev->lock, flags); mutex_unlock(&dev->lock);
return ret < 0 ? ret : -EIO; return ret < 0 ? ret : -EIO;
} }
...@@ -1235,7 +1231,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -1235,7 +1231,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (!dev->in_out_buffer) if (!dev->in_out_buffer)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&dev->lock); mutex_init(&dev->lock);
ret = hid_parse(hdev); ret = hid_parse(hdev);
if (ret) { if (ret) {
......
...@@ -76,6 +76,9 @@ ...@@ -76,6 +76,9 @@
#define USB_VENDOR_ID_ALPS_JP 0x044E #define USB_VENDOR_ID_ALPS_JP 0x044E
#define HID_DEVICE_ID_ALPS_U1_DUAL 0x120B #define HID_DEVICE_ID_ALPS_U1_DUAL 0x120B
#define USB_VENDOR_ID_AMI 0x046b
#define USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE 0xff10
#define USB_VENDOR_ID_ANTON 0x1130 #define USB_VENDOR_ID_ANTON 0x1130
#define USB_DEVICE_ID_ANTON_TOUCH_PAD 0x3101 #define USB_DEVICE_ID_ANTON_TOUCH_PAD 0x3101
......
...@@ -872,7 +872,7 @@ static const struct hid_device_id lg_devices[] = { ...@@ -872,7 +872,7 @@ static const struct hid_device_id lg_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG), { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG),
.driver_data = LG_NOGET | LG_FF4 }, .driver_data = LG_NOGET | LG_FF4 },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
.driver_data = LG_FF2 }, .driver_data = LG_NOGET | LG_FF2 },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940), { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940),
.driver_data = LG_FF3 }, .driver_data = LG_FF3 },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR), { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR),
......
...@@ -57,6 +57,7 @@ static const struct hid_blacklist { ...@@ -57,6 +57,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET }, { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
......
...@@ -166,19 +166,21 @@ static int wacom_pl_irq(struct wacom_wac *wacom) ...@@ -166,19 +166,21 @@ static int wacom_pl_irq(struct wacom_wac *wacom)
wacom->id[0] = STYLUS_DEVICE_ID; wacom->id[0] = STYLUS_DEVICE_ID;
} }
pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); if (prox) {
if (features->pressure_max > 255) pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
pressure = (pressure << 1) | ((data[4] >> 6) & 1); if (features->pressure_max > 255)
pressure += (features->pressure_max + 1) / 2; pressure = (pressure << 1) | ((data[4] >> 6) & 1);
pressure += (features->pressure_max + 1) / 2;
input_report_abs(input, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
input_report_abs(input, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); input_report_abs(input, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
input_report_abs(input, ABS_PRESSURE, pressure); input_report_abs(input, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
input_report_abs(input, ABS_PRESSURE, pressure);
input_report_key(input, BTN_TOUCH, data[4] & 0x08);
input_report_key(input, BTN_STYLUS, data[4] & 0x10); input_report_key(input, BTN_TOUCH, data[4] & 0x08);
/* Only allow the stylus2 button to be reported for the pen tool. */ input_report_key(input, BTN_STYLUS, data[4] & 0x10);
input_report_key(input, BTN_STYLUS2, (wacom->tool[0] == BTN_TOOL_PEN) && (data[4] & 0x20)); /* Only allow the stylus2 button to be reported for the pen tool. */
input_report_key(input, BTN_STYLUS2, (wacom->tool[0] == BTN_TOOL_PEN) && (data[4] & 0x20));
}
if (!prox) if (!prox)
wacom->id[0] = 0; wacom->id[0] = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment