Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Pull HID update from Jiri Kosina:

- Wacom driver fixes/updates (device name generation improvements,
touch ring status support) from Jason Gerecke

- T100 touchpad support from Hans de Goede

- support for batteries driven by HID input reports, from Dmitry
Torokhov

- Arnd pointed out that driver_lock semaphore is superfluous, as driver
core already provides all the necessary concurency protection.
Removal patch from Binoy Jayan

- logical minimum numbering improvements in sensor-hub driver, from
Srinivas Pandruvada

- support for Microsoft Win8 Wireless Radio Controls extensions from
João Paulo Rechi Vita

- assorted small fixes and device ID additions

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (28 commits)
HID: prodikeys: constify snd_rawmidi_ops structures
HID: sensor: constify platform_device_id
HID: input: throttle battery uevents
HID: usbmouse: constify usb_device_id and fix space before '[' error
HID: usbkbd: constify usb_device_id and fix space before '[' error.
HID: hid-sensor-hub: Force logical minimum to 1 for power and report state
HID: wacom: Do not completely map WACOM_HID_WD_TOUCHRINGSTATUS usage
HID: asus: Add T100CHI bluetooth keyboard dock touchpad support
HID: ntrig: constify attribute_group structures.
HID: logitech-hidpp: constify attribute_group structures.
HID: sensor: constify attribute_group structures.
HID: multitouch: constify attribute_group structures.
HID: multitouch: use proper symbolic constant for 0xff310076 application
HID: multitouch: Support Asus T304UA media keys
HID: multitouch: Support HID_GD_WIRELESS_RADIO_CTLS
HID: input: optionally use device id in battery name
HID: input: map digitizer battery usage
HID: Remove the semaphore driver_lock
HID: wacom: add USB_HID dependency
HID: add ALWAYS_POLL quirk for Logitech 0xc077
...

