diff options
| -rw-r--r-- | Documentation/input/event-codes.rst | 11 | ||||
| -rw-r--r-- | drivers/hid/hid-ids.h | 8 | ||||
| -rw-r--r-- | drivers/hid/hid-input.c | 47 | ||||
| -rw-r--r-- | drivers/hid/hid-logitech-hidpp.c | 309 | ||||
| -rw-r--r-- | drivers/hid/hid-multitouch.c | 6 | ||||
| -rw-r--r-- | drivers/hid/hid-quirks.c | 3 | ||||
| -rw-r--r-- | drivers/hid/hid-steam.c | 154 | ||||
| -rw-r--r-- | drivers/hid/i2c-hid/i2c-hid-core.c | 2 | ||||
| -rw-r--r-- | drivers/hid/uhid.c | 25 | ||||
| -rw-r--r-- | include/linux/hid.h | 28 | ||||
| -rw-r--r-- | include/uapi/linux/input-event-codes.h | 10 |
11 files changed, 159 insertions, 444 deletions
diff --git a/Documentation/input/event-codes.rst b/Documentation/input/event-codes.rst index cef220c176a4..a8c0873beb95 100644 --- a/Documentation/input/event-codes.rst +++ b/Documentation/input/event-codes.rst | |||
| @@ -190,16 +190,7 @@ A few EV_REL codes have special meanings: | |||
| 190 | * REL_WHEEL, REL_HWHEEL: | 190 | * REL_WHEEL, REL_HWHEEL: |
| 191 | 191 | ||
| 192 | - These codes are used for vertical and horizontal scroll wheels, | 192 | - These codes are used for vertical and horizontal scroll wheels, |
| 193 | respectively. The value is the number of "notches" moved on the wheel, the | 193 | respectively. |
| 194 | physical size of which varies by device. For high-resolution wheels (which | ||
| 195 | report multiple events for each notch of movement, or do not have notches) | ||
| 196 | this may be an approximation based on the high-resolution scroll events. | ||
| 197 | |||
| 198 | * REL_WHEEL_HI_RES: | ||
| 199 | |||
| 200 | - If a vertical scroll wheel supports high-resolution scrolling, this code | ||
| 201 | will be emitted in addition to REL_WHEEL. The value is the (approximate) | ||
| 202 | distance travelled by the user's finger, in microns. | ||
| 203 | 194 | ||
| 204 | EV_ABS | 195 | EV_ABS |
| 205 | ------ | 196 | ------ |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index c0d668944dbe..ed35c9a9a110 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -275,6 +275,9 @@ | |||
| 275 | 275 | ||
| 276 | #define USB_VENDOR_ID_CIDC 0x1677 | 276 | #define USB_VENDOR_ID_CIDC 0x1677 |
| 277 | 277 | ||
| 278 | #define I2C_VENDOR_ID_CIRQUE 0x0488 | ||
| 279 | #define I2C_PRODUCT_ID_CIRQUE_121F 0x121F | ||
| 280 | |||
| 278 | #define USB_VENDOR_ID_CJTOUCH 0x24b8 | 281 | #define USB_VENDOR_ID_CJTOUCH 0x24b8 |
| 279 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020 | 282 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020 |
| 280 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040 | 283 | #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040 |
| @@ -707,6 +710,7 @@ | |||
| 707 | #define USB_VENDOR_ID_LG 0x1fd2 | 710 | #define USB_VENDOR_ID_LG 0x1fd2 |
| 708 | #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 | 711 | #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 |
| 709 | #define USB_DEVICE_ID_LG_MELFAS_MT 0x6007 | 712 | #define USB_DEVICE_ID_LG_MELFAS_MT 0x6007 |
| 713 | #define I2C_DEVICE_ID_LG_8001 0x8001 | ||
| 710 | 714 | ||
| 711 | #define USB_VENDOR_ID_LOGITECH 0x046d | 715 | #define USB_VENDOR_ID_LOGITECH 0x046d |
| 712 | #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e | 716 | #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e |
| @@ -805,6 +809,7 @@ | |||
| 805 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 | 809 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 |
| 806 | #define USB_DEVICE_ID_MS_POWER_COVER 0x07da | 810 | #define USB_DEVICE_ID_MS_POWER_COVER 0x07da |
| 807 | #define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd | 811 | #define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd |
| 812 | #define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb | ||
| 808 | 813 | ||
| 809 | #define USB_VENDOR_ID_MOJO 0x8282 | 814 | #define USB_VENDOR_ID_MOJO 0x8282 |
| 810 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 | 815 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 |
| @@ -1043,6 +1048,7 @@ | |||
| 1043 | #define USB_VENDOR_ID_SYMBOL 0x05e0 | 1048 | #define USB_VENDOR_ID_SYMBOL 0x05e0 |
| 1044 | #define USB_DEVICE_ID_SYMBOL_SCANNER_1 0x0800 | 1049 | #define USB_DEVICE_ID_SYMBOL_SCANNER_1 0x0800 |
| 1045 | #define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300 | 1050 | #define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300 |
| 1051 | #define USB_DEVICE_ID_SYMBOL_SCANNER_3 0x1200 | ||
| 1046 | 1052 | ||
| 1047 | #define USB_VENDOR_ID_SYNAPTICS 0x06cb | 1053 | #define USB_VENDOR_ID_SYNAPTICS 0x06cb |
| 1048 | #define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 | 1054 | #define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 |
| @@ -1204,6 +1210,8 @@ | |||
| 1204 | #define USB_DEVICE_ID_PRIMAX_MOUSE_4D22 0x4d22 | 1210 | #define USB_DEVICE_ID_PRIMAX_MOUSE_4D22 0x4d22 |
| 1205 | #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 | 1211 | #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 |
| 1206 | #define USB_DEVICE_ID_PRIMAX_REZEL 0x4e72 | 1212 | #define USB_DEVICE_ID_PRIMAX_REZEL 0x4e72 |
| 1213 | #define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F 0x4d0f | ||
| 1214 | #define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22 0x4e22 | ||
| 1207 | 1215 | ||
| 1208 | 1216 | ||
| 1209 | #define USB_VENDOR_ID_RISO_KAGAKU 0x1294 /* Riso Kagaku Corp. */ | 1217 | #define USB_VENDOR_ID_RISO_KAGAKU 0x1294 /* Riso Kagaku Corp. */ |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index a2f74e6adc70..d6fab5798487 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
| @@ -325,6 +325,9 @@ static const struct hid_device_id hid_battery_quirks[] = { | |||
| 325 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, | 325 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, |
| 326 | USB_DEVICE_ID_ELECOM_BM084), | 326 | USB_DEVICE_ID_ELECOM_BM084), |
| 327 | HID_BATTERY_QUIRK_IGNORE }, | 327 | HID_BATTERY_QUIRK_IGNORE }, |
| 328 | { HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL, | ||
| 329 | USB_DEVICE_ID_SYMBOL_SCANNER_3), | ||
| 330 | HID_BATTERY_QUIRK_IGNORE }, | ||
| 328 | {} | 331 | {} |
| 329 | }; | 332 | }; |
| 330 | 333 | ||
| @@ -1838,47 +1841,3 @@ void hidinput_disconnect(struct hid_device *hid) | |||
| 1838 | } | 1841 | } |
| 1839 | EXPORT_SYMBOL_GPL(hidinput_disconnect); | 1842 | EXPORT_SYMBOL_GPL(hidinput_disconnect); |
| 1840 | 1843 | ||
| 1841 | /** | ||
| 1842 | * hid_scroll_counter_handle_scroll() - Send high- and low-resolution scroll | ||
| 1843 | * events given a high-resolution wheel | ||
| 1844 | * movement. | ||
| 1845 | * @counter: a hid_scroll_counter struct describing the wheel. | ||
| 1846 | * @hi_res_value: the movement of the wheel, in the mouse's high-resolution | ||
| 1847 | * units. | ||
| 1848 | * | ||
| 1849 | * Given a high-resolution movement, this function converts the movement into | ||
| 1850 | * microns and emits high-resolution scroll events for the input device. It also | ||
| 1851 | * uses the multiplier from &struct hid_scroll_counter to emit low-resolution | ||
| 1852 | * scroll events when appropriate for backwards-compatibility with userspace | ||
| 1853 | * input libraries. | ||
| 1854 | */ | ||
| 1855 | void hid_scroll_counter_handle_scroll(struct hid_scroll_counter *counter, | ||
| 1856 | int hi_res_value) | ||
| 1857 | { | ||
| 1858 | int low_res_value, remainder, multiplier; | ||
| 1859 | |||
| 1860 | input_report_rel(counter->dev, REL_WHEEL_HI_RES, | ||
| 1861 | hi_res_value * counter->microns_per_hi_res_unit); | ||
| 1862 | |||
| 1863 | /* | ||
| 1864 | * Update the low-res remainder with the high-res value, | ||
| 1865 | * but reset if the direction has changed. | ||
| 1866 | */ | ||
| 1867 | remainder = counter->remainder; | ||
| 1868 | if ((remainder ^ hi_res_value) < 0) | ||
| 1869 | remainder = 0; | ||
| 1870 | remainder += hi_res_value; | ||
| 1871 | |||
| 1872 | /* | ||
| 1873 | * Then just use the resolution multiplier to see if | ||
| 1874 | * we should send a low-res (aka regular wheel) event. | ||
| 1875 | */ | ||
| 1876 | multiplier = counter->resolution_multiplier; | ||
| 1877 | low_res_value = remainder / multiplier; | ||
| 1878 | remainder -= low_res_value * multiplier; | ||
| 1879 | counter->remainder = remainder; | ||
| 1880 | |||
| 1881 | if (low_res_value) | ||
| 1882 | input_report_rel(counter->dev, REL_WHEEL, low_res_value); | ||
| 1883 | } | ||
| 1884 | EXPORT_SYMBOL_GPL(hid_scroll_counter_handle_scroll); | ||
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index f01280898b24..19cc980eebce 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c | |||
| @@ -64,14 +64,6 @@ MODULE_PARM_DESC(disable_tap_to_click, | |||
| 64 | #define HIDPP_QUIRK_NO_HIDINPUT BIT(23) | 64 | #define HIDPP_QUIRK_NO_HIDINPUT BIT(23) |
| 65 | #define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) | 65 | #define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) |
| 66 | #define HIDPP_QUIRK_UNIFYING BIT(25) | 66 | #define HIDPP_QUIRK_UNIFYING BIT(25) |
| 67 | #define HIDPP_QUIRK_HI_RES_SCROLL_1P0 BIT(26) | ||
| 68 | #define HIDPP_QUIRK_HI_RES_SCROLL_X2120 BIT(27) | ||
| 69 | #define HIDPP_QUIRK_HI_RES_SCROLL_X2121 BIT(28) | ||
| 70 | |||
| 71 | /* Convenience constant to check for any high-res support. */ | ||
| 72 | #define HIDPP_QUIRK_HI_RES_SCROLL (HIDPP_QUIRK_HI_RES_SCROLL_1P0 | \ | ||
| 73 | HIDPP_QUIRK_HI_RES_SCROLL_X2120 | \ | ||
| 74 | HIDPP_QUIRK_HI_RES_SCROLL_X2121) | ||
| 75 | 67 | ||
| 76 | #define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT | 68 | #define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT |
| 77 | 69 | ||
| @@ -157,7 +149,6 @@ struct hidpp_device { | |||
| 157 | unsigned long capabilities; | 149 | unsigned long capabilities; |
| 158 | 150 | ||
| 159 | struct hidpp_battery battery; | 151 | struct hidpp_battery battery; |
| 160 | struct hid_scroll_counter vertical_wheel_counter; | ||
| 161 | }; | 152 | }; |
| 162 | 153 | ||
| 163 | /* HID++ 1.0 error codes */ | 154 | /* HID++ 1.0 error codes */ |
| @@ -409,53 +400,32 @@ static void hidpp_prefix_name(char **name, int name_length) | |||
| 409 | #define HIDPP_SET_LONG_REGISTER 0x82 | 400 | #define HIDPP_SET_LONG_REGISTER 0x82 |
| 410 | #define HIDPP_GET_LONG_REGISTER 0x83 | 401 | #define HIDPP_GET_LONG_REGISTER 0x83 |
| 411 | 402 | ||
| 412 | /** | 403 | #define HIDPP_REG_GENERAL 0x00 |
| 413 | * hidpp10_set_register_bit() - Sets a single bit in a HID++ 1.0 register. | 404 | |
| 414 | * @hidpp_dev: the device to set the register on. | 405 | static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev) |
| 415 | * @register_address: the address of the register to modify. | ||
| 416 | * @byte: the byte of the register to modify. Should be less than 3. | ||
| 417 | * Return: 0 if successful, otherwise a negative error code. | ||
| 418 | */ | ||
| 419 | static int hidpp10_set_register_bit(struct hidpp_device *hidpp_dev, | ||
| 420 | u8 register_address, u8 byte, u8 bit) | ||
| 421 | { | 406 | { |
| 422 | struct hidpp_report response; | 407 | struct hidpp_report response; |
| 423 | int ret; | 408 | int ret; |
| 424 | u8 params[3] = { 0 }; | 409 | u8 params[3] = { 0 }; |
| 425 | 410 | ||
| 426 | ret = hidpp_send_rap_command_sync(hidpp_dev, | 411 | ret = hidpp_send_rap_command_sync(hidpp_dev, |
| 427 | REPORT_ID_HIDPP_SHORT, | 412 | REPORT_ID_HIDPP_SHORT, |
| 428 | HIDPP_GET_REGISTER, | 413 | HIDPP_GET_REGISTER, |
| 429 | register_address, | 414 | HIDPP_REG_GENERAL, |
| 430 | NULL, 0, &response); | 415 | NULL, 0, &response); |
| 431 | if (ret) | 416 | if (ret) |
| 432 | return ret; | 417 | return ret; |
| 433 | 418 | ||
| 434 | memcpy(params, response.rap.params, 3); | 419 | memcpy(params, response.rap.params, 3); |
| 435 | 420 | ||
| 436 | params[byte] |= BIT(bit); | 421 | /* Set the battery bit */ |
| 422 | params[0] |= BIT(4); | ||
| 437 | 423 | ||
| 438 | return hidpp_send_rap_command_sync(hidpp_dev, | 424 | return hidpp_send_rap_command_sync(hidpp_dev, |
| 439 | REPORT_ID_HIDPP_SHORT, | 425 | REPORT_ID_HIDPP_SHORT, |
| 440 | HIDPP_SET_REGISTER, | 426 | HIDPP_SET_REGISTER, |
| 441 | register_address, | 427 | HIDPP_REG_GENERAL, |
| 442 | params, 3, &response); | 428 | params, 3, &response); |
| 443 | } | ||
| 444 | |||
| 445 | |||
| 446 | #define HIDPP_REG_GENERAL 0x00 | ||
| 447 | |||
| 448 | static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev) | ||
| 449 | { | ||
| 450 | return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_GENERAL, 0, 4); | ||
| 451 | } | ||
| 452 | |||
| 453 | #define HIDPP_REG_FEATURES 0x01 | ||
| 454 | |||
| 455 | /* On HID++ 1.0 devices, high-res scroll was called "scrolling acceleration". */ | ||
| 456 | static int hidpp10_enable_scrolling_acceleration(struct hidpp_device *hidpp_dev) | ||
| 457 | { | ||
| 458 | return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_FEATURES, 0, 6); | ||
| 459 | } | 429 | } |
| 460 | 430 | ||
| 461 | #define HIDPP_REG_BATTERY_STATUS 0x07 | 431 | #define HIDPP_REG_BATTERY_STATUS 0x07 |
| @@ -1167,100 +1137,6 @@ static int hidpp_battery_get_property(struct power_supply *psy, | |||
| 1167 | } | 1137 | } |
| 1168 | 1138 | ||
| 1169 | /* -------------------------------------------------------------------------- */ | 1139 | /* -------------------------------------------------------------------------- */ |
| 1170 | /* 0x2120: Hi-resolution scrolling */ | ||
| 1171 | /* -------------------------------------------------------------------------- */ | ||
| 1172 | |||
| 1173 | #define HIDPP_PAGE_HI_RESOLUTION_SCROLLING 0x2120 | ||
| 1174 | |||
| 1175 | #define CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE 0x10 | ||
| 1176 | |||
| 1177 | static int hidpp_hrs_set_highres_scrolling_mode(struct hidpp_device *hidpp, | ||
| 1178 | bool enabled, u8 *multiplier) | ||
| 1179 | { | ||
| 1180 | u8 feature_index; | ||
| 1181 | u8 feature_type; | ||
| 1182 | int ret; | ||
| 1183 | u8 params[1]; | ||
| 1184 | struct hidpp_report response; | ||
| 1185 | |||
| 1186 | ret = hidpp_root_get_feature(hidpp, | ||
| 1187 | HIDPP_PAGE_HI_RESOLUTION_SCROLLING, | ||
| 1188 | &feature_index, | ||
| 1189 | &feature_type); | ||
| 1190 | if (ret) | ||
| 1191 | return ret; | ||
| 1192 | |||
| 1193 | params[0] = enabled ? BIT(0) : 0; | ||
| 1194 | ret = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
| 1195 | CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE, | ||
| 1196 | params, sizeof(params), &response); | ||
| 1197 | if (ret) | ||
| 1198 | return ret; | ||
| 1199 | *multiplier = response.fap.params[1]; | ||
| 1200 | return 0; | ||
| 1201 | } | ||
| 1202 | |||
| 1203 | /* -------------------------------------------------------------------------- */ | ||
| 1204 | /* 0x2121: HiRes Wheel */ | ||
| 1205 | /* -------------------------------------------------------------------------- */ | ||
| 1206 | |||
| 1207 | #define HIDPP_PAGE_HIRES_WHEEL 0x2121 | ||
| 1208 | |||
| 1209 | #define CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY 0x00 | ||
| 1210 | #define CMD_HIRES_WHEEL_SET_WHEEL_MODE 0x20 | ||
| 1211 | |||
| 1212 | static int hidpp_hrw_get_wheel_capability(struct hidpp_device *hidpp, | ||
| 1213 | u8 *multiplier) | ||
| 1214 | { | ||
| 1215 | u8 feature_index; | ||
| 1216 | u8 feature_type; | ||
| 1217 | int ret; | ||
| 1218 | struct hidpp_report response; | ||
| 1219 | |||
| 1220 | ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL, | ||
| 1221 | &feature_index, &feature_type); | ||
| 1222 | if (ret) | ||
| 1223 | goto return_default; | ||
| 1224 | |||
| 1225 | ret = hidpp_send_fap_command_sync(hidpp, feature_index, | ||
| 1226 | CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY, | ||
| 1227 | NULL, 0, &response); | ||
| 1228 | if (ret) | ||
| 1229 | goto return_default; | ||
| 1230 | |||
| 1231 | *multiplier = response.fap.params[0]; | ||
| 1232 | return 0; | ||
| 1233 | return_default: | ||
| 1234 | hid_warn(hidpp->hid_dev, | ||
| 1235 | "Couldn't get wheel multiplier (error %d), assuming %d.\n", | ||
| 1236 | ret, *multiplier); | ||
| 1237 | return ret; | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | static int hidpp_hrw_set_wheel_mode(struct hidpp_device *hidpp, bool invert, | ||
| 1241 | bool high_resolution, bool use_hidpp) | ||
| 1242 | { | ||
| 1243 | u8 feature_index; | ||
| 1244 | u8 feature_type; | ||
| 1245 | int ret; | ||
| 1246 | u8 params[1]; | ||
| 1247 | struct hidpp_report response; | ||
| 1248 | |||
| 1249 | ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL, | ||
| 1250 | &feature_index, &feature_type); | ||
| 1251 | if (ret) | ||
| 1252 | return ret; | ||
| 1253 | |||
| 1254 | params[0] = (invert ? BIT(2) : 0) | | ||
| 1255 | (high_resolution ? BIT(1) : 0) | | ||
| 1256 | (use_hidpp ? BIT(0) : 0); | ||
| 1257 | |||
| 1258 | return hidpp_send_fap_command_sync(hidpp, feature_index, | ||
| 1259 | CMD_HIRES_WHEEL_SET_WHEEL_MODE, | ||
| 1260 | params, sizeof(params), &response); | ||
| 1261 | } | ||
| 1262 | |||
| 1263 | /* -------------------------------------------------------------------------- */ | ||
| 1264 | /* 0x4301: Solar Keyboard */ | 1140 | /* 0x4301: Solar Keyboard */ |
| 1265 | /* -------------------------------------------------------------------------- */ | 1141 | /* -------------------------------------------------------------------------- */ |
| 1266 | 1142 | ||
| @@ -2523,8 +2399,7 @@ static int m560_raw_event(struct hid_device *hdev, u8 *data, int size) | |||
| 2523 | input_report_rel(mydata->input, REL_Y, v); | 2399 | input_report_rel(mydata->input, REL_Y, v); |
| 2524 | 2400 | ||
| 2525 | v = hid_snto32(data[6], 8); | 2401 | v = hid_snto32(data[6], 8); |
| 2526 | hid_scroll_counter_handle_scroll( | 2402 | input_report_rel(mydata->input, REL_WHEEL, v); |
| 2527 | &hidpp->vertical_wheel_counter, v); | ||
| 2528 | 2403 | ||
| 2529 | input_sync(mydata->input); | 2404 | input_sync(mydata->input); |
| 2530 | } | 2405 | } |
| @@ -2653,72 +2528,6 @@ static int g920_get_config(struct hidpp_device *hidpp) | |||
| 2653 | } | 2528 | } |
| 2654 | 2529 | ||
| 2655 | /* -------------------------------------------------------------------------- */ | 2530 | /* -------------------------------------------------------------------------- */ |
| 2656 | /* High-resolution scroll wheels */ | ||
| 2657 | /* -------------------------------------------------------------------------- */ | ||
| 2658 | |||
| 2659 | /** | ||
| 2660 | * struct hi_res_scroll_info - Stores info on a device's high-res scroll wheel. | ||
| 2661 | * @product_id: the HID product ID of the device being described. | ||
| 2662 | * @microns_per_hi_res_unit: the distance moved by the user's finger for each | ||
| 2663 | * high-resolution unit reported by the device, in | ||
| 2664 | * 256ths of a millimetre. | ||
| 2665 | */ | ||
| 2666 | struct hi_res_scroll_info { | ||
| 2667 | __u32 product_id; | ||
| 2668 | int microns_per_hi_res_unit; | ||
| 2669 | }; | ||
| 2670 | |||
| 2671 | static struct hi_res_scroll_info hi_res_scroll_devices[] = { | ||
| 2672 | { /* Anywhere MX */ | ||
| 2673 | .product_id = 0x1017, .microns_per_hi_res_unit = 445 }, | ||
| 2674 | { /* Performance MX */ | ||
| 2675 | .product_id = 0x101a, .microns_per_hi_res_unit = 406 }, | ||
| 2676 | { /* M560 */ | ||
| 2677 | .product_id = 0x402d, .microns_per_hi_res_unit = 435 }, | ||
| 2678 | { /* MX Master 2S */ | ||
| 2679 | .product_id = 0x4069, .microns_per_hi_res_unit = 406 }, | ||
| 2680 | }; | ||
| 2681 | |||
| 2682 | static int hi_res_scroll_look_up_microns(__u32 product_id) | ||
| 2683 | { | ||
| 2684 | int i; | ||
| 2685 | int num_devices = sizeof(hi_res_scroll_devices) | ||
| 2686 | / sizeof(hi_res_scroll_devices[0]); | ||
| 2687 | for (i = 0; i < num_devices; i++) { | ||
| 2688 | if (hi_res_scroll_devices[i].product_id == product_id) | ||
| 2689 | return hi_res_scroll_devices[i].microns_per_hi_res_unit; | ||
| 2690 | } | ||
| 2691 | /* We don't have a value for this device, so use a sensible default. */ | ||
| 2692 | return 406; | ||
| 2693 | } | ||
| 2694 | |||
| 2695 | static int hi_res_scroll_enable(struct hidpp_device *hidpp) | ||
| 2696 | { | ||
| 2697 | int ret; | ||
| 2698 | u8 multiplier = 8; | ||
| 2699 | |||
| 2700 | if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2121) { | ||
| 2701 | ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, false); | ||
| 2702 | hidpp_hrw_get_wheel_capability(hidpp, &multiplier); | ||
| 2703 | } else if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2120) { | ||
| 2704 | ret = hidpp_hrs_set_highres_scrolling_mode(hidpp, true, | ||
| 2705 | &multiplier); | ||
| 2706 | } else /* if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0) */ | ||
| 2707 | ret = hidpp10_enable_scrolling_acceleration(hidpp); | ||
| 2708 | |||
| 2709 | if (ret) | ||
| 2710 | return ret; | ||
| 2711 | |||
| 2712 | hidpp->vertical_wheel_counter.resolution_multiplier = multiplier; | ||
| 2713 | hidpp->vertical_wheel_counter.microns_per_hi_res_unit = | ||
| 2714 | hi_res_scroll_look_up_microns(hidpp->hid_dev->product); | ||
| 2715 | hid_info(hidpp->hid_dev, "multiplier = %d, microns = %d\n", | ||
| 2716 | multiplier, | ||
| 2717 | hidpp->vertical_wheel_counter.microns_per_hi_res_unit); | ||
| 2718 | return 0; | ||
| 2719 | } | ||
| 2720 | |||
| 2721 | /* -------------------------------------------------------------------------- */ | ||
| 2722 | /* Generic HID++ devices */ | 2531 | /* Generic HID++ devices */ |
| 2723 | /* -------------------------------------------------------------------------- */ | 2532 | /* -------------------------------------------------------------------------- */ |
| 2724 | 2533 | ||
| @@ -2763,11 +2572,6 @@ static void hidpp_populate_input(struct hidpp_device *hidpp, | |||
| 2763 | wtp_populate_input(hidpp, input, origin_is_hid_core); | 2572 | wtp_populate_input(hidpp, input, origin_is_hid_core); |
| 2764 | else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) | 2573 | else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) |
| 2765 | m560_populate_input(hidpp, input, origin_is_hid_core); | 2574 | m560_populate_input(hidpp, input, origin_is_hid_core); |
| 2766 | |||
| 2767 | if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) { | ||
| 2768 | input_set_capability(input, EV_REL, REL_WHEEL_HI_RES); | ||
| 2769 | hidpp->vertical_wheel_counter.dev = input; | ||
| 2770 | } | ||
| 2771 | } | 2575 | } |
| 2772 | 2576 | ||
| 2773 | static int hidpp_input_configured(struct hid_device *hdev, | 2577 | static int hidpp_input_configured(struct hid_device *hdev, |
| @@ -2886,27 +2690,6 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
| 2886 | return 0; | 2690 | return 0; |
| 2887 | } | 2691 | } |
| 2888 | 2692 | ||
| 2889 | static int hidpp_event(struct hid_device *hdev, struct hid_field *field, | ||
| 2890 | struct hid_usage *usage, __s32 value) | ||
| 2891 | { | ||
| 2892 | /* This function will only be called for scroll events, due to the | ||
| 2893 | * restriction imposed in hidpp_usages. | ||
| 2894 | */ | ||
| 2895 | struct hidpp_device *hidpp = hid_get_drvdata(hdev); | ||
| 2896 | struct hid_scroll_counter *counter = &hidpp->vertical_wheel_counter; | ||
| 2897 | /* A scroll event may occur before the multiplier has been retrieved or | ||
| 2898 | * the input device set, or high-res scroll enabling may fail. In such | ||
| 2899 | * cases we must return early (falling back to default behaviour) to | ||
| 2900 | * avoid a crash in hid_scroll_counter_handle_scroll. | ||
| 2901 | */ | ||
| 2902 | if (!(hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) || value == 0 | ||
| 2903 | || counter->dev == NULL || counter->resolution_multiplier == 0) | ||
| 2904 | return 0; | ||
| 2905 | |||
| 2906 | hid_scroll_counter_handle_scroll(counter, value); | ||
| 2907 | return 1; | ||
| 2908 | } | ||
| 2909 | |||
| 2910 | static int hidpp_initialize_battery(struct hidpp_device *hidpp) | 2693 | static int hidpp_initialize_battery(struct hidpp_device *hidpp) |
| 2911 | { | 2694 | { |
| 2912 | static atomic_t battery_no = ATOMIC_INIT(0); | 2695 | static atomic_t battery_no = ATOMIC_INIT(0); |
| @@ -3118,9 +2901,6 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) | |||
| 3118 | if (hidpp->battery.ps) | 2901 | if (hidpp->battery.ps) |
| 3119 | power_supply_changed(hidpp->battery.ps); | 2902 | power_supply_changed(hidpp->battery.ps); |
| 3120 | 2903 | ||
| 3121 | if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) | ||
| 3122 | hi_res_scroll_enable(hidpp); | ||
| 3123 | |||
| 3124 | if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input) | 2904 | if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input) |
| 3125 | /* if the input nodes are already created, we can stop now */ | 2905 | /* if the input nodes are already created, we can stop now */ |
| 3126 | return; | 2906 | return; |
| @@ -3306,63 +3086,35 @@ static void hidpp_remove(struct hid_device *hdev) | |||
| 3306 | mutex_destroy(&hidpp->send_mutex); | 3086 | mutex_destroy(&hidpp->send_mutex); |
| 3307 | } | 3087 | } |
| 3308 | 3088 | ||
| 3309 | #define LDJ_DEVICE(product) \ | ||
| 3310 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, \ | ||
| 3311 | USB_VENDOR_ID_LOGITECH, (product)) | ||
| 3312 | |||
| 3313 | static const struct hid_device_id hidpp_devices[] = { | 3089 | static const struct hid_device_id hidpp_devices[] = { |
| 3314 | { /* wireless touchpad */ | 3090 | { /* wireless touchpad */ |
| 3315 | LDJ_DEVICE(0x4011), | 3091 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
| 3092 | USB_VENDOR_ID_LOGITECH, 0x4011), | ||
| 3316 | .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT | | 3093 | .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT | |
| 3317 | HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS }, | 3094 | HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS }, |
| 3318 | { /* wireless touchpad T650 */ | 3095 | { /* wireless touchpad T650 */ |
| 3319 | LDJ_DEVICE(0x4101), | 3096 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
| 3097 | USB_VENDOR_ID_LOGITECH, 0x4101), | ||
| 3320 | .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT }, | 3098 | .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT }, |
| 3321 | { /* wireless touchpad T651 */ | 3099 | { /* wireless touchpad T651 */ |
| 3322 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, | 3100 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, |
| 3323 | USB_DEVICE_ID_LOGITECH_T651), | 3101 | USB_DEVICE_ID_LOGITECH_T651), |
| 3324 | .driver_data = HIDPP_QUIRK_CLASS_WTP }, | 3102 | .driver_data = HIDPP_QUIRK_CLASS_WTP }, |
| 3325 | { /* Mouse Logitech Anywhere MX */ | ||
| 3326 | LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 }, | ||
| 3327 | { /* Mouse Logitech Cube */ | ||
| 3328 | LDJ_DEVICE(0x4010), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 }, | ||
| 3329 | { /* Mouse Logitech M335 */ | ||
| 3330 | LDJ_DEVICE(0x4050), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
| 3331 | { /* Mouse Logitech M515 */ | ||
| 3332 | LDJ_DEVICE(0x4007), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 }, | ||
| 3333 | { /* Mouse logitech M560 */ | 3103 | { /* Mouse logitech M560 */ |
| 3334 | LDJ_DEVICE(0x402d), | 3104 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
| 3335 | .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 | 3105 | USB_VENDOR_ID_LOGITECH, 0x402d), |
| 3336 | | HIDPP_QUIRK_HI_RES_SCROLL_X2120 }, | 3106 | .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 }, |
| 3337 | { /* Mouse Logitech M705 (firmware RQM17) */ | ||
| 3338 | LDJ_DEVICE(0x101b), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 }, | ||
| 3339 | { /* Mouse Logitech M705 (firmware RQM67) */ | ||
| 3340 | LDJ_DEVICE(0x406d), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
| 3341 | { /* Mouse Logitech M720 */ | ||
| 3342 | LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
| 3343 | { /* Mouse Logitech MX Anywhere 2 */ | ||
| 3344 | LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
| 3345 | { LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
| 3346 | { LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
| 3347 | { LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
| 3348 | { /* Mouse Logitech MX Anywhere 2S */ | ||
| 3349 | LDJ_DEVICE(0x406a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
| 3350 | { /* Mouse Logitech MX Master */ | ||
| 3351 | LDJ_DEVICE(0x4041), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
| 3352 | { LDJ_DEVICE(0x4060), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
| 3353 | { LDJ_DEVICE(0x4071), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
| 3354 | { /* Mouse Logitech MX Master 2S */ | ||
| 3355 | LDJ_DEVICE(0x4069), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, | ||
| 3356 | { /* Mouse Logitech Performance MX */ | ||
| 3357 | LDJ_DEVICE(0x101a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 }, | ||
| 3358 | { /* Keyboard logitech K400 */ | 3107 | { /* Keyboard logitech K400 */ |
| 3359 | LDJ_DEVICE(0x4024), | 3108 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
| 3109 | USB_VENDOR_ID_LOGITECH, 0x4024), | ||
| 3360 | .driver_data = HIDPP_QUIRK_CLASS_K400 }, | 3110 | .driver_data = HIDPP_QUIRK_CLASS_K400 }, |
| 3361 | { /* Solar Keyboard Logitech K750 */ | 3111 | { /* Solar Keyboard Logitech K750 */ |
| 3362 | LDJ_DEVICE(0x4002), | 3112 | HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
| 3113 | USB_VENDOR_ID_LOGITECH, 0x4002), | ||
| 3363 | .driver_data = HIDPP_QUIRK_CLASS_K750 }, | 3114 | .driver_data = HIDPP_QUIRK_CLASS_K750 }, |
| 3364 | 3115 | ||
| 3365 | { LDJ_DEVICE(HID_ANY_ID) }, | 3116 | { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, |
| 3117 | USB_VENDOR_ID_LOGITECH, HID_ANY_ID)}, | ||
| 3366 | 3118 | ||
| 3367 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL), | 3119 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL), |
| 3368 | .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS}, | 3120 | .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS}, |
| @@ -3371,19 +3123,12 @@ static const struct hid_device_id hidpp_devices[] = { | |||
| 3371 | 3123 | ||
| 3372 | MODULE_DEVICE_TABLE(hid, hidpp_devices); | 3124 | MODULE_DEVICE_TABLE(hid, hidpp_devices); |
| 3373 | 3125 | ||
| 3374 | static const struct hid_usage_id hidpp_usages[] = { | ||
| 3375 | { HID_GD_WHEEL, EV_REL, REL_WHEEL }, | ||
| 3376 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} | ||
| 3377 | }; | ||
| 3378 | |||
| 3379 | static struct hid_driver hidpp_driver = { | 3126 | static struct hid_driver hidpp_driver = { |
| 3380 | .name = "logitech-hidpp-device", | 3127 | .name = "logitech-hidpp-device", |
| 3381 | .id_table = hidpp_devices, | 3128 | .id_table = hidpp_devices, |
| 3382 | .probe = hidpp_probe, | 3129 | .probe = hidpp_probe, |
| 3383 | .remove = hidpp_remove, | 3130 | .remove = hidpp_remove, |
| 3384 | .raw_event = hidpp_raw_event, | 3131 | .raw_event = hidpp_raw_event, |
| 3385 | .usage_table = hidpp_usages, | ||
| 3386 | .event = hidpp_event, | ||
| 3387 | .input_configured = hidpp_input_configured, | 3132 | .input_configured = hidpp_input_configured, |
| 3388 | .input_mapping = hidpp_input_mapping, | 3133 | .input_mapping = hidpp_input_mapping, |
| 3389 | .input_mapped = hidpp_input_mapped, | 3134 | .input_mapped = hidpp_input_mapped, |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index f7c6de2b6730..dca0a3a90fb8 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
| @@ -1814,6 +1814,12 @@ static const struct hid_device_id mt_devices[] = { | |||
| 1814 | MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, | 1814 | MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, |
| 1815 | USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, | 1815 | USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, |
| 1816 | 1816 | ||
| 1817 | /* Cirque devices */ | ||
| 1818 | { .driver_data = MT_CLS_WIN_8_DUAL, | ||
| 1819 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, | ||
| 1820 | I2C_VENDOR_ID_CIRQUE, | ||
| 1821 | I2C_PRODUCT_ID_CIRQUE_121F) }, | ||
| 1822 | |||
| 1817 | /* CJTouch panels */ | 1823 | /* CJTouch panels */ |
| 1818 | { .driver_data = MT_CLS_NSMU, | 1824 | { .driver_data = MT_CLS_NSMU, |
| 1819 | MT_USB_DEVICE(USB_VENDOR_ID_CJTOUCH, | 1825 | MT_USB_DEVICE(USB_VENDOR_ID_CJTOUCH, |
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 8237dd86fb17..c85a79986b6a 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c | |||
| @@ -107,6 +107,7 @@ static const struct hid_device_id hid_quirks[] = { | |||
| 107 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL }, | 107 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL }, |
| 108 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL }, | 108 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL }, |
| 109 | { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT }, | 109 | { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT }, |
| 110 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE), HID_QUIRK_ALWAYS_POLL }, | ||
| 110 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS }, | 111 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS }, |
| 111 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS }, | 112 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS }, |
| 112 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, | 113 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, |
| @@ -129,6 +130,8 @@ static const struct hid_device_id hid_quirks[] = { | |||
| 129 | { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN), HID_QUIRK_NO_INIT_REPORTS }, | 130 | { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN), HID_QUIRK_NO_INIT_REPORTS }, |
| 130 | { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, | 131 | { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, |
| 131 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL }, | 132 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL }, |
| 133 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F), HID_QUIRK_ALWAYS_POLL }, | ||
| 134 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22), HID_QUIRK_ALWAYS_POLL }, | ||
| 132 | { HID_USB_DEVICE(USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS), HID_QUIRK_NOGET }, | 135 | { HID_USB_DEVICE(USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS), HID_QUIRK_NOGET }, |
| 133 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001), HID_QUIRK_NOGET }, | 136 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001), HID_QUIRK_NOGET }, |
| 134 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003), HID_QUIRK_NOGET }, | 137 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003), HID_QUIRK_NOGET }, |
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c index 0422ec2b13d2..dc4128bfe2ca 100644 --- a/drivers/hid/hid-steam.c +++ b/drivers/hid/hid-steam.c | |||
| @@ -23,8 +23,9 @@ | |||
| 23 | * In order to avoid breaking them this driver creates a layered hidraw device, | 23 | * In order to avoid breaking them this driver creates a layered hidraw device, |
| 24 | * so it can detect when the client is running and then: | 24 | * so it can detect when the client is running and then: |
| 25 | * - it will not send any command to the controller. | 25 | * - it will not send any command to the controller. |
| 26 | * - this input device will be disabled, to avoid double input of the same | 26 | * - this input device will be removed, to avoid double input of the same |
| 27 | * user action. | 27 | * user action. |
| 28 | * When the client is closed, this input device will be created again. | ||
| 28 | * | 29 | * |
| 29 | * For additional functions, such as changing the right-pad margin or switching | 30 | * For additional functions, such as changing the right-pad margin or switching |
| 30 | * the led, you can use the user-space tool at: | 31 | * the led, you can use the user-space tool at: |
| @@ -113,7 +114,7 @@ struct steam_device { | |||
| 113 | spinlock_t lock; | 114 | spinlock_t lock; |
| 114 | struct hid_device *hdev, *client_hdev; | 115 | struct hid_device *hdev, *client_hdev; |
| 115 | struct mutex mutex; | 116 | struct mutex mutex; |
| 116 | bool client_opened, input_opened; | 117 | bool client_opened; |
| 117 | struct input_dev __rcu *input; | 118 | struct input_dev __rcu *input; |
| 118 | unsigned long quirks; | 119 | unsigned long quirks; |
| 119 | struct work_struct work_connect; | 120 | struct work_struct work_connect; |
| @@ -279,18 +280,6 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable) | |||
| 279 | } | 280 | } |
| 280 | } | 281 | } |
| 281 | 282 | ||
| 282 | static void steam_update_lizard_mode(struct steam_device *steam) | ||
| 283 | { | ||
| 284 | mutex_lock(&steam->mutex); | ||
| 285 | if (!steam->client_opened) { | ||
| 286 | if (steam->input_opened) | ||
| 287 | steam_set_lizard_mode(steam, false); | ||
| 288 | else | ||
| 289 | steam_set_lizard_mode(steam, lizard_mode); | ||
| 290 | } | ||
| 291 | mutex_unlock(&steam->mutex); | ||
| 292 | } | ||
| 293 | |||
| 294 | static int steam_input_open(struct input_dev *dev) | 283 | static int steam_input_open(struct input_dev *dev) |
| 295 | { | 284 | { |
| 296 | struct steam_device *steam = input_get_drvdata(dev); | 285 | struct steam_device *steam = input_get_drvdata(dev); |
| @@ -301,7 +290,6 @@ static int steam_input_open(struct input_dev *dev) | |||
| 301 | return ret; | 290 | return ret; |
| 302 | 291 | ||
| 303 | mutex_lock(&steam->mutex); | 292 | mutex_lock(&steam->mutex); |
| 304 | steam->input_opened = true; | ||
| 305 | if (!steam->client_opened && lizard_mode) | 293 | if (!steam->client_opened && lizard_mode) |
| 306 | steam_set_lizard_mode(steam, false); | 294 | steam_set_lizard_mode(steam, false); |
| 307 | mutex_unlock(&steam->mutex); | 295 | mutex_unlock(&steam->mutex); |
| @@ -313,7 +301,6 @@ static void steam_input_close(struct input_dev *dev) | |||
| 313 | struct steam_device *steam = input_get_drvdata(dev); | 301 | struct steam_device *steam = input_get_drvdata(dev); |
| 314 | 302 | ||
| 315 | mutex_lock(&steam->mutex); | 303 | mutex_lock(&steam->mutex); |
| 316 | steam->input_opened = false; | ||
| 317 | if (!steam->client_opened && lizard_mode) | 304 | if (!steam->client_opened && lizard_mode) |
| 318 | steam_set_lizard_mode(steam, true); | 305 | steam_set_lizard_mode(steam, true); |
| 319 | mutex_unlock(&steam->mutex); | 306 | mutex_unlock(&steam->mutex); |
| @@ -400,7 +387,7 @@ static int steam_battery_register(struct steam_device *steam) | |||
| 400 | return 0; | 387 | return 0; |
| 401 | } | 388 | } |
| 402 | 389 | ||
| 403 | static int steam_register(struct steam_device *steam) | 390 | static int steam_input_register(struct steam_device *steam) |
| 404 | { | 391 | { |
| 405 | struct hid_device *hdev = steam->hdev; | 392 | struct hid_device *hdev = steam->hdev; |
| 406 | struct input_dev *input; | 393 | struct input_dev *input; |
| @@ -414,17 +401,6 @@ static int steam_register(struct steam_device *steam) | |||
| 414 | return 0; | 401 | return 0; |
| 415 | } | 402 | } |
| 416 | 403 | ||
| 417 | /* | ||
| 418 | * Unlikely, but getting the serial could fail, and it is not so | ||
| 419 | * important, so make up a serial number and go on. | ||
| 420 | */ | ||
| 421 | if (steam_get_serial(steam) < 0) | ||
| 422 | strlcpy(steam->serial_no, "XXXXXXXXXX", | ||
| 423 | sizeof(steam->serial_no)); | ||
| 424 | |||
| 425 | hid_info(hdev, "Steam Controller '%s' connected", | ||
| 426 | steam->serial_no); | ||
| 427 | |||
| 428 | input = input_allocate_device(); | 404 | input = input_allocate_device(); |
| 429 | if (!input) | 405 | if (!input) |
| 430 | return -ENOMEM; | 406 | return -ENOMEM; |
| @@ -492,11 +468,6 @@ static int steam_register(struct steam_device *steam) | |||
| 492 | goto input_register_fail; | 468 | goto input_register_fail; |
| 493 | 469 | ||
| 494 | rcu_assign_pointer(steam->input, input); | 470 | rcu_assign_pointer(steam->input, input); |
| 495 | |||
| 496 | /* ignore battery errors, we can live without it */ | ||
| 497 | if (steam->quirks & STEAM_QUIRK_WIRELESS) | ||
| 498 | steam_battery_register(steam); | ||
| 499 | |||
| 500 | return 0; | 471 | return 0; |
| 501 | 472 | ||
| 502 | input_register_fail: | 473 | input_register_fail: |
| @@ -504,27 +475,88 @@ input_register_fail: | |||
| 504 | return ret; | 475 | return ret; |
| 505 | } | 476 | } |
| 506 | 477 | ||
| 507 | static void steam_unregister(struct steam_device *steam) | 478 | static void steam_input_unregister(struct steam_device *steam) |
| 508 | { | 479 | { |
| 509 | struct input_dev *input; | 480 | struct input_dev *input; |
| 481 | rcu_read_lock(); | ||
| 482 | input = rcu_dereference(steam->input); | ||
| 483 | rcu_read_unlock(); | ||
| 484 | if (!input) | ||
| 485 | return; | ||
| 486 | RCU_INIT_POINTER(steam->input, NULL); | ||
| 487 | synchronize_rcu(); | ||
| 488 | input_unregister_device(input); | ||
| 489 | } | ||
| 490 | |||
| 491 | static void steam_battery_unregister(struct steam_device *steam) | ||
| 492 | { | ||
| 510 | struct power_supply *battery; | 493 | struct power_supply *battery; |
| 511 | 494 | ||
| 512 | rcu_read_lock(); | 495 | rcu_read_lock(); |
| 513 | input = rcu_dereference(steam->input); | ||
| 514 | battery = rcu_dereference(steam->battery); | 496 | battery = rcu_dereference(steam->battery); |
| 515 | rcu_read_unlock(); | 497 | rcu_read_unlock(); |
| 516 | 498 | ||
| 517 | if (battery) { | 499 | if (!battery) |
| 518 | RCU_INIT_POINTER(steam->battery, NULL); | 500 | return; |
| 519 | synchronize_rcu(); | 501 | RCU_INIT_POINTER(steam->battery, NULL); |
| 520 | power_supply_unregister(battery); | 502 | synchronize_rcu(); |
| 503 | power_supply_unregister(battery); | ||
| 504 | } | ||
| 505 | |||
| 506 | static int steam_register(struct steam_device *steam) | ||
| 507 | { | ||
| 508 | int ret; | ||
| 509 | |||
| 510 | /* | ||
| 511 | * This function can be called several times in a row with the | ||
| 512 | * wireless adaptor, without steam_unregister() between them, because | ||
| 513 | * another client send a get_connection_status command, for example. | ||
| 514 | * The battery and serial number are set just once per device. | ||
| 515 | */ | ||
| 516 | if (!steam->serial_no[0]) { | ||
| 517 | /* | ||
| 518 | * Unlikely, but getting the serial could fail, and it is not so | ||
| 519 | * important, so make up a serial number and go on. | ||
| 520 | */ | ||
| 521 | if (steam_get_serial(steam) < 0) | ||
| 522 | strlcpy(steam->serial_no, "XXXXXXXXXX", | ||
| 523 | sizeof(steam->serial_no)); | ||
| 524 | |||
| 525 | hid_info(steam->hdev, "Steam Controller '%s' connected", | ||
| 526 | steam->serial_no); | ||
| 527 | |||
| 528 | /* ignore battery errors, we can live without it */ | ||
| 529 | if (steam->quirks & STEAM_QUIRK_WIRELESS) | ||
| 530 | steam_battery_register(steam); | ||
| 531 | |||
| 532 | mutex_lock(&steam_devices_lock); | ||
| 533 | list_add(&steam->list, &steam_devices); | ||
| 534 | mutex_unlock(&steam_devices_lock); | ||
| 521 | } | 535 | } |
| 522 | if (input) { | 536 | |
| 523 | RCU_INIT_POINTER(steam->input, NULL); | 537 | mutex_lock(&steam->mutex); |
| 524 | synchronize_rcu(); | 538 | if (!steam->client_opened) { |
| 539 | steam_set_lizard_mode(steam, lizard_mode); | ||
| 540 | ret = steam_input_register(steam); | ||
| 541 | } else { | ||
| 542 | ret = 0; | ||
| 543 | } | ||
| 544 | mutex_unlock(&steam->mutex); | ||
| 545 | |||
| 546 | return ret; | ||
| 547 | } | ||
| 548 | |||
| 549 | static void steam_unregister(struct steam_device *steam) | ||
| 550 | { | ||
| 551 | steam_battery_unregister(steam); | ||
| 552 | steam_input_unregister(steam); | ||
| 553 | if (steam->serial_no[0]) { | ||
| 525 | hid_info(steam->hdev, "Steam Controller '%s' disconnected", | 554 | hid_info(steam->hdev, "Steam Controller '%s' disconnected", |
| 526 | steam->serial_no); | 555 | steam->serial_no); |
| 527 | input_unregister_device(input); | 556 | mutex_lock(&steam_devices_lock); |
| 557 | list_del(&steam->list); | ||
| 558 | mutex_unlock(&steam_devices_lock); | ||
| 559 | steam->serial_no[0] = 0; | ||
| 528 | } | 560 | } |
| 529 | } | 561 | } |
| 530 | 562 | ||
| @@ -600,6 +632,9 @@ static int steam_client_ll_open(struct hid_device *hdev) | |||
| 600 | mutex_lock(&steam->mutex); | 632 | mutex_lock(&steam->mutex); |
| 601 | steam->client_opened = true; | 633 | steam->client_opened = true; |
| 602 | mutex_unlock(&steam->mutex); | 634 | mutex_unlock(&steam->mutex); |
| 635 | |||
| 636 | steam_input_unregister(steam); | ||
| 637 | |||
| 603 | return ret; | 638 | return ret; |
| 604 | } | 639 | } |
| 605 | 640 | ||
| @@ -609,13 +644,13 @@ static void steam_client_ll_close(struct hid_device *hdev) | |||
| 609 | 644 | ||
| 610 | mutex_lock(&steam->mutex); | 645 | mutex_lock(&steam->mutex); |
| 611 | steam->client_opened = false; | 646 | steam->client_opened = false; |
| 612 | if (steam->input_opened) | ||
| 613 | steam_set_lizard_mode(steam, false); | ||
| 614 | else | ||
| 615 | steam_set_lizard_mode(steam, lizard_mode); | ||
| 616 | mutex_unlock(&steam->mutex); | 647 | mutex_unlock(&steam->mutex); |
| 617 | 648 | ||
| 618 | hid_hw_close(steam->hdev); | 649 | hid_hw_close(steam->hdev); |
| 650 | if (steam->connected) { | ||
| 651 | steam_set_lizard_mode(steam, lizard_mode); | ||
| 652 | steam_input_register(steam); | ||
| 653 | } | ||
| 619 | } | 654 | } |
| 620 | 655 | ||
| 621 | static int steam_client_ll_raw_request(struct hid_device *hdev, | 656 | static int steam_client_ll_raw_request(struct hid_device *hdev, |
| @@ -744,11 +779,6 @@ static int steam_probe(struct hid_device *hdev, | |||
| 744 | } | 779 | } |
| 745 | } | 780 | } |
| 746 | 781 | ||
| 747 | mutex_lock(&steam_devices_lock); | ||
| 748 | steam_update_lizard_mode(steam); | ||
| 749 | list_add(&steam->list, &steam_devices); | ||
| 750 | mutex_unlock(&steam_devices_lock); | ||
| 751 | |||
| 752 | return 0; | 782 | return 0; |
| 753 | 783 | ||
| 754 | hid_hw_open_fail: | 784 | hid_hw_open_fail: |
| @@ -774,10 +804,6 @@ static void steam_remove(struct hid_device *hdev) | |||
| 774 | return; | 804 | return; |
| 775 | } | 805 | } |
| 776 | 806 | ||
| 777 | mutex_lock(&steam_devices_lock); | ||
| 778 | list_del(&steam->list); | ||
| 779 | mutex_unlock(&steam_devices_lock); | ||
| 780 | |||
| 781 | hid_destroy_device(steam->client_hdev); | 807 | hid_destroy_device(steam->client_hdev); |
| 782 | steam->client_opened = false; | 808 | steam->client_opened = false; |
| 783 | cancel_work_sync(&steam->work_connect); | 809 | cancel_work_sync(&steam->work_connect); |
| @@ -792,12 +818,14 @@ static void steam_remove(struct hid_device *hdev) | |||
| 792 | static void steam_do_connect_event(struct steam_device *steam, bool connected) | 818 | static void steam_do_connect_event(struct steam_device *steam, bool connected) |
| 793 | { | 819 | { |
| 794 | unsigned long flags; | 820 | unsigned long flags; |
| 821 | bool changed; | ||
| 795 | 822 | ||
| 796 | spin_lock_irqsave(&steam->lock, flags); | 823 | spin_lock_irqsave(&steam->lock, flags); |
| 824 | changed = steam->connected != connected; | ||
| 797 | steam->connected = connected; | 825 | steam->connected = connected; |
| 798 | spin_unlock_irqrestore(&steam->lock, flags); | 826 | spin_unlock_irqrestore(&steam->lock, flags); |
| 799 | 827 | ||
| 800 | if (schedule_work(&steam->work_connect) == 0) | 828 | if (changed && schedule_work(&steam->work_connect) == 0) |
| 801 | dbg_hid("%s: connected=%d event already queued\n", | 829 | dbg_hid("%s: connected=%d event already queued\n", |
| 802 | __func__, connected); | 830 | __func__, connected); |
| 803 | } | 831 | } |
| @@ -1019,13 +1047,8 @@ static int steam_raw_event(struct hid_device *hdev, | |||
| 1019 | return 0; | 1047 | return 0; |
| 1020 | rcu_read_lock(); | 1048 | rcu_read_lock(); |
| 1021 | input = rcu_dereference(steam->input); | 1049 | input = rcu_dereference(steam->input); |
| 1022 | if (likely(input)) { | 1050 | if (likely(input)) |
| 1023 | steam_do_input_event(steam, input, data); | 1051 | steam_do_input_event(steam, input, data); |
| 1024 | } else { | ||
| 1025 | dbg_hid("%s: input data without connect event\n", | ||
| 1026 | __func__); | ||
| 1027 | steam_do_connect_event(steam, true); | ||
| 1028 | } | ||
| 1029 | rcu_read_unlock(); | 1052 | rcu_read_unlock(); |
| 1030 | break; | 1053 | break; |
| 1031 | case STEAM_EV_CONNECT: | 1054 | case STEAM_EV_CONNECT: |
| @@ -1074,7 +1097,10 @@ static int steam_param_set_lizard_mode(const char *val, | |||
| 1074 | 1097 | ||
| 1075 | mutex_lock(&steam_devices_lock); | 1098 | mutex_lock(&steam_devices_lock); |
| 1076 | list_for_each_entry(steam, &steam_devices, list) { | 1099 | list_for_each_entry(steam, &steam_devices, list) { |
| 1077 | steam_update_lizard_mode(steam); | 1100 | mutex_lock(&steam->mutex); |
| 1101 | if (!steam->client_opened) | ||
| 1102 | steam_set_lizard_mode(steam, lizard_mode); | ||
| 1103 | mutex_unlock(&steam->mutex); | ||
| 1078 | } | 1104 | } |
| 1079 | mutex_unlock(&steam_devices_lock); | 1105 | mutex_unlock(&steam_devices_lock); |
| 1080 | return 0; | 1106 | return 0; |
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 3cde7c1b9c33..8555ce7e737b 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c | |||
| @@ -177,6 +177,8 @@ static const struct i2c_hid_quirks { | |||
| 177 | I2C_HID_QUIRK_NO_RUNTIME_PM }, | 177 | I2C_HID_QUIRK_NO_RUNTIME_PM }, |
| 178 | { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33, | 178 | { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33, |
| 179 | I2C_HID_QUIRK_DELAY_AFTER_SLEEP }, | 179 | I2C_HID_QUIRK_DELAY_AFTER_SLEEP }, |
| 180 | { USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_8001, | ||
| 181 | I2C_HID_QUIRK_NO_RUNTIME_PM }, | ||
| 180 | { 0, 0 } | 182 | { 0, 0 } |
| 181 | }; | 183 | }; |
| 182 | 184 | ||
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 3c5507313606..840634e0f1e3 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/atomic.h> | 13 | #include <linux/atomic.h> |
| 14 | #include <linux/compat.h> | 14 | #include <linux/compat.h> |
| 15 | #include <linux/cred.h> | ||
| 15 | #include <linux/device.h> | 16 | #include <linux/device.h> |
| 16 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
| 17 | #include <linux/hid.h> | 18 | #include <linux/hid.h> |
| @@ -496,12 +497,13 @@ static int uhid_dev_create2(struct uhid_device *uhid, | |||
| 496 | goto err_free; | 497 | goto err_free; |
| 497 | } | 498 | } |
| 498 | 499 | ||
| 499 | len = min(sizeof(hid->name), sizeof(ev->u.create2.name)); | 500 | /* @hid is zero-initialized, strncpy() is correct, strlcpy() not */ |
| 500 | strlcpy(hid->name, ev->u.create2.name, len); | 501 | len = min(sizeof(hid->name), sizeof(ev->u.create2.name)) - 1; |
| 501 | len = min(sizeof(hid->phys), sizeof(ev->u.create2.phys)); | 502 | strncpy(hid->name, ev->u.create2.name, len); |
| 502 | strlcpy(hid->phys, ev->u.create2.phys, len); | 503 | len = min(sizeof(hid->phys), sizeof(ev->u.create2.phys)) - 1; |
| 503 | len = min(sizeof(hid->uniq), sizeof(ev->u.create2.uniq)); | 504 | strncpy(hid->phys, ev->u.create2.phys, len); |
| 504 | strlcpy(hid->uniq, ev->u.create2.uniq, len); | 505 | len = min(sizeof(hid->uniq), sizeof(ev->u.create2.uniq)) - 1; |
| 506 | strncpy(hid->uniq, ev->u.create2.uniq, len); | ||
| 505 | 507 | ||
| 506 | hid->ll_driver = &uhid_hid_driver; | 508 | hid->ll_driver = &uhid_hid_driver; |
| 507 | hid->bus = ev->u.create2.bus; | 509 | hid->bus = ev->u.create2.bus; |
| @@ -722,6 +724,17 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer, | |||
| 722 | 724 | ||
| 723 | switch (uhid->input_buf.type) { | 725 | switch (uhid->input_buf.type) { |
| 724 | case UHID_CREATE: | 726 | case UHID_CREATE: |
| 727 | /* | ||
| 728 | * 'struct uhid_create_req' contains a __user pointer which is | ||
| 729 | * copied from, so it's unsafe to allow this with elevated | ||
| 730 | * privileges (e.g. from a setuid binary) or via kernel_write(). | ||
| 731 | */ | ||
| 732 | if (file->f_cred != current_cred() || uaccess_kernel()) { | ||
| 733 | pr_err_once("UHID_CREATE from different security context by process %d (%s), this is not allowed.\n", | ||
| 734 | task_tgid_vnr(current), current->comm); | ||
| 735 | ret = -EACCES; | ||
| 736 | goto unlock; | ||
| 737 | } | ||
| 725 | ret = uhid_dev_create(uhid, &uhid->input_buf); | 738 | ret = uhid_dev_create(uhid, &uhid->input_buf); |
| 726 | break; | 739 | break; |
| 727 | case UHID_CREATE2: | 740 | case UHID_CREATE2: |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 387c70df6f29..a355d61940f2 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
| @@ -1139,34 +1139,6 @@ static inline u32 hid_report_len(struct hid_report *report) | |||
| 1139 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, | 1139 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, |
| 1140 | int interrupt); | 1140 | int interrupt); |
| 1141 | 1141 | ||
| 1142 | |||
| 1143 | /** | ||
| 1144 | * struct hid_scroll_counter - Utility class for processing high-resolution | ||
| 1145 | * scroll events. | ||
| 1146 | * @dev: the input device for which events should be reported. | ||
| 1147 | * @microns_per_hi_res_unit: the amount moved by the user's finger for each | ||
| 1148 | * high-resolution unit reported by the mouse, in | ||
| 1149 | * microns. | ||
| 1150 | * @resolution_multiplier: the wheel's resolution in high-resolution mode as a | ||
| 1151 | * multiple of its lower resolution. For example, if | ||
| 1152 | * moving the wheel by one "notch" would result in a | ||
| 1153 | * value of 1 in low-resolution mode but 8 in | ||
| 1154 | * high-resolution, the multiplier is 8. | ||
| 1155 | * @remainder: counts the number of high-resolution units moved since the last | ||
| 1156 | * low-resolution event (REL_WHEEL or REL_HWHEEL) was sent. Should | ||
| 1157 | * only be used by class methods. | ||
| 1158 | */ | ||
| 1159 | struct hid_scroll_counter { | ||
| 1160 | struct input_dev *dev; | ||
| 1161 | int microns_per_hi_res_unit; | ||
| 1162 | int resolution_multiplier; | ||
| 1163 | |||
| 1164 | int remainder; | ||
| 1165 | }; | ||
| 1166 | |||
| 1167 | void hid_scroll_counter_handle_scroll(struct hid_scroll_counter *counter, | ||
| 1168 | int hi_res_value); | ||
| 1169 | |||
| 1170 | /* HID quirks API */ | 1142 | /* HID quirks API */ |
| 1171 | unsigned long hid_lookup_quirk(const struct hid_device *hdev); | 1143 | unsigned long hid_lookup_quirk(const struct hid_device *hdev); |
| 1172 | int hid_quirks_init(char **quirks_param, __u16 bus, int count); | 1144 | int hid_quirks_init(char **quirks_param, __u16 bus, int count); |
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index 6d180cc60a5d..3eb5a4c3d60a 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h | |||
| @@ -716,7 +716,6 @@ | |||
| 716 | * the situation described above. | 716 | * the situation described above. |
| 717 | */ | 717 | */ |
| 718 | #define REL_RESERVED 0x0a | 718 | #define REL_RESERVED 0x0a |
| 719 | #define REL_WHEEL_HI_RES 0x0b | ||
| 720 | #define REL_MAX 0x0f | 719 | #define REL_MAX 0x0f |
| 721 | #define REL_CNT (REL_MAX+1) | 720 | #define REL_CNT (REL_MAX+1) |
| 722 | 721 | ||
| @@ -753,15 +752,6 @@ | |||
| 753 | 752 | ||
| 754 | #define ABS_MISC 0x28 | 753 | #define ABS_MISC 0x28 |
| 755 | 754 | ||
| 756 | /* | ||
| 757 | * 0x2e is reserved and should not be used in input drivers. | ||
| 758 | * It was used by HID as ABS_MISC+6 and userspace needs to detect if | ||
| 759 | * the next ABS_* event is correct or is just ABS_MISC + n. | ||
| 760 | * We define here ABS_RESERVED so userspace can rely on it and detect | ||
| 761 | * the situation described above. | ||
| 762 | */ | ||
| 763 | #define ABS_RESERVED 0x2e | ||
| 764 | |||
| 765 | #define ABS_MT_SLOT 0x2f /* MT slot being modified */ | 755 | #define ABS_MT_SLOT 0x2f /* MT slot being modified */ |
| 766 | #define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */ | 756 | #define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */ |
| 767 | #define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */ | 757 | #define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */ |
