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