Skip to content

Commit 77ede3a

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID subsystem fixes from Jiri Kosina: - buffer management size fix for i2c-hid driver, from Adrian Salido - tool ID regression fixes for Wacom driver from Jason Gerecke - a few small assorted fixes and a few device ID additions * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: Revert "HID: multitouch: Support ALPS PTP stick with pid 0x120A" HID: hidraw: fix power sequence when closing device HID: wacom: Always increment hdev refcount within wacom_get_hdev_data HID: wacom: generic: Clear ABS_MISC when tool leaves proximity HID: wacom: generic: Send MSC_SERIAL and ABS_MISC when leaving prox HID: i2c-hid: allocate hid buffers for real worst case HID: rmi: Make sure the HID device is opened on resume HID: multitouch: Support ALPS PTP stick with pid 0x120A HID: multitouch: support buttons and trackpoint on Lenovo X1 Tab Gen2 HID: wacom: Correct coordinate system of touchring and pen twist HID: wacom: Properly report negative values from Intuos Pro 2 Bluetooth HID: multitouch: Fix system-control buttons not working HID: add multi-input quirk for IDC6680 touchscreen HID: wacom: leds: Don't try to control the EKR's read-only LEDs HID: wacom: bits shifted too much for 9th and 10th buttons
2 parents 9a431ef + 66dcdaf commit 77ede3a

File tree

8 files changed

+118
-27
lines changed

8 files changed

+118
-27
lines changed

drivers/hid/hid-ids.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@
533533
#define USB_VENDOR_ID_IDEACOM 0x1cb6
534534
#define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650
535535
#define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651
536+
#define USB_DEVICE_ID_IDEACOM_IDC6680 0x6680
536537

537538
#define USB_VENDOR_ID_ILITEK 0x222a
538539
#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001
@@ -660,6 +661,7 @@
660661
#define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048
661662
#define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067
662663
#define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085
664+
#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3
663665

664666
#define USB_VENDOR_ID_LG 0x1fd2
665667
#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064

drivers/hid/hid-multitouch.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
930930
field->application != HID_DG_PEN &&
931931
field->application != HID_DG_TOUCHPAD &&
932932
field->application != HID_GD_KEYBOARD &&
933+
field->application != HID_GD_SYSTEM_CONTROL &&
933934
field->application != HID_CP_CONSUMER_CONTROL &&
934935
field->application != HID_GD_WIRELESS_RADIO_CTLS &&
935936
!(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS &&
@@ -1419,6 +1420,12 @@ static const struct hid_device_id mt_devices[] = {
14191420
USB_VENDOR_ID_ALPS_JP,
14201421
HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP) },
14211422

1423+
/* Lenovo X1 TAB Gen 2 */
1424+
{ .driver_data = MT_CLS_WIN_8_DUAL,
1425+
HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
1426+
USB_VENDOR_ID_LENOVO,
1427+
USB_DEVICE_ID_LENOVO_X1_TAB) },
1428+
14221429
/* Anton devices */
14231430
{ .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
14241431
MT_USB_DEVICE(USB_VENDOR_ID_ANTON,

drivers/hid/hid-rmi.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,17 +436,24 @@ static int rmi_post_resume(struct hid_device *hdev)
436436
if (!(data->device_flags & RMI_DEVICE))
437437
return 0;
438438

439-
ret = rmi_reset_attn_mode(hdev);
439+
/* Make sure the HID device is ready to receive events */
440+
ret = hid_hw_open(hdev);
440441
if (ret)
441442
return ret;
442443

444+
ret = rmi_reset_attn_mode(hdev);
445+
if (ret)
446+
goto out;
447+
443448
ret = rmi_driver_resume(rmi_dev, false);
444449
if (ret) {
445450
hid_warn(hdev, "Failed to resume device: %d\n", ret);
446-
return ret;
451+
goto out;
447452
}
448453

449-
return 0;
454+
out:
455+
hid_hw_close(hdev);
456+
return ret;
450457
}
451458
#endif /* CONFIG_PM */
452459

drivers/hid/hidraw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,8 @@ static void drop_ref(struct hidraw *hidraw, int exists_bit)
337337
kfree(hidraw);
338338
} else {
339339
/* close device for last reader */
340-
hid_hw_power(hidraw->hid, PM_HINT_NORMAL);
341340
hid_hw_close(hidraw->hid);
341+
hid_hw_power(hidraw->hid, PM_HINT_NORMAL);
342342
}
343343
}
344344
}

drivers/hid/i2c-hid/i2c-hid.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,8 @@ static int i2c_hid_alloc_buffers(struct i2c_hid *ihid, size_t report_size)
543543
{
544544
/* the worst case is computed from the set_report command with a
545545
* reportID > 15 and the maximum report length */
546-
int args_len = sizeof(__u8) + /* optional ReportID byte */
546+
int args_len = sizeof(__u8) + /* ReportID */
547+
sizeof(__u8) + /* optional ReportID byte */
547548
sizeof(__u16) + /* data register */
548549
sizeof(__u16) + /* size of the report */
549550
report_size; /* report */

drivers/hid/usbhid/hid-quirks.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ static const struct hid_blacklist {
9999
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL },
100100
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL },
101101
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
102+
{ USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680, HID_QUIRK_MULTI_INPUT },
102103
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007, HID_QUIRK_ALWAYS_POLL },
103104
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL },
104105
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, HID_QUIRK_NOGET },

drivers/hid/wacom_sys.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,8 +668,10 @@ static struct wacom_hdev_data *wacom_get_hdev_data(struct hid_device *hdev)
668668

669669
/* Try to find an already-probed interface from the same device */
670670
list_for_each_entry(data, &wacom_udev_list, list) {
671-
if (compare_device_paths(hdev, data->dev, '/'))
671+
if (compare_device_paths(hdev, data->dev, '/')) {
672+
kref_get(&data->kref);
672673
return data;
674+
}
673675
}
674676

675677
/* Fallback to finding devices that appear to be "siblings" */
@@ -766,6 +768,9 @@ static int wacom_led_control(struct wacom *wacom)
766768
if (!wacom->led.groups)
767769
return -ENOTSUPP;
768770

771+
if (wacom->wacom_wac.features.type == REMOTE)
772+
return -ENOTSUPP;
773+
769774
if (wacom->wacom_wac.pid) { /* wireless connected */
770775
report_id = WAC_CMD_WL_LED_CONTROL;
771776
buf_size = 13;

drivers/hid/wacom_wac.c

Lines changed: 89 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -567,8 +567,8 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
567567
keys = data[9] & 0x07;
568568
}
569569
} else {
570-
buttons = ((data[6] & 0x10) << 10) |
571-
((data[5] & 0x10) << 9) |
570+
buttons = ((data[6] & 0x10) << 5) |
571+
((data[5] & 0x10) << 4) |
572572
((data[6] & 0x0F) << 4) |
573573
(data[5] & 0x0F);
574574
}
@@ -1227,11 +1227,17 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
12271227
continue;
12281228

12291229
if (range) {
1230+
/* Fix rotation alignment: userspace expects zero at left */
1231+
int16_t rotation = (int16_t)get_unaligned_le16(&frame[9]);
1232+
rotation += 1800/4;
1233+
if (rotation > 899)
1234+
rotation -= 1800;
1235+
12301236
input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1]));
12311237
input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3]));
1232-
input_report_abs(pen_input, ABS_TILT_X, frame[7]);
1233-
input_report_abs(pen_input, ABS_TILT_Y, frame[8]);
1234-
input_report_abs(pen_input, ABS_Z, get_unaligned_le16(&frame[9]));
1238+
input_report_abs(pen_input, ABS_TILT_X, (char)frame[7]);
1239+
input_report_abs(pen_input, ABS_TILT_Y, (char)frame[8]);
1240+
input_report_abs(pen_input, ABS_Z, rotation);
12351241
input_report_abs(pen_input, ABS_WHEEL, get_unaligned_le16(&frame[11]));
12361242
}
12371243
input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5]));
@@ -1319,12 +1325,19 @@ static void wacom_intuos_pro2_bt_pad(struct wacom_wac *wacom)
13191325
unsigned char *data = wacom->data;
13201326

13211327
int buttons = (data[282] << 1) | ((data[281] >> 6) & 0x01);
1322-
int ring = data[285];
1323-
int prox = buttons | (ring & 0x80);
1328+
int ring = data[285] & 0x7F;
1329+
bool ringstatus = data[285] & 0x80;
1330+
bool prox = buttons || ringstatus;
1331+
1332+
/* Fix touchring data: userspace expects 0 at left and increasing clockwise */
1333+
ring = 71 - ring;
1334+
ring += 3*72/16;
1335+
if (ring > 71)
1336+
ring -= 72;
13241337

13251338
wacom_report_numbered_buttons(pad_input, 9, buttons);
13261339

1327-
input_report_abs(pad_input, ABS_WHEEL, (ring & 0x80) ? (ring & 0x7f) : 0);
1340+
input_report_abs(pad_input, ABS_WHEEL, ringstatus ? ring : 0);
13281341

13291342
input_report_key(pad_input, wacom->tool[1], prox ? 1 : 0);
13301343
input_report_abs(pad_input, ABS_MISC, prox ? PAD_DEVICE_ID : 0);
@@ -1616,6 +1629,20 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
16161629
return 0;
16171630
}
16181631