+438 -266
+1 -1
drivers/hid/Kconfig
··· 924 924 925 925 config HID_WACOM 926 926 tristate "Wacom Intuos/Graphire tablet support (USB)" 927 - depends on HID 927 + depends on USB_HID 928 928 select POWER_SUPPLY 929 929 select NEW_LEDS 930 930 select LEDS_CLASS
+173 -45
drivers/hid/hid-asus.c
··· 29 29 #include <linux/hid.h> 30 30 #include <linux/module.h> 31 31 #include <linux/input/mt.h> 32 + #include <linux/usb.h> /* For to_usb_interface for T100 touchpad intf check */ 32 33 33 34 #include "hid-ids.h" 34 35 ··· 39 38 MODULE_AUTHOR("Frederik Wenigwieser <frederik.wenigwieser@gmail.com>"); 40 39 MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); 41 40 41 + #define T100_TPAD_INTF 2 42 + 43 + #define T100CHI_MOUSE_REPORT_ID 0x06 42 44 #define FEATURE_REPORT_ID 0x0d 43 45 #define INPUT_REPORT_ID 0x5d 44 46 #define FEATURE_KBD_REPORT_ID 0x5a 45 - 46 - #define INPUT_REPORT_SIZE 28 47 47 #define FEATURE_KBD_REPORT_SIZE 16 48 48 49 49 #define SUPPORT_KBD_BACKLIGHT BIT(0) 50 50 51 - #define MAX_CONTACTS 5 52 - 53 - #define MAX_X 2794 54 - #define MAX_Y 1758 55 51 #define MAX_TOUCH_MAJOR 8 56 52 #define MAX_PRESSURE 128 57 - 58 - #define CONTACT_DATA_SIZE 5 59 53 60 54 #define BTN_LEFT_MASK 0x01 61 55 #define CONTACT_TOOL_TYPE_MASK 0x80 ··· 66 70 #define QUIRK_NO_CONSUMER_USAGES BIT(4) 67 71 #define QUIRK_USE_KBD_BACKLIGHT BIT(5) 68 72 #define QUIRK_T100_KEYBOARD BIT(6) 73 + #define QUIRK_T100CHI BIT(7) 69 74 70 75 #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ 71 76 QUIRK_NO_INIT_REPORTS | \ ··· 85 88 bool removed; 86 89 }; 87 90 91 + struct asus_touchpad_info { 92 + int max_x; 93 + int max_y; 94 + int res_x; 95 + int res_y; 96 + int contact_size; 97 + int max_contacts; 98 + }; 99 + 88 100 struct asus_drvdata { 89 101 unsigned long quirks; 90 102 struct input_dev *input; 91 103 struct asus_kbd_leds *kbd_backlight; 104 + const struct asus_touchpad_info *tp; 92 105 bool enable_backlight; 93 106 }; 94 107 95 - static void asus_report_contact_down(struct input_dev *input, 108 + static const struct asus_touchpad_info asus_i2c_tp = { 109 + .max_x = 2794, 110 + .max_y = 1758, 111 + .contact_size = 5, 112 + .max_contacts = 5, 113 + }; 114 + 115 + static const struct asus_touchpad_info asus_t100ta_tp = { 116 + .max_x = 2240, 117 + .max_y = 1120, 118 + .res_x = 30, /* units/mm */ 119 + .res_y = 27, /* units/mm */ 120 + .contact_size = 5, 121 + .max_contacts = 5, 122 + }; 123 + 124 + static const struct asus_touchpad_info asus_t100chi_tp = { 125 + .max_x = 2640, 126 + .max_y = 1320, 127 + .res_x = 31, /* units/mm */ 128 + .res_y = 29, /* units/mm */ 129 + .contact_size = 3, 130 + .max_contacts = 4, 131 + }; 132 + 133 + static void asus_report_contact_down(struct asus_drvdata *drvdat, 96 134 int toolType, u8 *data) 97 135 { 98 - int touch_major, pressure; 99 - int x = (data[0] & CONTACT_X_MSB_MASK) << 4 | data[1]; 100 - int y = MAX_Y - ((data[0] & CONTACT_Y_MSB_MASK) << 8 | data[2]); 136 + struct input_dev *input = drvdat->input; 137 + int touch_major, pressure, x, y; 138 + 139 + x = (data[0] & CONTACT_X_MSB_MASK) << 4 | data[1]; 140 + y = drvdat->tp->max_y - ((data[0] & CONTACT_Y_MSB_MASK) << 8 | data[2]); 141 + 142 + input_report_abs(input, ABS_MT_POSITION_X, x); 143 + input_report_abs(input, ABS_MT_POSITION_Y, y); 144 + 145 + if (drvdat->tp->contact_size < 5) 146 + return; 101 147 102 148 if (toolType == MT_TOOL_PALM) { 103 149 touch_major = MAX_TOUCH_MAJOR; ··· 150 110 pressure = data[4] & CONTACT_PRESSURE_MASK; 151 111 } 152 112 153 - input_report_abs(input, ABS_MT_POSITION_X, x); 154 - input_report_abs(input, ABS_MT_POSITION_Y, y); 155 113 input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major); 156 114 input_report_abs(input, ABS_MT_PRESSURE, pressure); 157 115 } 158 116 159 117 /* Required for Synaptics Palm Detection */ 160 - static void asus_report_tool_width(struct input_dev *input) 118 + static void asus_report_tool_width(struct asus_drvdata *drvdat) 161 119 { 162 - struct input_mt *mt = input->mt; 120 + struct input_mt *mt = drvdat->input->mt; 163 121 struct input_mt_slot *oldest; 164 122 int oldid, count, i; 123 + 124 + if (drvdat->tp->contact_size < 5) 125 + return; 165 126 166 127 oldest = NULL; 167 128 oldid = mt->trkid; ··· 182 141 } 183 142 184 143 if (oldest) { 185 - input_report_abs(input, ABS_TOOL_WIDTH, 144 + input_report_abs(drvdat->input, ABS_TOOL_WIDTH, 186 145 input_mt_get_value(oldest, ABS_MT_TOUCH_MAJOR)); 187 146 } 188 147 } 189 148 190 - static void asus_report_input(struct input_dev *input, u8 *data) 149 + static int asus_report_input(struct asus_drvdata *drvdat, u8 *data, int size) 191 150 { 192 - int i; 151 + int i, toolType = MT_TOOL_FINGER; 193 152 u8 *contactData = data + 2; 194 153 195 - for (i = 0; i < MAX_CONTACTS; i++) { 154 + if (size != 3 + drvdat->tp->contact_size * drvdat->tp->max_contacts) 155 + return 0; 156 + 157 + for (i = 0; i < drvdat->tp->max_contacts; i++) { 196 158 bool down = !!(data[1] & BIT(i+3)); 197 - int toolType = contactData[3] & CONTACT_TOOL_TYPE_MASK ? 159 + 160 + if (drvdat->tp->contact_size >= 5) 161 + toolType = contactData[3] & CONTACT_TOOL_TYPE_MASK ? 198 162 MT_TOOL_PALM : MT_TOOL_FINGER; 199 163 200 - input_mt_slot(input, i); 201 - input_mt_report_slot_state(input, toolType, down); 164 + input_mt_slot(drvdat->input, i); 165 + input_mt_report_slot_state(drvdat->input, toolType, down); 202 166 203 167 if (down) { 204 - asus_report_contact_down(input, toolType, contactData); 205 - contactData += CONTACT_DATA_SIZE; 168 + asus_report_contact_down(drvdat, toolType, contactData); 169 + contactData += drvdat->tp->contact_size; 206 170 } 207 171 } 208 172 209 - input_report_key(input, BTN_LEFT, data[1] & BTN_LEFT_MASK); 210 - asus_report_tool_width(input); 173 + input_report_key(drvdat->input, BTN_LEFT, data[1] & BTN_LEFT_MASK); 174 + asus_report_tool_width(drvdat); 211 175 212 - input_mt_sync_frame(input); 213 - input_sync(input); 176 + input_mt_sync_frame(drvdat->input); 177 + input_sync(drvdat->input); 178 + 179 + return 1; 214 180 } 215 181 216 182 static int asus_raw_event(struct hid_device *hdev, ··· 225 177 { 226 178 struct asus_drvdata *drvdata = hid_get_drvdata(hdev); 227 179 228 - if (drvdata->quirks & QUIRK_IS_MULTITOUCH && 229 - data[0] == INPUT_REPORT_ID && 230 - size == INPUT_REPORT_SIZE) { 231 - asus_report_input(drvdata->input, data); 232 - return 1; 233 - } 180 + if (drvdata->tp && data[0] == INPUT_REPORT_ID) 181 + return asus_report_input(drvdata, data, size); 234 182 235 183 return 0; 236 184 } ··· 378 334 struct input_dev *input = hi->input; 379 335 struct asus_drvdata *drvdata = hid_get_drvdata(hdev); 380 336 381 - if (drvdata->quirks & QUIRK_IS_MULTITOUCH) { 337 + /* T100CHI uses MULTI_INPUT, bind the touchpad to the mouse hid_input */ 338 + if (drvdata->quirks & QUIRK_T100CHI && 339 + hi->report->id != T100CHI_MOUSE_REPORT_ID) 340 + return 0; 341 + 342 + if (drvdata->tp) { 382 343 int ret; 383 344 384 - input_set_abs_params(input, ABS_MT_POSITION_X, 0, MAX_X, 0, 0); 385 - input_set_abs_params(input, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0); 386 - input_set_abs_params(input, ABS_TOOL_WIDTH, 0, MAX_TOUCH_MAJOR, 0, 0); 387 - input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, MAX_TOUCH_MAJOR, 0, 0); 388 - input_set_abs_params(input, ABS_MT_PRESSURE, 0, MAX_PRESSURE, 0, 0); 345 + input_set_abs_params(input, ABS_MT_POSITION_X, 0, 346 + drvdata->tp->max_x, 0, 0); 347 + input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 348 + drvdata->tp->max_y, 0, 0); 349 + input_abs_set_res(input, ABS_MT_POSITION_X, drvdata->tp->res_x); 350 + input_abs_set_res(input, ABS_MT_POSITION_Y, drvdata->tp->res_y); 351 + 352 + if (drvdata->tp->contact_size >= 5) { 353 + input_set_abs_params(input, ABS_TOOL_WIDTH, 0, 354 + MAX_TOUCH_MAJOR, 0, 0); 355 + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 356 + MAX_TOUCH_MAJOR, 0, 0); 357 + input_set_abs_params(input, ABS_MT_PRESSURE, 0, 358 + MAX_PRESSURE, 0, 0); 359 + } 389 360 390 361 __set_bit(BTN_LEFT, input->keybit); 391 362 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); 392 363 393 - ret = input_mt_init_slots(input, MAX_CONTACTS, INPUT_MT_POINTER); 364 + ret = input_mt_init_slots(input, drvdata->tp->max_contacts, 365 + INPUT_MT_POINTER); 394 366 395 367 if (ret) { 396 368 hid_err(hdev, "Asus input mt init slots failed: %d\n", ret); ··· 436 376 * We do it all manually in asus_input_configured 437 377 */ 438 378 return -1; 379 + } 380 + 381 + /* 382 + * Ignore a bunch of bogus collections in the T100CHI descriptor. 383 + * This avoids a bunch of non-functional hid_input devices getting 384 + * created because of the T100CHI using HID_QUIRK_MULTI_INPUT. 385 + */ 386 + if (drvdata->quirks & QUIRK_T100CHI) { 387 + if (field->application == (HID_UP_GENDESK | 0x0080) || 388 + usage->hid == (HID_UP_GENDEVCTRLS | 0x0024) || 389 + usage->hid == (HID_UP_GENDEVCTRLS | 0x0025) || 390 + usage->hid == (HID_UP_GENDEVCTRLS | 0x0026)) 391 + return -1; 392 + /* 393 + * We use the hid_input for the mouse report for the touchpad, 394 + * keep the left button, to avoid the core removing it. 395 + */ 396 + if (field->application == HID_GD_MOUSE && 397 + usage->hid != (HID_UP_BUTTON | 1)) 398 + return -1; 439 399 } 440 400 441 401 /* ASUS-specific keyboard hotkeys */ ··· 576 496 { 577 497 struct asus_drvdata *drvdata = hid_get_drvdata(hdev); 578 498 579 - if (drvdata->quirks & QUIRK_IS_MULTITOUCH) 499 + if (drvdata->tp) 580 500 return asus_start_multitouch(hdev); 581 501 582 502 return 0; ··· 596 516 hid_set_drvdata(hdev, drvdata); 597 517 598 518 drvdata->quirks = id->driver_data; 519 + 520 + if (drvdata->quirks & QUIRK_IS_MULTITOUCH) 521 + drvdata->tp = &asus_i2c_tp; 522 + 523 + if (drvdata->quirks & QUIRK_T100_KEYBOARD) { 524 + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 525 + 526 + if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) { 527 + drvdata->quirks = QUIRK_SKIP_INPUT_MAPPING; 528 + drvdata->tp = &asus_t100ta_tp; 529 + } 530 + } 531 + 532 + if (drvdata->quirks & QUIRK_T100CHI) { 533 + /* 534 + * All functionality is on a single HID interface and for 535 + * userspace the touchpad must be a separate input_dev. 536 + */ 537 + hdev->quirks |= HID_QUIRK_MULTI_INPUT | 538 + HID_QUIRK_NO_EMPTY_INPUT; 539 + drvdata->tp = &asus_t100chi_tp; 540 + } 599 541 600 542 if (drvdata->quirks & QUIRK_NO_INIT_REPORTS) 601 543 hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; ··· 640 538 goto err_stop_hw; 641 539 } 642 540 643 - if (drvdata->quirks & QUIRK_IS_MULTITOUCH) { 541 + if (drvdata->tp) { 644 542 drvdata->input->name = "Asus TouchPad"; 645 543 } else { 646 544 drvdata->input->name = "Asus Keyboard"; 647 545 } 648 546 649 - if (drvdata->quirks & QUIRK_IS_MULTITOUCH) { 547 + if (drvdata->tp) { 650 548 ret = asus_start_multitouch(hdev); 651 549 if (ret) 652 550 goto err_stop_hw; ··· 680 578 hid_info(hdev, "Fixing up Asus notebook report descriptor\n"); 681 579 rdesc[55] = 0xdd; 682 580 } 581 + /* For the T100TA keyboard dock */ 683 582 if (drvdata->quirks & QUIRK_T100_KEYBOARD && 684 583 *rsize == 76 && rdesc[73] == 0x81 && rdesc[74] == 0x01) { 685 584 hid_info(hdev, "Fixing up Asus T100 keyb report descriptor\n"); 686 585 rdesc[74] &= ~HID_MAIN_ITEM_CONSTANT; 586 + } 587 + /* For the T100CHI keyboard dock */ 588 + if (drvdata->quirks & QUIRK_T100CHI && 589 + *rsize == 403 && rdesc[388] == 0x09 && rdesc[389] == 0x76) { 590 + /* 591 + * Change Usage (76h) to Usage Minimum (00h), Usage Maximum 592 + * (FFh) and clear the flags in the Input() byte. 593 + * Note the descriptor has a bogus 0 byte at the end so we 594 + * only need 1 extra byte. 595 + */ 596 + *rsize = 404; 597 + rdesc = kmemdup(rdesc, *rsize, GFP_KERNEL); 598 + if (!rdesc) 599 + return NULL; 600 + 601 + hid_info(hdev, "Fixing up T100CHI keyb report descriptor\n"); 602 + memmove(rdesc + 392, rdesc + 390, 12); 603 + rdesc[388] = 0x19; 604 + rdesc[389] = 0x00; 605 + rdesc[390] = 0x29; 606 + rdesc[391] = 0xff; 607 + rdesc[402] = 0x00; 687 608 } 688 609 689 610 return rdesc; ··· 727 602 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_ASUS_AK1D) }, 728 603 { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_ASUS_MD_5110) }, 729 604 { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_ASUS_MD_5112) }, 605 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK, 606 + USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD), QUIRK_T100CHI }, 607 + 730 608 { } 731 609 }; 732 610 MODULE_DEVICE_TABLE(hid, asus_devices);
+5 -11
drivers/hid/hid-core.c
··· 1982 1982 { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD) }, 1983 1983 { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_ASUS_MD_5112) }, 1984 1984 { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_ASUS_MD_5110) }, 1985 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD) }, 1985 1986 #endif 1986 1987 #if IS_ENABLED(CONFIG_HID_AUREAL) 1987 1988 { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, ··· 2488 2487 const struct hid_device_id *id; 2489 2488 int ret = 0; 2490 2489 2491 - if (down_interruptible(&hdev->driver_lock)) 2492 - return -EINTR; 2493 2490 if (down_interruptible(&hdev->driver_input_lock)) { 2494 2491 ret = -EINTR; 2495 - goto unlock_driver_lock; 2492 + goto end; 2496 2493 } 2497 2494 hdev->io_started = false; 2498 2495 ··· 2517 2518 unlock: 2518 2519 if (!hdev->io_started) 2519 2520 up(&hdev->driver_input_lock); 2520 - unlock_driver_lock: 2521 - up(&hdev->driver_lock); 2521 + end: 2522 2522 return ret; 2523 2523 } 2524 2524 ··· 2527 2529 struct hid_driver *hdrv; 2528 2530 int ret = 0; 2529 2531 2530 - if (down_interruptible(&hdev->driver_lock)) 2531 - return -EINTR; 2532 2532 if (down_interruptible(&hdev->driver_input_lock)) { 2533 2533 ret = -EINTR; 2534 - goto unlock_driver_lock; 2534 + goto end; 2535 2535 } 2536 2536 hdev->io_started = false; 2537 2537 ··· 2545 2549 2546 2550 if (!hdev->io_started) 2547 2551 up(&hdev->driver_input_lock); 2548 - unlock_driver_lock: 2549 - up(&hdev->driver_lock); 2552 + end: 2550 2553 return ret; 2551 2554 } 2552 2555 ··· 3003 3008 init_waitqueue_head(&hdev->debug_wait); 3004 3009 INIT_LIST_HEAD(&hdev->debug_list); 3005 3010 spin_lock_init(&hdev->debug_list_lock); 3006 - sema_init(&hdev->driver_lock, 1); 3007 3011 sema_init(&hdev->driver_input_lock, 1); 3008 3012 mutex_init(&hdev->ll_open_lock); 3009 3013
+4 -1
drivers/hid/hid-ids.h
··· 176 176 #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 177 177 #define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b 178 178 #define USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD 0x17e0 179 + #define USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD 0x8502 180 + #define USB_DEVICE_ID_ASUSTEK_T304_KEYBOARD 0x184a 179 181 #define USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD 0x8585 180 182 #define USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD 0x0101 181 183 #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 0x1854 ··· 668 666 #define USB_VENDOR_ID_LOGITECH 0x046d 669 667 #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e 670 668 #define USB_DEVICE_ID_LOGITECH_T651 0xb00c 671 - #define USB_DEVICE_ID_LOGITECH_C077 0xc007 669 + #define USB_DEVICE_ID_LOGITECH_C007 0xc007 670 + #define USB_DEVICE_ID_LOGITECH_C077 0xc077 672 671 #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 673 672 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 674 673 #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
+135 -61
drivers/hid/hid-input.c
··· 340 340 return quirks; 341 341 } 342 342 343 + static int hidinput_scale_battery_capacity(struct hid_device *dev, 344 + int value) 345 + { 346 + if (dev->battery_min < dev->battery_max && 347 + value >= dev->battery_min && value <= dev->battery_max) 348 + value = ((value - dev->battery_min) * 100) / 349 + (dev->battery_max - dev->battery_min); 350 + 351 + return value; 352 + } 353 + 354 + static int hidinput_query_battery_capacity(struct hid_device *dev) 355 + { 356 + u8 *buf; 357 + int ret; 358 + 359 + buf = kmalloc(2, GFP_KERNEL); 360 + if (!buf) 361 + return -ENOMEM; 362 + 363 + ret = hid_hw_raw_request(dev, dev->battery_report_id, buf, 2, 364 + dev->battery_report_type, HID_REQ_GET_REPORT); 365 + if (ret != 2) { 366 + kfree(buf); 367 + return -ENODATA; 368 + } 369 + 370 + ret = hidinput_scale_battery_capacity(dev, buf[1]); 371 + kfree(buf); 372 + return ret; 373 + } 374 + 343 375 static int hidinput_get_battery_property(struct power_supply *psy, 344 376 enum power_supply_property prop, 345 377 union power_supply_propval *val) 346 378 { 347 379 struct hid_device *dev = power_supply_get_drvdata(psy); 380 + int value; 348 381 int ret = 0; 349 - __u8 *buf; 350 382 351 383 switch (prop) { 352 384 case POWER_SUPPLY_PROP_PRESENT: ··· 387 355 break; 388 356 389 357 case POWER_SUPPLY_PROP_CAPACITY: 390 - 391 - buf = kmalloc(2 * sizeof(__u8), GFP_KERNEL); 392 - if (!buf) { 393 - ret = -ENOMEM; 394 - break; 358 + if (dev->battery_report_type == HID_FEATURE_REPORT) { 359 + value = hidinput_query_battery_capacity(dev); 360 + if (value < 0) 361 + return value; 362 + } else { 363 + value = dev->battery_capacity; 395 364 } 396 - ret = hid_hw_raw_request(dev, dev->battery_report_id, buf, 2, 397 - dev->battery_report_type, 398 - HID_REQ_GET_REPORT); 399 365 400 - if (ret != 2) { 401 - ret = -ENODATA; 402 - kfree(buf); 403 - break; 404 - } 405 - ret = 0; 406 - 407 - if (dev->battery_min < dev->battery_max && 408 - buf[1] >= dev->battery_min && 409 - buf[1] <= dev->battery_max) 410 - val->intval = (100 * (buf[1] - dev->battery_min)) / 411 - (dev->battery_max - dev->battery_min); 412 - kfree(buf); 366 + val->intval = value; 413 367 break; 414 368 415 369 case POWER_SUPPLY_PROP_MODEL_NAME: ··· 403 385 break; 404 386 405 387 case POWER_SUPPLY_PROP_STATUS: 406 - val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 388 + if (!dev->battery_reported && 389 + dev->battery_report_type == HID_FEATURE_REPORT) { 390 + value = hidinput_query_battery_capacity(dev); 391 + if (value < 0) 392 + return value; 393 + 394 + dev->battery_capacity = value; 395 + dev->battery_reported = true; 396 + } 397 + 398 + if (!dev->battery_reported) 399 + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 400 + else if (dev->battery_capacity == 100) 401 + val->intval = POWER_SUPPLY_STATUS_FULL; 402 + else 403 + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 407 404 break; 408 405 409 406 case POWER_SUPPLY_PROP_SCOPE: ··· 433 400 return ret; 434 401 } 435 402 436 - static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, struct hid_field *field) 403 + static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, struct hid_field *field) 437 404 { 438 - struct power_supply_desc *psy_desc = NULL; 405 + struct power_supply_desc *psy_desc; 439 406 struct power_supply_config psy_cfg = { .drv_data = dev, }; 440 407 unsigned quirks; 441 408 s32 min, max; 409 + int error; 442 410 443 - if (field->usage->hid != HID_DC_BATTERYSTRENGTH) 444 - return false; /* no match */ 445 - 446 - if (dev->battery != NULL) 447 - goto out; /* already initialized? */ 411 + if (dev->battery) 412 + return 0; /* already initialized? */ 448 413 449 414 quirks = find_battery_quirk(dev); 450 415 ··· 450 419 dev->bus, dev->vendor, dev->product, dev->version, quirks); 451 420 452 421 if (quirks & HID_BATTERY_QUIRK_IGNORE) 453 - goto out; 422 + return 0; 454 423 455 424 psy_desc = kzalloc(sizeof(*psy_desc), GFP_KERNEL); 456 - if (psy_desc == NULL) 457 - goto out; 425 + if (!psy_desc) 426 + return -ENOMEM; 458 427 459 - psy_desc->name = kasprintf(GFP_KERNEL, "hid-%s-battery", dev->uniq); 460 - if (psy_desc->name == NULL) { 461 - kfree(psy_desc); 462 - goto out; 428 + psy_desc->name = kasprintf(GFP_KERNEL, "hid-%s-battery", 429 + strlen(dev->uniq) ? 430 + dev->uniq : dev_name(&dev->dev)); 431 + if (!psy_desc->name) { 432 + error = -ENOMEM; 433 + goto err_free_mem; 463 434 } 464 435 465 436 psy_desc->type = POWER_SUPPLY_TYPE_BATTERY; ··· 488 455 489 456 dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg); 490 457 if (IS_ERR(dev->battery)) { 491 - hid_warn(dev, "can't register power supply: %ld\n", 492 - PTR_ERR(dev->battery)); 493 - kfree(psy_desc->name); 494 - kfree(psy_desc); 495 - dev->battery = NULL; 496 - } else { 497 - power_supply_powers(dev->battery, &dev->dev); 458 + error = PTR_ERR(dev->battery); 459 + hid_warn(dev, "can't register power supply: %d\n", error); 460 + goto err_free_name; 498 461 } 499 462 500 - out: 501 - return true; 463 + power_supply_powers(dev->battery, &dev->dev); 464 + return 0; 465 + 466 + err_free_name: 467 + kfree(psy_desc->name); 468 + err_free_mem: 469 + kfree(psy_desc); 470 + dev->battery = NULL; 471 + return error; 502 472 } 503 473 504 474 static void hidinput_cleanup_battery(struct hid_device *dev) ··· 517 481 kfree(psy_desc); 518 482 dev->battery = NULL; 519 483 } 520 - #else /* !CONFIG_HID_BATTERY_STRENGTH */ 521 - static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, 522 - struct hid_field *field) 484 + 485 + static void hidinput_update_battery(struct hid_device *dev, int value) 523 486 { 524 - return false; 487 + int capacity; 488 + 489 + if (!dev->battery) 490 + return; 491 + 492 + if (value == 0 || value < dev->battery_min || value > dev->battery_max) 493 + return; 494 + 495 + capacity = hidinput_scale_battery_capacity(dev, value); 496 + 497 + if (!dev->battery_reported || capacity != dev->battery_capacity) { 498 + dev->battery_capacity = capacity; 499 + dev->battery_reported = true; 500 + power_supply_changed(dev->battery); 501 + } 502 + } 503 + #else /* !CONFIG_HID_BATTERY_STRENGTH */ 504 + static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, 505 + struct hid_field *field) 506 + { 507 + return 0; 525 508 } 526 509 527 510 static void hidinput_cleanup_battery(struct hid_device *dev) 511 + { 512 + } 513 + 514 + static void hidinput_update_battery(struct hid_device *dev, int value) 528 515 { 529 516 } 530 517 #endif /* CONFIG_HID_BATTERY_STRENGTH */ ··· 768 709 default: map_key(BTN_TOOL_PEN); break; 769 710 } 770 711 break; 712 + 713 + case 0x3b: /* Battery Strength */ 714 + hidinput_setup_battery(device, HID_INPUT_REPORT, field); 715 + usage->type = EV_PWR; 716 + goto ignore; 771 717 772 718 case 0x3c: /* Invert */ 773 719 map_key_clear(BTN_TOOL_RUBBER); ··· 1008 944 break; 1009 945 1010 946 case HID_UP_GENDEVCTRLS: 1011 - if (hidinput_setup_battery(device, HID_INPUT_REPORT, field)) 947 + switch (usage->hid) { 948 + case HID_DC_BATTERYSTRENGTH: 949 + hidinput_setup_battery(device, HID_INPUT_REPORT, field); 950 + usage->type = EV_PWR; 1012 951 goto ignore; 1013 - else 1014 - goto unknown; 1015 - break; 952 + } 953 + goto unknown; 1016 954 1017 955 case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */ 1018 956 set_bit(EV_REP, input->evbit); ··· 1097 1031 if (usage->code > max) 1098 1032 goto ignore; 1099 1033 1100 - 1101 1034 if (usage->type == EV_ABS) { 1102 1035 1103 1036 int a = field->logical_minimum; ··· 1155 1090 struct input_dev *input; 1156 1091 unsigned *quirks = &hid->quirks; 1157 1092 1093 + if (!usage->type) 1094 + return; 1095 + 1096 + if (usage->type == EV_PWR) { 1097 + hidinput_update_battery(hid, value); 1098 + return; 1099 + } 1100 + 1158 1101 if (!field->hidinput) 1159 1102 return; 1160 1103 1161 1104 input = field->hidinput->input; 1162 - 1163 - if (!usage->type) 1164 - return; 1165 1105 1166 1106 if (usage->hat_min < usage->hat_max || usage->hat_dir) { 1167 1107 int hat_dir = usage->hat_dir; ··· 1443 1373 struct hid_driver *drv = hid->driver; 1444 1374 struct hid_report_enum *rep_enum; 1445 1375 struct hid_report *rep; 1376 + struct hid_usage *usage; 1446 1377 int i, j; 1447 1378 1448 1379 rep_enum = &hid->report_enum[HID_FEATURE_REPORT]; ··· 1454 1383 continue; 1455 1384 1456 1385 for (j = 0; j < rep->field[i]->maxusage; j++) { 1386 + usage = &rep->field[i]->usage[j]; 1387 + 1457 1388 /* Verify if Battery Strength feature is available */ 1458 - hidinput_setup_battery(hid, HID_FEATURE_REPORT, rep->field[i]); 1389 + if (usage->hid == HID_DC_BATTERYSTRENGTH) 1390 + hidinput_setup_battery(hid, HID_FEATURE_REPORT, 1391 + rep->field[i]); 1459 1392 1460 1393 if (drv->feature_mapping) 1461 - drv->feature_mapping(hid, rep->field[i], 1462 - rep->field[i]->usage + j); 1394 + drv->feature_mapping(hid, rep->field[i], usage); 1463 1395 } 1464 1396 } 1465 1397 }
+1 -1
drivers/hid/hid-logitech-hidpp.c
··· 2926 2926 NULL 2927 2927 }; 2928 2928 2929 - static struct attribute_group ps_attribute_group = { 2929 + static const struct attribute_group ps_attribute_group = { 2930 2930 .attrs = sysfs_attrs 2931 2931 }; 2932 2932
+48 -2
drivers/hid/hid-multitouch.c
··· 72 72 #define MT_QUIRK_FIX_CONST_CONTACT_ID BIT(14) 73 73 #define MT_QUIRK_TOUCH_SIZE_SCALING BIT(15) 74 74 #define MT_QUIRK_STICKY_FINGERS BIT(16) 75 + #define MT_QUIRK_ASUS_CUSTOM_UP BIT(17) 75 76 76 77 #define MT_INPUTMODE_TOUCHSCREEN 0x02 77 78 #define MT_INPUTMODE_TOUCHPAD 0x03 ··· 170 169 #define MT_CLS_GENERALTOUCH_TWOFINGERS 0x0108 171 170 #define MT_CLS_GENERALTOUCH_PWT_TENFINGERS 0x0109 172 171 #define MT_CLS_LG 0x010a 172 + #define MT_CLS_ASUS 0x010b 173 173 #define MT_CLS_VTL 0x0110 174 174 #define MT_CLS_GOOGLE 0x0111 175 175 ··· 292 290 MT_QUIRK_IGNORE_DUPLICATES | 293 291 MT_QUIRK_HOVERING | 294 292 MT_QUIRK_CONTACT_CNT_ACCURATE }, 293 + { .name = MT_CLS_ASUS, 294 + .quirks = MT_QUIRK_ALWAYS_VALID | 295 + MT_QUIRK_CONTACT_CNT_ACCURATE | 296 + MT_QUIRK_ASUS_CUSTOM_UP }, 295 297 { .name = MT_CLS_VTL, 296 298 .quirks = MT_QUIRK_ALWAYS_VALID | 297 299 MT_QUIRK_CONTACT_CNT_ACCURATE | ··· 347 341 NULL 348 342 }; 349 343 350 - static struct attribute_group mt_attribute_group = { 344 + static const struct attribute_group mt_attribute_group = { 351 345 .attrs = sysfs_attrs 352 346 }; 353 347 ··· 911 905 return 0; 912 906 } 913 907 908 + #define mt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, \ 909 + max, EV_KEY, (c)) 914 910 static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, 915 911 struct hid_field *field, struct hid_usage *usage, 916 912 unsigned long **bit, int *max) ··· 930 922 field->application != HID_DG_PEN && 931 923 field->application != HID_DG_TOUCHPAD && 932 924 field->application != HID_GD_KEYBOARD && 933 - field->application != HID_CP_CONSUMER_CONTROL) 925 + field->application != HID_CP_CONSUMER_CONTROL && 926 + field->application != HID_GD_WIRELESS_RADIO_CTLS && 927 + !(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS && 928 + td->mtclass.quirks & MT_QUIRK_ASUS_CUSTOM_UP)) 934 929 return -1; 930 + 931 + /* 932 + * Some Asus keyboard+touchpad devices have the hotkeys defined in the 933 + * touchpad report descriptor. We need to treat these as an array to 934 + * map usages to input keys. 935 + */ 936 + if (field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS && 937 + td->mtclass.quirks & MT_QUIRK_ASUS_CUSTOM_UP && 938 + (usage->hid & HID_USAGE_PAGE) == HID_UP_CUSTOM) { 939 + set_bit(EV_REP, hi->input->evbit); 940 + if (field->flags & HID_MAIN_ITEM_VARIABLE) 941 + field->flags &= ~HID_MAIN_ITEM_VARIABLE; 942 + switch (usage->hid & HID_USAGE) { 943 + case 0x10: mt_map_key_clear(KEY_BRIGHTNESSDOWN); break; 944 + case 0x20: mt_map_key_clear(KEY_BRIGHTNESSUP); break; 945 + case 0x35: mt_map_key_clear(KEY_DISPLAY_OFF); break; 946 + case 0x6b: mt_map_key_clear(KEY_F21); break; 947 + case 0x6c: mt_map_key_clear(KEY_SLEEP); break; 948 + default: 949 + return -1; 950 + } 951 + return 1; 952 + } 935 953 936 954 /* 937 955 * some egalax touchscreens have "application == HID_DG_TOUCHSCREEN" ··· 1166 1132 break; 1167 1133 case HID_CP_CONSUMER_CONTROL: 1168 1134 suffix = "Consumer Control"; 1135 + break; 1136 + case HID_GD_WIRELESS_RADIO_CTLS: 1137 + suffix = "Wireless Radio Control"; 1138 + break; 1139 + case HID_VD_ASUS_CUSTOM_MEDIA_KEYS: 1140 + suffix = "Custom Media Keys"; 1169 1141 break; 1170 1142 default: 1171 1143 suffix = "UNKNOWN"; ··· 1423 1383 { .driver_data = MT_CLS_EXPORT_ALL_INPUTS, 1424 1384 MT_USB_DEVICE(USB_VENDOR_ID_ANTON, 1425 1385 USB_DEVICE_ID_ANTON_TOUCH_PAD) }, 1386 + 1387 + /* Asus T304UA */ 1388 + { .driver_data = MT_CLS_ASUS, 1389 + HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, 1390 + USB_VENDOR_ID_ASUSTEK, 1391 + USB_DEVICE_ID_ASUSTEK_T304_KEYBOARD) }, 1426 1392 1427 1393 /* Atmel panels */ 1428 1394 { .driver_data = MT_CLS_SERIAL,
+1 -1
drivers/hid/hid-ntrig.c
··· 445 445 NULL 446 446 }; 447 447 448 - static struct attribute_group ntrig_attribute_group = { 448 + static const struct attribute_group ntrig_attribute_group = { 449 449 .attrs = sysfs_attrs 450 450 }; 451 451
+1 -1
drivers/hid/hid-prodikeys.c
··· 593 593 pm->in_triggered = up; 594 594 } 595 595 596 - static struct snd_rawmidi_ops pcmidi_in_ops = { 596 + static const struct snd_rawmidi_ops pcmidi_in_ops = { 597 597 .open = pcmidi_in_open, 598 598 .close = pcmidi_in_close, 599 599 .trigger = pcmidi_in_trigger
+2 -2
drivers/hid/hid-sensor-custom.c
··· 276 276 NULL, 277 277 }; 278 278 279 - static struct attribute_group enable_sensor_attr_group = { 279 + static const struct attribute_group enable_sensor_attr_group = { 280 280 .attrs = enable_sensor_attrs, 281 281 }; 282 282 ··· 823 823 return 0; 824 824 } 825 825 826 - static struct platform_device_id hid_sensor_custom_ids[] = { 826 + static const struct platform_device_id hid_sensor_custom_ids[] = { 827 827 { 828 828 .name = "HID-SENSOR-2000e1", 829 829 },
-94
drivers/hid/hid-sensor-hub.c
··· 579 579 } 580 580 EXPORT_SYMBOL_GPL(sensor_hub_device_close); 581 581 582 - static __u8 *sensor_hub_report_fixup(struct hid_device *hdev, __u8 *rdesc, 583 - unsigned int *rsize) 584 - { 585 - int index; 586 - struct sensor_hub_data *sd = hid_get_drvdata(hdev); 587 - unsigned char report_block[] = { 588 - 0x0a, 0x16, 0x03, 0x15, 0x00, 0x25, 0x05}; 589 - unsigned char power_block[] = { 590 - 0x0a, 0x19, 0x03, 0x15, 0x00, 0x25, 0x05}; 591 - 592 - if (!(sd->quirks & HID_SENSOR_HUB_ENUM_QUIRK)) { 593 - hid_dbg(hdev, "No Enum quirks\n"); 594 - return rdesc; 595 - } 596 - 597 - /* Looks for power and report state usage id and force to 1 */ 598 - for (index = 0; index < *rsize; ++index) { 599 - if (((*rsize - index) > sizeof(report_block)) && 600 - !memcmp(&rdesc[index], report_block, 601 - sizeof(report_block))) { 602 - rdesc[index + 4] = 0x01; 603 - index += sizeof(report_block); 604 - } 605 - if (((*rsize - index) > sizeof(power_block)) && 606 - !memcmp(&rdesc[index], power_block, 607 - sizeof(power_block))) { 608 - rdesc[index + 4] = 0x01; 609 - index += sizeof(power_block); 610 - } 611 - } 612 - 613 - /* Checks if the report descriptor of Thinkpad Helix 2 has a logical 614 - * minimum for magnetic flux axis greater than the maximum */ 615 - if (hdev->product == USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA && 616 - *rsize == 2558 && rdesc[913] == 0x17 && rdesc[914] == 0x40 && 617 - rdesc[915] == 0x81 && rdesc[916] == 0x08 && 618 - rdesc[917] == 0x00 && rdesc[918] == 0x27 && 619 - rdesc[921] == 0x07 && rdesc[922] == 0x00) { 620 - /* Sets negative logical minimum for mag x, y and z */ 621 - rdesc[914] = rdesc[935] = rdesc[956] = 0xc0; 622 - rdesc[915] = rdesc[936] = rdesc[957] = 0x7e; 623 - rdesc[916] = rdesc[937] = rdesc[958] = 0xf7; 624 - rdesc[917] = rdesc[938] = rdesc[959] = 0xff; 625 - } 626 - 627 - return rdesc; 628 - } 629 - 630 582 static int sensor_hub_probe(struct hid_device *hdev, 631 583 const struct hid_device_id *id) 632 584 { ··· 730 778 } 731 779 732 780 static const struct hid_device_id sensor_hub_devices[] = { 733 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_0, 734 - USB_DEVICE_ID_INTEL_HID_SENSOR_0), 735 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 736 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1, 737 - USB_DEVICE_ID_INTEL_HID_SENSOR_0), 738 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 739 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1, 740 - USB_DEVICE_ID_INTEL_HID_SENSOR_1), 741 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 742 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT, 743 - USB_DEVICE_ID_MS_SURFACE_PRO_2), 744 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 745 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT, 746 - USB_DEVICE_ID_MS_TOUCH_COVER_2), 747 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 748 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT, 749 - USB_DEVICE_ID_MS_TYPE_COVER_2), 750 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 751 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT, 752 - 0x07bd), /* Microsoft Surface 3 */ 753 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 754 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROCHIP, 755 - 0x0f01), /* MM7150 */ 756 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 757 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, 758 - USB_DEVICE_ID_STM_HID_SENSOR), 759 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 760 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, 761 - USB_DEVICE_ID_STM_HID_SENSOR_1), 762 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 763 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_TEXAS_INSTRUMENTS, 764 - USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA), 765 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 766 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE, 767 - USB_DEVICE_ID_ITE_LENOVO_YOGA), 768 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 769 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE, 770 - USB_DEVICE_ID_ITE_LENOVO_YOGA2), 771 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 772 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE, 773 - USB_DEVICE_ID_ITE_LENOVO_YOGA900), 774 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 775 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_0, 776 - 0x22D8), 777 - .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 778 781 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, 779 782 HID_ANY_ID) }, 780 783 { } ··· 742 835 .probe = sensor_hub_probe, 743 836 .remove = sensor_hub_remove, 744 837 .raw_event = sensor_hub_raw_event, 745 - .report_fixup = sensor_hub_report_fixup, 746 838 #ifdef CONFIG_PM 747 839 .suspend = sensor_hub_suspend, 748 840 .resume = sensor_hub_resume,
+2 -1
drivers/hid/i2c-hid/i2c-hid.c
··· 780 780 return 0; 781 781 } 782 782 783 - static struct hid_ll_driver i2c_hid_ll_driver = { 783 + struct hid_ll_driver i2c_hid_ll_driver = { 784 784 .parse = i2c_hid_parse, 785 785 .start = i2c_hid_start, 786 786 .stop = i2c_hid_stop, ··· 790 790 .output_report = i2c_hid_output_report, 791 791 .raw_request = i2c_hid_raw_request, 792 792 }; 793 + EXPORT_SYMBOL_GPL(i2c_hid_ll_driver); 793 794 794 795 static int i2c_hid_init_irq(struct i2c_client *client) 795 796 {
+2 -1
drivers/hid/uhid.c
··· 369 369 return uhid_hid_output_raw(hid, buf, count, HID_OUTPUT_REPORT); 370 370 } 371 371 372 - static struct hid_ll_driver uhid_hid_driver = { 372 + struct hid_ll_driver uhid_hid_driver = { 373 373 .start = uhid_hid_start, 374 374 .stop = uhid_hid_stop, 375 375 .open = uhid_hid_open, ··· 378 378 .raw_request = uhid_hid_raw_request, 379 379 .output_report = uhid_hid_output_report, 380 380 }; 381 + EXPORT_SYMBOL_GPL(uhid_hid_driver); 381 382 382 383 #ifdef CONFIG_COMPAT 383 384
+2 -1
drivers/hid/usbhid/hid-core.c
··· 1265 1265 return hid_set_idle(dev, ifnum, report, idle); 1266 1266 } 1267 1267 1268 - static struct hid_ll_driver usb_hid_driver = { 1268 + struct hid_ll_driver usb_hid_driver = { 1269 1269 .parse = usbhid_parse, 1270 1270 .start = usbhid_start, 1271 1271 .stop = usbhid_stop, ··· 1278 1278 .output_report = usbhid_output_report, 1279 1279 .idle = usbhid_idle, 1280 1280 }; 1281 + EXPORT_SYMBOL_GPL(usb_hid_driver); 1281 1282 1282 1283 static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id) 1283 1284 {
+1
drivers/hid/usbhid/hid-quirks.c
··· 99 99 { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL }, 100 100 { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL }, 101 101 { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, 102 + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007, HID_QUIRK_ALWAYS_POLL }, 102 103 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL }, 103 104 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, HID_QUIRK_NOGET }, 104 105 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A, HID_QUIRK_ALWAYS_POLL },
+1 -1
drivers/hid/usbhid/usbkbd.c
··· 392 392 } 393 393 } 394 394 395 - static struct usb_device_id usb_kbd_id_table [] = { 395 + static const struct usb_device_id usb_kbd_id_table[] = { 396 396 { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT, 397 397 USB_INTERFACE_PROTOCOL_KEYBOARD) }, 398 398 { } /* Terminating entry */
+1 -1
drivers/hid/usbhid/usbmouse.c
··· 226 226 } 227 227 } 228 228 229 - static struct usb_device_id usb_mouse_id_table [] = { 229 + static const struct usb_device_id usb_mouse_id_table[] = { 230 230 { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT, 231 231 USB_INTERFACE_PROTOCOL_MOUSE) }, 232 232 { } /* Terminating entry */
+30 -37
drivers/hid/wacom_sys.c
··· 1671 1671 u8 mode; 1672 1672 1673 1673 mode = wacom->led.groups[index].select; 1674 - if (mode >= 0 && mode < 3) 1675 - return snprintf(buf, PAGE_SIZE, "%d\n", mode); 1676 - else 1677 - return snprintf(buf, PAGE_SIZE, "%d\n", -1); 1674 + return sprintf(buf, "%d\n", mode < 3 ? mode : -1); 1678 1675 } 1679 1676 1680 1677 #define DEVICE_EKR_ATTR_GROUP(SET_ID) \ ··· 2025 2028 2026 2029 /* Generic devices name unspecified */ 2027 2030 if ((features->type == HID_GENERIC) && !strcmp("Wacom HID", features->name)) { 2028 - if (strstr(wacom->hdev->name, "Wacom") || 2029 - strstr(wacom->hdev->name, "wacom") || 2030 - strstr(wacom->hdev->name, "WACOM")) { 2031 - /* name is in HID descriptor, use it */ 2032 - strlcpy(name, wacom->hdev->name, sizeof(name)); 2031 + char *product_name = wacom->hdev->name; 2033 2032 2034 - /* strip out excess whitespaces */ 2035 - while (1) { 2036 - char *gap = strstr(name, " "); 2037 - if (gap == NULL) 2038 - break; 2039 - /* shift everything including the terminator */ 2040 - memmove(gap, gap+1, strlen(gap)); 2041 - } 2042 - 2043 - /* strip off excessive prefixing */ 2044 - if (strstr(name, "Wacom Co.,Ltd. Wacom ") == name) { 2045 - int n = strlen(name); 2046 - int x = strlen("Wacom Co.,Ltd. "); 2047 - memmove(name, name+x, n-x+1); 2048 - } 2049 - if (strstr(name, "Wacom Co., Ltd. Wacom ") == name) { 2050 - int n = strlen(name); 2051 - int x = strlen("Wacom Co., Ltd. "); 2052 - memmove(name, name+x, n-x+1); 2053 - } 2054 - 2055 - /* get rid of trailing whitespace */ 2056 - if (name[strlen(name)-1] == ' ') 2057 - name[strlen(name)-1] = '\0'; 2058 - } else { 2059 - /* no meaningful name retrieved. use product ID */ 2060 - snprintf(name, sizeof(name), 2061 - "%s %X", features->name, wacom->hdev->product); 2033 + if (hid_is_using_ll_driver(wacom->hdev, &usb_hid_driver)) { 2034 + struct usb_interface *intf = to_usb_interface(wacom->hdev->dev.parent); 2035 + struct usb_device *dev = interface_to_usbdev(intf); 2036 + product_name = dev->product; 2062 2037 } 2038 + 2039 + if (wacom->hdev->bus == BUS_I2C) { 2040 + snprintf(name, sizeof(name), "%s %X", 2041 + features->name, wacom->hdev->product); 2042 + } else if (strstr(product_name, "Wacom") || 2043 + strstr(product_name, "wacom") || 2044 + strstr(product_name, "WACOM")) { 2045 + strlcpy(name, product_name, sizeof(name)); 2046 + } else { 2047 + snprintf(name, sizeof(name), "Wacom %s", product_name); 2048 + } 2049 + 2050 + /* strip out excess whitespaces */ 2051 + while (1) { 2052 + char *gap = strstr(name, " "); 2053 + if (gap == NULL) 2054 + break; 2055 + /* shift everything including the terminator */ 2056 + memmove(gap, gap+1, strlen(gap)); 2057 + } 2058 + 2059 + /* get rid of trailing whitespace */ 2060 + if (name[strlen(name)-1] == ' ') 2061 + name[strlen(name)-1] = '\0'; 2063 2062 } else { 2064 2063 strlcpy(name, features->name, sizeof(name)); 2065 2064 }
+7 -1
drivers/hid/wacom_wac.c
··· 1846 1846 features->device_type |= WACOM_DEVICETYPE_PAD; 1847 1847 break; 1848 1848 case WACOM_HID_WD_TOUCHRINGSTATUS: 1849 - wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0); 1849 + /* 1850 + * Only set up type/code association. Completely mapping 1851 + * this usage may overwrite the axis resolution and range. 1852 + */ 1853 + usage->type = EV_ABS; 1854 + usage->code = ABS_WHEEL; 1855 + set_bit(EV_ABS, input->evbit); 1850 1856 features->device_type |= WACOM_DEVICETYPE_PAD; 1851 1857 break; 1852 1858 case WACOM_HID_WD_BUTTONCONFIG:
+3
drivers/iio/common/hid-sensors/hid-sensor-attributes.c
··· 473 473 HID_USAGE_SENSOR_PROY_POWER_STATE, 474 474 &st->power_state); 475 475 476 + st->power_state.logical_minimum = 1; 477 + st->report_state.logical_minimum = 1; 478 + 476 479 sensor_hub_input_get_attribute_info(hsdev, 477 480 HID_FEATURE_REPORT, usage_id, 478 481 HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS,
+16 -2
include/linux/hid.h
··· 173 173 #define HID_UP_LOGIVENDOR3 0xff430000 174 174 #define HID_UP_LNVENDOR 0xffa00000 175 175 #define HID_UP_SENSOR 0x00200000 176 + #define HID_UP_ASUSVENDOR 0xff310000 176 177 177 178 #define HID_USAGE 0x0000ffff 178 179 ··· 293 292 #define HID_DG_BARRELSWITCH2 0x000d005a 294 293 #define HID_DG_TOOLSERIALNUMBER 0x000d005b 295 294 295 + #define HID_VD_ASUS_CUSTOM_MEDIA_KEYS 0xff310076 296 296 /* 297 297 * HID report types --- Ouch! HID spec says 1 2 3! 298 298 */ ··· 534 532 struct hid_report_enum report_enum[HID_REPORT_TYPES]; 535 533 struct work_struct led_work; /* delayed LED worker */ 536 534 537 - struct semaphore driver_lock; /* protects the current driver, except during input */ 538 535 struct semaphore driver_input_lock; /* protects the current driver */ 539 536 struct device dev; /* device */ 540 537 struct hid_driver *driver; ··· 549 548 * battery is non-NULL. 550 549 */ 551 550 struct power_supply *battery; 551 + __s32 battery_capacity; 552 552 __s32 battery_min; 553 553 __s32 battery_max; 554 554 __s32 battery_report_type; 555 555 __s32 battery_report_id; 556 + bool battery_reported; 556 557 #endif 557 558 558 559 unsigned int status; /* see STAT flags above */ 559 560 unsigned claimed; /* Claimed by hidinput, hiddev? */ 560 561 unsigned quirks; /* Various quirks the device can pull on us */ 561 - bool io_started; /* Protected by driver_lock. If IO has started */ 562 + bool io_started; /* If IO has started */ 562 563 563 564 struct list_head inputs; /* The list of inputs */ 564 565 void *hiddev; /* The hiddev structure */ ··· 785 782 786 783 int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype); 787 784 }; 785 + 786 + extern struct hid_ll_driver i2c_hid_ll_driver; 787 + extern struct hid_ll_driver hidp_hid_driver; 788 + extern struct hid_ll_driver uhid_hid_driver; 789 + extern struct hid_ll_driver usb_hid_driver; 790 + 791 + static inline bool hid_is_using_ll_driver(struct hid_device *hdev, 792 + struct hid_ll_driver *driver) 793 + { 794 + return hdev->ll_driver == driver; 795 + } 788 796 789 797 #define PM_HINT_FULLON 1<<5 790 798 #define PM_HINT_NORMAL 1<<1
+2 -1
net/bluetooth/hidp/core.c
··· 734 734 hid->claimed = 0; 735 735 } 736 736 737 - static struct hid_ll_driver hidp_hid_driver = { 737 + struct hid_ll_driver hidp_hid_driver = { 738 738 .parse = hidp_parse, 739 739 .start = hidp_start, 740 740 .stop = hidp_stop, ··· 743 743 .raw_request = hidp_raw_request, 744 744 .output_report = hidp_output_report, 745 745 }; 746 + EXPORT_SYMBOL_GPL(hidp_hid_driver); 746 747 747 748 /* This function sets up the hid device. It does not add it 748 749 to the HID system. That is done in hidp_add_connection(). */