1632+
static int wacom_offset_rotation(struct input_dev *input, struct hid_usage *usage,
1633+
int value, int num, int denom)
1634+
{
1635+
struct input_absinfo *abs = &input->absinfo[usage->code];
1636+
int range = (abs->maximum - abs->minimum + 1);
1637+
1638+
value += num*range/denom;
1639+
if (value > abs->maximum)
1640+
value -= range;
1641+
else if (value < abs->minimum)
1642+
value += range;
1643+
return value;
1644+
}
1645+
16191646
int wacom_equivalent_usage(int usage)
16201647
{
16211648
if ((usage & HID_USAGE_PAGE) == WACOM_HID_UP_WACOMDIGITIZER) {
@@ -1898,6 +1925,7 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
18981925
unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
18991926
int i;
19001927
bool is_touch_on = value;
1928+
bool do_report = false;
19011929

19021930
/*
19031931
* Avoid reporting this event and setting inrange_state if this usage
@@ -1912,6 +1940,29 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
19121940
}
19131941

19141942
switch (equivalent_usage) {
1943+
case WACOM_HID_WD_TOUCHRING:
1944+
/*
1945+
* Userspace expects touchrings to increase in value with
1946+
* clockwise gestures and have their zero point at the
1947+
* tablet's left. HID events "should" be clockwise-
1948+
* increasing and zero at top, though the MobileStudio
1949+
* Pro and 2nd-gen Intuos Pro don't do this...
1950+
*/
1951+
if (hdev->vendor == 0x56a &&
1952+
(hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */
1953+
hdev->product == 0x357 || hdev->product == 0x358)) { /* Intuos Pro 2 */
1954+
value = (field->logical_maximum - value);
1955+
1956+
if (hdev->product == 0x357 || hdev->product == 0x358)
1957+
value = wacom_offset_rotation(input, usage, value, 3, 16);
1958+
else if (hdev->product == 0x34d || hdev->product == 0x34e)
1959+
value = wacom_offset_rotation(input, usage, value, 1, 2);
1960+
}
1961+
else {
1962+
value = wacom_offset_rotation(input, usage, value, 1, 4);
1963+
}
1964+
do_report = true;
1965+
break;
19151966
case WACOM_HID_WD_TOUCHRINGSTATUS:
19161967
if (!value)
19171968
input_event(input, usage->type, usage->code, 0);
@@ -1945,10 +1996,14 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
19451996
value, i);
19461997
/* fall through*/
19471998
default:
1999+
do_report = true;
2000+
break;
2001+
}
2002+
2003+
if (do_report) {
19482004
input_event(input, usage->type, usage->code, value);
19492005
if (value)
19502006
wacom_wac->hid_data.pad_input_event_flag = true;
1951-
break;
19522007
}
19532008
}
19542009

@@ -2086,22 +2141,34 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
20862141
wacom_wac->hid_data.tipswitch |= value;
20872142
return;
20882143
case HID_DG_TOOLSERIALNUMBER:
2089-
wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL);
2090-
wacom_wac->serial[0] |= (__u32)value;
2144+
if (value) {
2145+
wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL);
2146+
wacom_wac->serial[0] |= (__u32)value;
2147+
}
20912148
return;
2149+
case HID_DG_TWIST:
2150+
/*
2151+
* Userspace expects pen twist to have its zero point when
2152+
* the buttons/finger is on the tablet's left. HID values
2153+
* are zero when buttons are toward the top.
2154+
*/
2155+
value = wacom_offset_rotation(input, usage, value, 1, 4);
2156+
break;
20922157
case WACOM_HID_WD_SENSE:
20932158
wacom_wac->hid_data.sense_state = value;
20942159
return;
20952160
case WACOM_HID_WD_SERIALHI:
2096-
wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF);
2097-
wacom_wac->serial[0] |= ((__u64)value) << 32;
2098-
/*
2099-
* Non-USI EMR devices may contain additional tool type
2100-
* information here. See WACOM_HID_WD_TOOLTYPE case for
2101-
* more details.
2102-
*/
2103-
if (value >> 20 == 1) {
2104-
wacom_wac->id[0] |= value & 0xFFFFF;
2161+
if (value) {
2162+
wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF);
2163+
wacom_wac->serial[0] |= ((__u64)value) << 32;
2164+
/*
2165+
* Non-USI EMR devices may contain additional tool type
2166+
* information here. See WACOM_HID_WD_TOOLTYPE case for
2167+
* more details.
2168+
*/
2169+
if (value >> 20 == 1) {
2170+
wacom_wac->id[0] |= value & 0xFFFFF;
2171+
}
21052172
}
21062173
return;
21072174
case WACOM_HID_WD_TOOLTYPE:
@@ -2205,7 +2272,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
22052272
input_report_key(input, wacom_wac->tool[0], prox);
22062273
if (wacom_wac->serial[0]) {
22072274
input_event(input, EV_MSC, MSC_SERIAL, wacom_wac->serial[0]);
2208-
input_report_abs(input, ABS_MISC, id);
2275+
input_report_abs(input, ABS_MISC, prox ? id : 0);
22092276
}
22102277

22112278
wacom_wac->hid_data.tipswitch = false;
@@ -2216,6 +2283,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
22162283
if (!prox) {
22172284
wacom_wac->tool[0] = 0;
22182285
wacom_wac->id[0] = 0;
2286+
wacom_wac->serial[0] = 0;
22192287
}
22202288
}
22212289

0 commit comments

Comments
 (0)