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

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

Pull HID updates from Jiri Kosina:

- quite a few firmware fixes for RMI driver by Andrew Duggan

- huion and uclogic drivers have been substantially overlaping in
functionality laterly. This redundancy is fixed by hid-huion driver
being merged into hid-uclogic; work done by Benjamin Tissoires and
Nikolai Kondrashov

- i2c-hid now supports ACPI GPIO interrupts; patch from Mika Westerberg

- Some of the quirks, that got separated into individual drivers, have
historically had EXPERT dependency. As HID subsystem matured (as
well as the individual drivers), this made less and less sense. This
dependency is now being removed by patch from Jean Delvare

- Logitech lg4ff driver received a couple of improvements for mode
switching, by Michal Malý

- multitouch driver now supports clickpads, patches by Benjamin
Tissoires and Seth Forshee

- hid-sensor framework received a substantial update; namely support
for Custom and Generic pages is being added; work done by Srinivas
Pandruvada

- wacom driver received substantial update; it now supports
i2c-conntected devices (Mika Westerberg), Bamboo PADs are now
properly supported (Benjamin Tissoires), much improved battery
reporting (Jason Gerecke) and pen proximity cleanups (Ping Cheng)

- small assorted fixes and device ID additions

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (68 commits)
HID: sensor: Update document for custom sensor
HID: sensor: Custom and Generic sensor support
HID: debug: fix error handling in hid_debug_events_read()
Input - mt: Fix input_mt_get_slot_by_key
HID: logitech-hidpp: fix error return code
HID: wacom: Add support for Cintiq 13HD Touch
HID: logitech-hidpp: add a module parameter to keep firmware gestures
HID: usbhid: yet another mouse with ALWAYS_POLL
HID: usbhid: more mice with ALWAYS_POLL
HID: wacom: set stylus_in_proximity before checking touch_down
HID: wacom: use wacom_wac_finger_count_touches to set touch_down
HID: wacom: remove hardcoded WACOM_QUIRK_MULTI_INPUT
HID: pidff: effect can't be NULL
HID: add quirk for PIXART OEM mouse used by HP
HID: add HP OEM mouse to quirk ALWAYS_POLL
HID: wacom: ask for a in-prox report when it was missed
HID: hid-sensor-hub: Fix sparse warning
HID: hid-sensor-hub: fix attribute read for logical usage id
HID: plantronics: fix Kconfig default
HID: pidff: support more than one concurrent effect
...

+2983 -709
+10
Documentation/ABI/testing/sysfs-driver-hid
··· 8 8 report descriptor. 9 9 This file cannot be written. 10 10 Users: HIDAPI library (http://www.signal11.us/oss/hidapi) 11 + 12 + What: For USB devices : /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/country 13 + For BT devices : /sys/class/bluetooth/hci<addr>/<hid-bus>:<vendor-id>:<product-id>.<num>/country 14 + Symlink : /sys/class/hidraw/hidraw<num>/device/country 15 + Date: February 2015 16 + KernelVersion: 3.19 17 + Contact: Olivier Gay <ogay@logitech.com> 18 + Description: When read, this file returns the hex integer value in ASCII 19 + of the device's HID country code (e.g. 21 for US). 20 + This file cannot be written.
+45
Documentation/ABI/testing/sysfs-driver-hid-logitech-lg4ff
··· 5 5 Description: Display minimum, maximum and current range of the steering 6 6 wheel. Writing a value within min and max boundaries sets the 7 7 range of the wheel. 8 + 9 + What: /sys/bus/hid/drivers/logitech/<dev>/alternate_modes 10 + Date: Feb 2015 11 + KernelVersion: 4.1 12 + Contact: Michal Malý <madcatxster@gmail.com> 13 + Description: Displays a set of alternate modes supported by a wheel. Each 14 + mode is listed as follows: 15 + Tag: Mode Name 16 + Currently active mode is marked with an asterisk. List also 17 + contains an abstract item "native" which always denotes the 18 + native mode of the wheel. Echoing the mode tag switches the 19 + wheel into the corresponding mode. Depending on the exact model 20 + of the wheel not all listed modes might always be selectable. 21 + If a wheel cannot be switched into the desired mode, -EINVAL 22 + is returned accompanied with an explanatory message in the 23 + kernel log. 24 + This entry is not created for devices that have only one mode. 25 + 26 + Currently supported mode switches: 27 + Driving Force Pro: 28 + DF-EX --> DFP 29 + 30 + G25: 31 + DF-EX --> DFP --> G25 32 + 33 + G27: 34 + DF-EX <*> DFP <-> G25 <-> G27 35 + DF-EX <*--------> G25 <-> G27 36 + DF-EX <*----------------> G27 37 + 38 + DFGT: 39 + DF-EX <*> DFP <-> DFGT 40 + DF-EX <*--------> DFGT 41 + 42 + * hid_logitech module must be loaded with lg4ff_no_autoswitch=1 43 + parameter set in order for the switch to DF-EX mode to work. 44 + 45 + What: /sys/bus/hid/drivers/logitech/<dev>/real_id 46 + Date: Feb 2015 47 + KernelVersion: 4.1 48 + Contact: Michal Malý <madcatxster@gmail.com> 49 + Description: Displays the real model of the wheel regardless of any 50 + alternate mode the wheel might be switched to. 51 + It is a read-only value. 52 + This entry is not created for devices that have only one mode.
+84
Documentation/hid/hid-sensor.txt
··· 138 138 the usage id of X axis. HID sensors can provide events, so this is not necessary 139 139 to poll for any field. If there is some new sample, the core driver will call 140 140 registered callback function to process the sample. 141 + 142 + 143 + ---------- 144 + 145 + HID Custom and generic Sensors 146 + 147 + HID Sensor specification defines two special sensor usage types. Since they 148 + don't represent a standard sensor, it is not possible to define using Linux IIO 149 + type interfaces. 150 + The purpose of these sensors is to extend the functionality or provide a 151 + way to obfuscate the data being communicated by a sensor. Without knowing the 152 + mapping between the data and its encapsulated form, it is difficult for 153 + an application/driver to determine what data is being communicated by the sensor. 154 + This allows some differentiating use cases, where vendor can provide applications. 155 + Some common use cases are debug other sensors or to provide some events like 156 + keyboard attached/detached or lid open/close. 157 + 158 + To allow application to utilize these sensors, here they are exported uses sysfs 159 + attribute groups, attributes and misc device interface. 160 + 161 + An example of this representation on sysfs: 162 + /sys/devices/pci0000:00/INT33C2:00/i2c-0/i2c-INT33D1:00/0018:8086:09FA.0001/HID-SENSOR-2000e1.6.auto$ tree -R 163 + . 164 + ????????? enable_sensor 165 + ????????? feature-0-200316 166 + ??????? ????????? feature-0-200316-maximum 167 + ??????? ????????? feature-0-200316-minimum 168 + ??????? ????????? feature-0-200316-name 169 + ??????? ????????? feature-0-200316-size 170 + ??????? ????????? feature-0-200316-unit-expo 171 + ??????? ????????? feature-0-200316-units 172 + ??????? ????????? feature-0-200316-value 173 + ????????? feature-1-200201 174 + ??????? ????????? feature-1-200201-maximum 175 + ??????? ????????? feature-1-200201-minimum 176 + ??????? ????????? feature-1-200201-name 177 + ??????? ????????? feature-1-200201-size 178 + ??????? ????????? feature-1-200201-unit-expo 179 + ??????? ????????? feature-1-200201-units 180 + ??????? ????????? feature-1-200201-value 181 + ????????? input-0-200201 182 + ??????? ????????? input-0-200201-maximum 183 + ??????? ????????? input-0-200201-minimum 184 + ??????? ????????? input-0-200201-name 185 + ??????? ????????? input-0-200201-size 186 + ??????? ????????? input-0-200201-unit-expo 187 + ??????? ????????? input-0-200201-units 188 + ??????? ????????? input-0-200201-value 189 + ????????? input-1-200202 190 + ??????? ????????? input-1-200202-maximum 191 + ??????? ????????? input-1-200202-minimum 192 + ??????? ????????? input-1-200202-name 193 + ??????? ????????? input-1-200202-size 194 + ??????? ????????? input-1-200202-unit-expo 195 + ??????? ????????? input-1-200202-units 196 + ??????? ????????? input-1-200202-value 197 + 198 + Here there is a custom sensors with four fields, two feature and two inputs. 199 + Each field is represented by a set of attributes. All fields except the "value" 200 + are read only. The value field is a RW field. 201 + Example 202 + /sys/bus/platform/devices/HID-SENSOR-2000e1.6.auto/feature-0-200316$ grep -r . * 203 + feature-0-200316-maximum:6 204 + feature-0-200316-minimum:0 205 + feature-0-200316-name:property-reporting-state 206 + feature-0-200316-size:1 207 + feature-0-200316-unit-expo:0 208 + feature-0-200316-units:25 209 + feature-0-200316-value:1 210 + 211 + How to enable such sensor? 212 + By default sensor can be power gated. To enable sysfs attribute "enable" can be 213 + used. 214 + $ echo 1 > enable_sensor 215 + 216 + Once enabled and powered on, sensor can report value using HID reports. 217 + These reports are pushed using misc device interface in a FIFO order. 218 + /dev$ tree | grep HID-SENSOR-2000e1.6.auto 219 + ??????? ????????? 10:53 -> ../HID-SENSOR-2000e1.6.auto 220 + ????????? HID-SENSOR-2000e1.6.auto 221 + 222 + Each reports can be of variable length preceded by a header. This header 223 + consist of a 32 bit usage id, 64 bit time stamp and 32 bit length field of raw 224 + data.
+28 -20
drivers/hid/Kconfig
··· 92 92 depends on HID 93 93 94 94 config HID_A4TECH 95 - tristate "A4 tech mice" if EXPERT 95 + tristate "A4 tech mice" 96 96 depends on HID 97 97 default !EXPERT 98 98 ---help--- ··· 113 113 game controllers. 114 114 115 115 config HID_APPLE 116 - tristate "Apple {i,Power,Mac}Books" if EXPERT 116 + tristate "Apple {i,Power,Mac}Books" 117 117 depends on HID 118 118 default !EXPERT 119 119 ---help--- ··· 141 141 Support for Aureal Cy se W-01RN Remote Controller and other Aureal derived remotes. 142 142 143 143 config HID_BELKIN 144 - tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT 144 + tristate "Belkin Flip KVM and Wireless keyboard" 145 145 depends on HID 146 146 default !EXPERT 147 147 ---help--- ··· 158 158 - BETOP 2185 PC & BFM MODE 159 159 160 160 config HID_CHERRY 161 - tristate "Cherry Cymotion keyboard" if EXPERT 161 + tristate "Cherry Cymotion keyboard" 162 162 depends on HID 163 163 default !EXPERT 164 164 ---help--- 165 165 Support for Cherry Cymotion keyboard. 166 166 167 167 config HID_CHICONY 168 - tristate "Chicony Tactical pad" if EXPERT 168 + tristate "Chicony Tactical pad" 169 169 depends on HID 170 170 default !EXPERT 171 171 ---help--- ··· 196 196 customizable USB descriptor fields are exposed as sysfs attributes. 197 197 198 198 config HID_CYPRESS 199 - tristate "Cypress mouse and barcode readers" if EXPERT 199 + tristate "Cypress mouse and barcode readers" 200 200 depends on HID 201 201 default !EXPERT 202 202 ---help--- ··· 245 245 different devices than those handled by CONFIG_TOUCHSCREEN_USB_ELO. 246 246 247 247 config HID_EZKEY 248 - tristate "Ezkey BTC 8193 keyboard" if EXPERT 248 + tristate "Ezkey BTC 8193 keyboard" 249 249 depends on HID 250 250 default !EXPERT 251 251 ---help--- ··· 286 286 Currently the following devices are know to be supported: 287 287 - MSI GT683R 288 288 289 - config HID_HUION 290 - tristate "Huion tablets" 291 - depends on USB_HID 292 - ---help--- 293 - Support for Huion 580 tablet. 294 - 295 289 config HID_KEYTOUCH 296 290 tristate "Keytouch HID devices" 297 291 depends on HID ··· 306 312 307 313 config HID_UCLOGIC 308 314 tristate "UC-Logic" 309 - depends on HID 315 + depends on USB_HID 310 316 ---help--- 311 - Support for UC-Logic tablets. 317 + Support for UC-Logic and Huion tablets. 312 318 313 319 config HID_WALTOP 314 320 tristate "Waltop" ··· 338 344 Support for Twinhan IR remote control. 339 345 340 346 config HID_KENSINGTON 341 - tristate "Kensington Slimblade Trackball" if EXPERT 347 + tristate "Kensington Slimblade Trackball" 342 348 depends on HID 343 349 default !EXPERT 344 350 ---help--- ··· 366 372 - ThinkPad Compact USB Keyboard with TrackPoint (supports Fn keys) 367 373 368 374 config HID_LOGITECH 369 - tristate "Logitech devices" if EXPERT 375 + tristate "Logitech devices" 370 376 depends on HID 371 377 default !EXPERT 372 378 ---help--- ··· 455 461 Apple Wireless "Magic" Mouse and the Apple Wireless "Magic" Trackpad. 456 462 457 463 config HID_MICROSOFT 458 - tristate "Microsoft non-fully HID-compliant devices" if EXPERT 464 + tristate "Microsoft non-fully HID-compliant devices" 459 465 depends on HID 460 466 default !EXPERT 461 467 ---help--- 462 468 Support for Microsoft devices that are not fully compliant with HID standard. 463 469 464 470 config HID_MONTEREY 465 - tristate "Monterey Genius KB29E keyboard" if EXPERT 471 + tristate "Monterey Genius KB29E keyboard" 466 472 depends on HID 467 473 default !EXPERT 468 474 ---help--- ··· 632 638 633 639 config HID_PLANTRONICS 634 640 tristate "Plantronics USB HID Driver" 635 - default !EXPERT 636 641 depends on HID 637 642 ---help--- 638 643 Provides HID support for Plantronics telephony devices. ··· 877 884 drivers can use the service provided by this driver to register 878 885 for events and handle data streams. Each sensor driver can format 879 886 data and present to user mode using input or IIO interface. 887 + 888 + config HID_SENSOR_CUSTOM_SENSOR 889 + tristate "HID Sensors hub custom sensor support" 890 + depends on HID_SENSOR_HUB 891 + default n 892 + ---help--- 893 + HID Sensor hub specification allows definition of some custom and 894 + generic sensors. Unlike other HID sensors, they can't be exported 895 + via Linux IIO because of custom fields. This is up to the manufacturer 896 + to decide how to interpret these special sensor ids and process in 897 + the user space. Currently some manufacturers are using these ids for 898 + sensor calibration and debugging other sensors. Manufacturers 899 + should't use these special custom sensor ids to export any of the 900 + standard sensors. 901 + Select this config option for custom/generic sensor support. 880 902 881 903 endmenu 882 904
+1 -1
drivers/hid/Makefile
··· 41 41 obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o 42 42 obj-$(CONFIG_HID_HOLTEK) += hid-holtek-mouse.o 43 43 obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o 44 - obj-$(CONFIG_HID_HUION) += hid-huion.o 45 44 obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o 46 45 obj-$(CONFIG_HID_ICADE) += hid-icade.o 47 46 obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o ··· 100 101 obj-$(CONFIG_HID_WALTOP) += hid-waltop.o 101 102 obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o 102 103 obj-$(CONFIG_HID_SENSOR_HUB) += hid-sensor-hub.o 104 + obj-$(CONFIG_HID_SENSOR_CUSTOM_SENSOR) += hid-sensor-custom.o 103 105 104 106 obj-$(CONFIG_USB_HID) += usbhid/ 105 107 obj-$(CONFIG_USB_MOUSE) += usbhid/
+21
drivers/hid/hid-core.c
··· 1562 1562 return count; 1563 1563 } 1564 1564 1565 + static ssize_t 1566 + show_country(struct device *dev, struct device_attribute *attr, 1567 + char *buf) 1568 + { 1569 + struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1570 + 1571 + return sprintf(buf, "%02x\n", hdev->country & 0xff); 1572 + } 1573 + 1565 1574 static struct bin_attribute dev_bin_attr_report_desc = { 1566 1575 .attr = { .name = "report_descriptor", .mode = 0444 }, 1567 1576 .read = read_report_descriptor, 1568 1577 .size = HID_MAX_DESCRIPTOR_SIZE, 1578 + }; 1579 + 1580 + static struct device_attribute dev_attr_country = { 1581 + .attr = { .name = "country", .mode = 0444 }, 1582 + .show = show_country, 1569 1583 }; 1570 1584 1571 1585 int hid_connect(struct hid_device *hdev, unsigned int connect_mask) ··· 1660 1646 bus = "<UNKNOWN>"; 1661 1647 } 1662 1648 1649 + ret = device_create_file(&hdev->dev, &dev_attr_country); 1650 + if (ret) 1651 + hid_warn(hdev, 1652 + "can't create sysfs country code attribute err: %d\n", ret); 1653 + 1663 1654 ret = device_create_bin_file(&hdev->dev, &dev_bin_attr_report_desc); 1664 1655 if (ret) 1665 1656 hid_warn(hdev, ··· 1680 1661 1681 1662 void hid_disconnect(struct hid_device *hdev) 1682 1663 { 1664 + device_remove_file(&hdev->dev, &dev_attr_country); 1683 1665 device_remove_bin_file(&hdev->dev, &dev_bin_attr_report_desc); 1684 1666 if (hdev->claimed & HID_CLAIMED_INPUT) 1685 1667 hidinput_disconnect(hdev); ··· 1844 1824 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, 1845 1825 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) }, 1846 1826 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, 1827 + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912) }, 1847 1828 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, 1848 1829 { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, 1849 1830 #if IS_ENABLED(CONFIG_HID_LENOVO)
+3 -1
drivers/hid/hid-debug.c
··· 165 165 {0, 0x53, "DeviceIndex"}, 166 166 {0, 0x54, "ContactCount"}, 167 167 {0, 0x55, "ContactMaximumNumber"}, 168 + {0, 0x59, "ButtonType"}, 168 169 {0, 0x5A, "SecondaryBarrelSwitch"}, 169 170 {0, 0x5B, "TransducerSerialNumber"}, 170 171 { 15, 0, "PhysicalInterfaceDevice" }, ··· 1128 1127 1129 1128 if (!list->hdev || !list->hdev->debug) { 1130 1129 ret = -EIO; 1131 - break; 1130 + set_current_state(TASK_RUNNING); 1131 + goto out; 1132 1132 } 1133 1133 1134 1134 /* allow O_NONBLOCK from other threads */
-290
drivers/hid/hid-huion.c
··· 1 - /* 2 - * HID driver for Huion devices not fully compliant with HID standard 3 - * 4 - * Copyright (c) 2013 Martin Rusko 5 - * Copyright (c) 2014 Nikolai Kondrashov 6 - */ 7 - 8 - /* 9 - * This program is free software; you can redistribute it and/or modify it 10 - * under the terms of the GNU General Public License as published by the Free 11 - * Software Foundation; either version 2 of the License, or (at your option) 12 - * any later version. 13 - */ 14 - 15 - #include <linux/device.h> 16 - #include <linux/hid.h> 17 - #include <linux/module.h> 18 - #include <linux/usb.h> 19 - #include <asm/unaligned.h> 20 - #include "usbhid/usbhid.h" 21 - 22 - #include "hid-ids.h" 23 - 24 - /* Report descriptor template placeholder head */ 25 - #define HUION_PH_HEAD 0xFE, 0xED, 0x1D 26 - 27 - /* Report descriptor template placeholder IDs */ 28 - enum huion_ph_id { 29 - HUION_PH_ID_X_LM, 30 - HUION_PH_ID_X_PM, 31 - HUION_PH_ID_Y_LM, 32 - HUION_PH_ID_Y_PM, 33 - HUION_PH_ID_PRESSURE_LM, 34 - HUION_PH_ID_NUM 35 - }; 36 - 37 - /* Report descriptor template placeholder */ 38 - #define HUION_PH(_ID) HUION_PH_HEAD, HUION_PH_ID_##_ID 39 - 40 - /* Fixed report descriptor template */ 41 - static const __u8 huion_tablet_rdesc_template[] = { 42 - 0x05, 0x0D, /* Usage Page (Digitizer), */ 43 - 0x09, 0x02, /* Usage (Pen), */ 44 - 0xA1, 0x01, /* Collection (Application), */ 45 - 0x85, 0x07, /* Report ID (7), */ 46 - 0x09, 0x20, /* Usage (Stylus), */ 47 - 0xA0, /* Collection (Physical), */ 48 - 0x14, /* Logical Minimum (0), */ 49 - 0x25, 0x01, /* Logical Maximum (1), */ 50 - 0x75, 0x01, /* Report Size (1), */ 51 - 0x09, 0x42, /* Usage (Tip Switch), */ 52 - 0x09, 0x44, /* Usage (Barrel Switch), */ 53 - 0x09, 0x46, /* Usage (Tablet Pick), */ 54 - 0x95, 0x03, /* Report Count (3), */ 55 - 0x81, 0x02, /* Input (Variable), */ 56 - 0x95, 0x03, /* Report Count (3), */ 57 - 0x81, 0x03, /* Input (Constant, Variable), */ 58 - 0x09, 0x32, /* Usage (In Range), */ 59 - 0x95, 0x01, /* Report Count (1), */ 60 - 0x81, 0x02, /* Input (Variable), */ 61 - 0x95, 0x01, /* Report Count (1), */ 62 - 0x81, 0x03, /* Input (Constant, Variable), */ 63 - 0x75, 0x10, /* Report Size (16), */ 64 - 0x95, 0x01, /* Report Count (1), */ 65 - 0xA4, /* Push, */ 66 - 0x05, 0x01, /* Usage Page (Desktop), */ 67 - 0x65, 0x13, /* Unit (Inch), */ 68 - 0x55, 0xFD, /* Unit Exponent (-3), */ 69 - 0x34, /* Physical Minimum (0), */ 70 - 0x09, 0x30, /* Usage (X), */ 71 - 0x27, HUION_PH(X_LM), /* Logical Maximum (PLACEHOLDER), */ 72 - 0x47, HUION_PH(X_PM), /* Physical Maximum (PLACEHOLDER), */ 73 - 0x81, 0x02, /* Input (Variable), */ 74 - 0x09, 0x31, /* Usage (Y), */ 75 - 0x27, HUION_PH(Y_LM), /* Logical Maximum (PLACEHOLDER), */ 76 - 0x47, HUION_PH(Y_PM), /* Physical Maximum (PLACEHOLDER), */ 77 - 0x81, 0x02, /* Input (Variable), */ 78 - 0xB4, /* Pop, */ 79 - 0x09, 0x30, /* Usage (Tip Pressure), */ 80 - 0x27, 81 - HUION_PH(PRESSURE_LM), /* Logical Maximum (PLACEHOLDER), */ 82 - 0x81, 0x02, /* Input (Variable), */ 83 - 0xC0, /* End Collection, */ 84 - 0xC0 /* End Collection */ 85 - }; 86 - 87 - /* Parameter indices */ 88 - enum huion_prm { 89 - HUION_PRM_X_LM = 1, 90 - HUION_PRM_Y_LM = 2, 91 - HUION_PRM_PRESSURE_LM = 4, 92 - HUION_PRM_RESOLUTION = 5, 93 - HUION_PRM_NUM 94 - }; 95 - 96 - /* Driver data */ 97 - struct huion_drvdata { 98 - __u8 *rdesc; 99 - unsigned int rsize; 100 - }; 101 - 102 - static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc, 103 - unsigned int *rsize) 104 - { 105 - struct huion_drvdata *drvdata = hid_get_drvdata(hdev); 106 - switch (hdev->product) { 107 - case USB_DEVICE_ID_HUION_TABLET: 108 - if (drvdata->rdesc != NULL) { 109 - rdesc = drvdata->rdesc; 110 - *rsize = drvdata->rsize; 111 - } 112 - break; 113 - } 114 - return rdesc; 115 - } 116 - 117 - /** 118 - * Enable fully-functional tablet mode and determine device parameters. 119 - * 120 - * @hdev: HID device 121 - */ 122 - static int huion_tablet_enable(struct hid_device *hdev) 123 - { 124 - int rc; 125 - struct usb_device *usb_dev = hid_to_usb_dev(hdev); 126 - struct huion_drvdata *drvdata = hid_get_drvdata(hdev); 127 - __le16 *buf = NULL; 128 - size_t len; 129 - s32 params[HUION_PH_ID_NUM]; 130 - s32 resolution; 131 - __u8 *p; 132 - s32 v; 133 - 134 - /* 135 - * Read string descriptor containing tablet parameters. The specific 136 - * string descriptor and data were discovered by sniffing the Windows 137 - * driver traffic. 138 - * NOTE: This enables fully-functional tablet mode. 139 - */ 140 - len = HUION_PRM_NUM * sizeof(*buf); 141 - buf = kmalloc(len, GFP_KERNEL); 142 - if (buf == NULL) { 143 - hid_err(hdev, "failed to allocate parameter buffer\n"); 144 - rc = -ENOMEM; 145 - goto cleanup; 146 - } 147 - rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 148 - USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, 149 - (USB_DT_STRING << 8) + 0x64, 150 - 0x0409, buf, len, 151 - USB_CTRL_GET_TIMEOUT); 152 - if (rc == -EPIPE) { 153 - hid_err(hdev, "device parameters not found\n"); 154 - rc = -ENODEV; 155 - goto cleanup; 156 - } else if (rc < 0) { 157 - hid_err(hdev, "failed to get device parameters: %d\n", rc); 158 - rc = -ENODEV; 159 - goto cleanup; 160 - } else if (rc != len) { 161 - hid_err(hdev, "invalid device parameters\n"); 162 - rc = -ENODEV; 163 - goto cleanup; 164 - } 165 - 166 - /* Extract device parameters */ 167 - params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[HUION_PRM_X_LM]); 168 - params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[HUION_PRM_Y_LM]); 169 - params[HUION_PH_ID_PRESSURE_LM] = 170 - le16_to_cpu(buf[HUION_PRM_PRESSURE_LM]); 171 - resolution = le16_to_cpu(buf[HUION_PRM_RESOLUTION]); 172 - if (resolution == 0) { 173 - params[HUION_PH_ID_X_PM] = 0; 174 - params[HUION_PH_ID_Y_PM] = 0; 175 - } else { 176 - params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] * 177 - 1000 / resolution; 178 - params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] * 179 - 1000 / resolution; 180 - } 181 - 182 - /* Allocate fixed report descriptor */ 183 - drvdata->rdesc = devm_kmalloc(&hdev->dev, 184 - sizeof(huion_tablet_rdesc_template), 185 - GFP_KERNEL); 186 - if (drvdata->rdesc == NULL) { 187 - hid_err(hdev, "failed to allocate fixed rdesc\n"); 188 - rc = -ENOMEM; 189 - goto cleanup; 190 - } 191 - drvdata->rsize = sizeof(huion_tablet_rdesc_template); 192 - 193 - /* Format fixed report descriptor */ 194 - memcpy(drvdata->rdesc, huion_tablet_rdesc_template, 195 - drvdata->rsize); 196 - for (p = drvdata->rdesc; 197 - p <= drvdata->rdesc + drvdata->rsize - 4;) { 198 - if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D && 199 - p[3] < sizeof(params)) { 200 - v = params[p[3]]; 201 - put_unaligned(cpu_to_le32(v), (s32 *)p); 202 - p += 4; 203 - } else { 204 - p++; 205 - } 206 - } 207 - 208 - rc = 0; 209 - 210 - cleanup: 211 - kfree(buf); 212 - return rc; 213 - } 214 - 215 - static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id) 216 - { 217 - int rc; 218 - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 219 - struct huion_drvdata *drvdata; 220 - 221 - /* Allocate and assign driver data */ 222 - drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL); 223 - if (drvdata == NULL) { 224 - hid_err(hdev, "failed to allocate driver data\n"); 225 - return -ENOMEM; 226 - } 227 - hid_set_drvdata(hdev, drvdata); 228 - 229 - switch (id->product) { 230 - case USB_DEVICE_ID_HUION_TABLET: 231 - /* If this is the pen interface */ 232 - if (intf->cur_altsetting->desc.bInterfaceNumber == 0) { 233 - rc = huion_tablet_enable(hdev); 234 - if (rc) { 235 - hid_err(hdev, "tablet enabling failed\n"); 236 - return rc; 237 - } 238 - } 239 - break; 240 - } 241 - 242 - rc = hid_parse(hdev); 243 - if (rc) { 244 - hid_err(hdev, "parse failed\n"); 245 - return rc; 246 - } 247 - 248 - rc = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 249 - if (rc) { 250 - hid_err(hdev, "hw start failed\n"); 251 - return rc; 252 - } 253 - 254 - return 0; 255 - } 256 - 257 - static int huion_raw_event(struct hid_device *hdev, struct hid_report *report, 258 - u8 *data, int size) 259 - { 260 - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 261 - 262 - /* If this is a pen input report */ 263 - if (intf->cur_altsetting->desc.bInterfaceNumber == 0 && 264 - report->type == HID_INPUT_REPORT && 265 - report->id == 0x07 && size >= 2) 266 - /* Invert the in-range bit */ 267 - data[1] ^= 0x40; 268 - 269 - return 0; 270 - } 271 - 272 - static const struct hid_device_id huion_devices[] = { 273 - { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) }, 274 - { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_HUION_TABLET) }, 275 - { } 276 - }; 277 - MODULE_DEVICE_TABLE(hid, huion_devices); 278 - 279 - static struct hid_driver huion_driver = { 280 - .name = "huion", 281 - .id_table = huion_devices, 282 - .probe = huion_probe, 283 - .report_fixup = huion_report_fixup, 284 - .raw_event = huion_raw_event, 285 - }; 286 - module_hid_driver(huion_driver); 287 - 288 - MODULE_AUTHOR("Martin Rusko"); 289 - MODULE_DESCRIPTION("Huion HID driver"); 290 - MODULE_LICENSE("GPL");
+10
drivers/hid/hid-ids.h
··· 459 459 #define USB_DEVICE_ID_UGCI_FLYING 0x0020 460 460 #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 461 461 462 + #define USB_VENDOR_ID_HP 0x03f0 463 + #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A 0x0a4a 464 + #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a 465 + #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a 466 + 462 467 #define USB_VENDOR_ID_HUION 0x256c 463 468 #define USB_DEVICE_ID_HUION_TABLET 0x006e 464 469 ··· 538 533 #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011 539 534 #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2 0x501a 540 535 #define USB_DEVICE_ID_KYE_EASYPEN_M610X 0x5013 536 + #define USB_DEVICE_ID_KYE_PENSKETCH_M912 0x5015 541 537 542 538 #define USB_VENDOR_ID_LABTEC 0x1020 543 539 #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 ··· 597 591 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 598 592 #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f 599 593 #define USB_DEVICE_ID_LOGITECH_HARMONY_PS3 0x0306 594 + #define USB_DEVICE_ID_LOGITECH_MOUSE_C01A 0xc01a 595 + #define USB_DEVICE_ID_LOGITECH_MOUSE_C05A 0xc05a 596 + #define USB_DEVICE_ID_LOGITECH_MOUSE_C06A 0xc06a 600 597 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a 601 598 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211 602 599 #define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 ··· 1031 1022 #define USB_DEVICE_ID_ZYTRONIC_ZXY100 0x0005 1032 1023 1033 1024 #define USB_VENDOR_ID_PRIMAX 0x0461 1025 + #define USB_DEVICE_ID_PRIMAX_MOUSE_4D22 0x4d22 1034 1026 #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 1035 1027 1036 1028
+23
drivers/hid/hid-input.c
··· 720 720 } 721 721 break; 722 722 723 + case HID_UP_TELEPHONY: 724 + switch (usage->hid & HID_USAGE) { 725 + case 0x2f: map_key_clear(KEY_MICMUTE); break; 726 + case 0xb0: map_key_clear(KEY_NUMERIC_0); break; 727 + case 0xb1: map_key_clear(KEY_NUMERIC_1); break; 728 + case 0xb2: map_key_clear(KEY_NUMERIC_2); break; 729 + case 0xb3: map_key_clear(KEY_NUMERIC_3); break; 730 + case 0xb4: map_key_clear(KEY_NUMERIC_4); break; 731 + case 0xb5: map_key_clear(KEY_NUMERIC_5); break; 732 + case 0xb6: map_key_clear(KEY_NUMERIC_6); break; 733 + case 0xb7: map_key_clear(KEY_NUMERIC_7); break; 734 + case 0xb8: map_key_clear(KEY_NUMERIC_8); break; 735 + case 0xb9: map_key_clear(KEY_NUMERIC_9); break; 736 + case 0xba: map_key_clear(KEY_NUMERIC_STAR); break; 737 + case 0xbb: map_key_clear(KEY_NUMERIC_POUND); break; 738 + case 0xbc: map_key_clear(KEY_NUMERIC_A); break; 739 + case 0xbd: map_key_clear(KEY_NUMERIC_B); break; 740 + case 0xbe: map_key_clear(KEY_NUMERIC_C); break; 741 + case 0xbf: map_key_clear(KEY_NUMERIC_D); break; 742 + default: goto ignore; 743 + } 744 + break; 745 + 723 746 case HID_UP_CONSUMER: /* USB HUT v1.12, pages 75-84 */ 724 747 switch (usage->hid & HID_USAGE) { 725 748 case 0x000: goto ignore;
+140
drivers/hid/hid-kye.c
··· 268 268 0xC0 /* End Collection */ 269 269 }; 270 270 271 + 272 + /* Original PenSketch M912 report descriptor size */ 273 + #define PENSKETCH_M912_RDESC_ORIG_SIZE 482 274 + 275 + /* Fixed PenSketch M912 report descriptor */ 276 + static __u8 pensketch_m912_rdesc_fixed[] = { 277 + 0x05, 0x01, /* Usage Page (Desktop), */ 278 + 0x08, /* Usage (00h), */ 279 + 0xA1, 0x01, /* Collection (Application), */ 280 + 0x85, 0x05, /* Report ID (5), */ 281 + 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 282 + 0x09, 0x01, /* Usage (01h), */ 283 + 0x15, 0x81, /* Logical Minimum (-127), */ 284 + 0x25, 0x7F, /* Logical Maximum (127), */ 285 + 0x75, 0x08, /* Report Size (8), */ 286 + 0x95, 0x07, /* Report Count (7), */ 287 + 0xB1, 0x02, /* Feature (Variable), */ 288 + 0xC0, /* End Collection, */ 289 + 0x05, 0x0D, /* Usage Page (Digitizer), */ 290 + 0x09, 0x02, /* Usage (Pen), */ 291 + 0xA1, 0x01, /* Collection (Application), */ 292 + 0x85, 0x10, /* Report ID (16), */ 293 + 0x09, 0x20, /* Usage (Stylus), */ 294 + 0xA0, /* Collection (Physical), */ 295 + 0x09, 0x42, /* Usage (Tip Switch), */ 296 + 0x09, 0x44, /* Usage (Barrel Switch), */ 297 + 0x09, 0x46, /* Usage (Tablet Pick), */ 298 + 0x14, /* Logical Minimum (0), */ 299 + 0x25, 0x01, /* Logical Maximum (1), */ 300 + 0x75, 0x01, /* Report Size (1), */ 301 + 0x95, 0x03, /* Report Count (3), */ 302 + 0x81, 0x02, /* Input (Variable), */ 303 + 0x95, 0x04, /* Report Count (4), */ 304 + 0x81, 0x03, /* Input (Constant, Variable), */ 305 + 0x09, 0x32, /* Usage (In Range), */ 306 + 0x95, 0x01, /* Report Count (1), */ 307 + 0x81, 0x02, /* Input (Variable), */ 308 + 0x75, 0x10, /* Report Size (16), */ 309 + 0x95, 0x01, /* Report Count (1), */ 310 + 0xA4, /* Push, */ 311 + 0x05, 0x01, /* Usage Page (Desktop), */ 312 + 0x55, 0xFD, /* Unit Exponent (-3), */ 313 + 0x65, 0x13, /* Unit (Inch), */ 314 + 0x14, /* Logical Minimum (0), */ 315 + 0x34, /* Physical Minimum (0), */ 316 + 0x09, 0x30, /* Usage (X), */ 317 + 0x27, 0x00, 0xF0, 0x00, 0x00, /* Logical Maximum (61440), */ 318 + 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */ 319 + 0x81, 0x02, /* Input (Variable), */ 320 + 0x09, 0x31, /* Usage (Y), */ 321 + 0x27, 0x00, 0xB4, 0x00, 0x00, /* Logical Maximum (46080), */ 322 + 0x46, 0x28, 0x23, /* Physical Maximum (9000), */ 323 + 0x81, 0x02, /* Input (Variable), */ 324 + 0xB4, /* Pop, */ 325 + 0x09, 0x30, /* Usage (Tip Pressure), */ 326 + 0x14, /* Logical Minimum (0), */ 327 + 0x26, 0xFF, 0x07, /* Logical Maximum (2047), */ 328 + 0x81, 0x02, /* Input (Variable), */ 329 + 0xC0, /* End Collection, */ 330 + 0xC0, /* End Collection, */ 331 + 0x05, 0x0D, /* Usage Page (Digitizer), */ 332 + 0x09, 0x21, /* Usage (Puck), */ 333 + 0xA1, 0x01, /* Collection (Application), */ 334 + 0x85, 0x11, /* Report ID (17), */ 335 + 0x09, 0x21, /* Usage (Puck), */ 336 + 0xA0, /* Collection (Physical), */ 337 + 0x05, 0x09, /* Usage Page (Button), */ 338 + 0x75, 0x01, /* Report Size (1), */ 339 + 0x19, 0x01, /* Usage Minimum (01h), */ 340 + 0x29, 0x03, /* Usage Maximum (03h), */ 341 + 0x14, /* Logical Minimum (0), */ 342 + 0x25, 0x01, /* Logical Maximum (1), */ 343 + 0x95, 0x03, /* Report Count (3), */ 344 + 0x81, 0x02, /* Input (Variable), */ 345 + 0x95, 0x04, /* Report Count (4), */ 346 + 0x81, 0x01, /* Input (Constant), */ 347 + 0x95, 0x01, /* Report Count (1), */ 348 + 0x0B, 0x32, 0x00, 0x0D, 0x00, /* Usage (Digitizer In Range), */ 349 + 0x14, /* Logical Minimum (0), */ 350 + 0x25, 0x01, /* Logical Maximum (1), */ 351 + 0x81, 0x02, /* Input (Variable), */ 352 + 0xA4, /* Push, */ 353 + 0x05, 0x01, /* Usage Page (Desktop), */ 354 + 0x75, 0x10, /* Report Size (16), */ 355 + 0x95, 0x01, /* Report Count (1), */ 356 + 0x55, 0xFD, /* Unit Exponent (-3), */ 357 + 0x65, 0x13, /* Unit (Inch), */ 358 + 0x14, /* Logical Minimum (0), */ 359 + 0x34, /* Physical Minimum (0), */ 360 + 0x09, 0x30, /* Usage (X), */ 361 + 0x27, 0x00, 0xF0, 0x00, 0x00, /* Logical Maximum (61440), */ 362 + 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */ 363 + 0x81, 0x02, /* Input (Variable), */ 364 + 0x09, 0x31, /* Usage (Y), */ 365 + 0x27, 0x00, 0xB4, 0x00, 0x00, /* Logical Maximum (46080), */ 366 + 0x46, 0x28, 0x23, /* Physical Maximum (9000), */ 367 + 0x81, 0x02, /* Input (Variable), */ 368 + 0x09, 0x38, /* Usage (Wheel), */ 369 + 0x75, 0x08, /* Report Size (8), */ 370 + 0x95, 0x01, /* Report Count (1), */ 371 + 0x15, 0xFF, /* Logical Minimum (-1), */ 372 + 0x25, 0x01, /* Logical Maximum (1), */ 373 + 0x34, /* Physical Minimum (0), */ 374 + 0x44, /* Physical Maximum (0), */ 375 + 0x81, 0x06, /* Input (Variable, Relative), */ 376 + 0xB4, /* Pop, */ 377 + 0xC0, /* End Collection, */ 378 + 0xC0, /* End Collection, */ 379 + 0x05, 0x0C, /* Usage Page (Consumer), */ 380 + 0x09, 0x01, /* Usage (Consumer Control), */ 381 + 0xA1, 0x01, /* Collection (Application), */ 382 + 0x85, 0x12, /* Report ID (18), */ 383 + 0x14, /* Logical Minimum (0), */ 384 + 0x25, 0x01, /* Logical Maximum (1), */ 385 + 0x75, 0x01, /* Report Size (1), */ 386 + 0x95, 0x08, /* Report Count (8), */ 387 + 0x05, 0x0C, /* Usage Page (Consumer), */ 388 + 0x0A, 0x6A, 0x02, /* Usage (AC Delete), */ 389 + 0x0A, 0x1A, 0x02, /* Usage (AC Undo), */ 390 + 0x0A, 0x01, 0x02, /* Usage (AC New), */ 391 + 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */ 392 + 0x0A, 0x25, 0x02, /* Usage (AC Forward), */ 393 + 0x0A, 0x24, 0x02, /* Usage (AC Back), */ 394 + 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */ 395 + 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */ 396 + 0x81, 0x02, /* Input (Variable), */ 397 + 0x95, 0x30, /* Report Count (48), */ 398 + 0x81, 0x03, /* Input (Constant, Variable), */ 399 + 0xC0 /* End Collection */ 400 + }; 401 + 271 402 static __u8 *kye_consumer_control_fixup(struct hid_device *hdev, __u8 *rdesc, 272 403 unsigned int *rsize, int offset, const char *device_name) { 273 404 /* ··· 464 333 if (*rsize == EASYPEN_M610X_RDESC_ORIG_SIZE) { 465 334 rdesc = easypen_m610x_rdesc_fixed; 466 335 *rsize = sizeof(easypen_m610x_rdesc_fixed); 336 + } 337 + break; 338 + case USB_DEVICE_ID_KYE_PENSKETCH_M912: 339 + if (*rsize == PENSKETCH_M912_RDESC_ORIG_SIZE) { 340 + rdesc = pensketch_m912_rdesc_fixed; 341 + *rsize = sizeof(pensketch_m912_rdesc_fixed); 467 342 } 468 343 break; 469 344 case USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE: ··· 555 418 case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: 556 419 case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2: 557 420 case USB_DEVICE_ID_KYE_EASYPEN_M610X: 421 + case USB_DEVICE_ID_KYE_PENSKETCH_M912: 558 422 ret = kye_tablet_enable(hdev); 559 423 if (ret) { 560 424 hid_err(hdev, "tablet enabling failed\n"); ··· 595 457 USB_DEVICE_ID_GENIUS_GX_IMPERATOR) }, 596 458 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 597 459 USB_DEVICE_ID_GENIUS_MANTICORE) }, 460 + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, 461 + USB_DEVICE_ID_KYE_PENSKETCH_M912) }, 598 462 { } 599 463 }; 600 464 MODULE_DEVICE_TABLE(hid, kye_devices);
+7
drivers/hid/hid-lg.c
··· 27 27 #include "usbhid/usbhid.h" 28 28 #include "hid-ids.h" 29 29 #include "hid-lg.h" 30 + #include "hid-lg4ff.h" 30 31 31 32 #define LG_RDESC 0x001 32 33 #define LG_BAD_RELATIVE_KEYS 0x002 ··· 818 817 .remove = lg_remove, 819 818 }; 820 819 module_hid_driver(lg_driver); 820 + 821 + #ifdef CONFIG_LOGIWHEELS_FF 822 + int lg4ff_no_autoswitch = 0; 823 + module_param_named(lg4ff_no_autoswitch, lg4ff_no_autoswitch, int, S_IRUGO); 824 + MODULE_PARM_DESC(lg4ff_no_autoswitch, "Do not switch multimode wheels to their native mode automatically"); 825 + #endif 821 826 822 827 MODULE_LICENSE("GPL");
-12
drivers/hid/hid-lg.h
··· 24 24 static inline int lg3ff_init(struct hid_device *hdev) { return -1; } 25 25 #endif 26 26 27 - #ifdef CONFIG_LOGIWHEELS_FF 28 - int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field, 29 - struct hid_usage *usage, __s32 value, struct lg_drv_data *drv_data); 30 - int lg4ff_init(struct hid_device *hdev); 31 - int lg4ff_deinit(struct hid_device *hdev); 32 - #else 33 - static inline int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field, 34 - struct hid_usage *usage, __s32 value, struct lg_drv_data *drv_data) { return 0; } 35 - static inline int lg4ff_init(struct hid_device *hdev) { return -1; } 36 - static inline int lg4ff_deinit(struct hid_device *hdev) { return -1; } 37 - #endif 38 - 39 27 #endif
+531 -77
drivers/hid/hid-lg4ff.c
··· 30 30 31 31 #include "usbhid/usbhid.h" 32 32 #include "hid-lg.h" 33 + #include "hid-lg4ff.h" 33 34 #include "hid-ids.h" 34 35 35 - #define DFGT_REV_MAJ 0x13 36 - #define DFGT_REV_MIN 0x22 37 - #define DFGT2_REV_MIN 0x26 38 - #define DFP_REV_MAJ 0x11 39 - #define DFP_REV_MIN 0x06 40 - #define FFEX_REV_MAJ 0x21 41 - #define FFEX_REV_MIN 0x00 42 - #define G25_REV_MAJ 0x12 43 - #define G25_REV_MIN 0x22 44 - #define G27_REV_MAJ 0x12 45 - #define G27_REV_MIN 0x38 46 - #define G27_2_REV_MIN 0x39 47 - 48 36 #define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) 37 + 38 + #define LG4FF_MMODE_IS_MULTIMODE 0 39 + #define LG4FF_MMODE_SWITCHED 1 40 + #define LG4FF_MMODE_NOT_MULTIMODE 2 41 + 42 + #define LG4FF_MODE_NATIVE_IDX 0 43 + #define LG4FF_MODE_DFEX_IDX 1 44 + #define LG4FF_MODE_DFP_IDX 2 45 + #define LG4FF_MODE_G25_IDX 3 46 + #define LG4FF_MODE_DFGT_IDX 4 47 + #define LG4FF_MODE_G27_IDX 5 48 + #define LG4FF_MODE_MAX_IDX 6 49 + 50 + #define LG4FF_MODE_NATIVE BIT(LG4FF_MODE_NATIVE_IDX) 51 + #define LG4FF_MODE_DFEX BIT(LG4FF_MODE_DFEX_IDX) 52 + #define LG4FF_MODE_DFP BIT(LG4FF_MODE_DFP_IDX) 53 + #define LG4FF_MODE_G25 BIT(LG4FF_MODE_G25_IDX) 54 + #define LG4FF_MODE_DFGT BIT(LG4FF_MODE_DFGT_IDX) 55 + #define LG4FF_MODE_G27 BIT(LG4FF_MODE_G27_IDX) 56 + 57 + #define LG4FF_DFEX_TAG "DF-EX" 58 + #define LG4FF_DFEX_NAME "Driving Force / Formula EX" 59 + #define LG4FF_DFP_TAG "DFP" 60 + #define LG4FF_DFP_NAME "Driving Force Pro" 61 + #define LG4FF_G25_TAG "G25" 62 + #define LG4FF_G25_NAME "G25 Racing Wheel" 63 + #define LG4FF_G27_TAG "G27" 64 + #define LG4FF_G27_NAME "G27 Racing Wheel" 65 + #define LG4FF_DFGT_TAG "DFGT" 66 + #define LG4FF_DFGT_NAME "Driving Force GT" 67 + 68 + #define LG4FF_FFEX_REV_MAJ 0x21 69 + #define LG4FF_FFEX_REV_MIN 0x00 49 70 50 71 static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range); 51 72 static void hid_lg4ff_set_range_g25(struct hid_device *hid, u16 range); ··· 80 59 __u8 led_state; 81 60 struct led_classdev *led[5]; 82 61 #endif 62 + u32 alternate_modes; 63 + const char *real_tag; 64 + const char *real_name; 65 + u16 real_product_id; 83 66 struct list_head list; 84 67 void (*set_range)(struct hid_device *hid, u16 range); 85 68 }; ··· 102 77 void (*set_range)(struct hid_device *hid, u16 range); 103 78 }; 104 79 80 + struct lg4ff_compat_mode_switch { 81 + const __u8 cmd_count; /* Number of commands to send */ 82 + const __u8 cmd[]; 83 + }; 84 + 85 + struct lg4ff_wheel_ident_info { 86 + const u16 mask; 87 + const u16 result; 88 + const u16 real_product_id; 89 + }; 90 + 91 + struct lg4ff_wheel_ident_checklist { 92 + const u32 count; 93 + const struct lg4ff_wheel_ident_info *models[]; 94 + }; 95 + 96 + struct lg4ff_multimode_wheel { 97 + const u16 product_id; 98 + const u32 alternate_modes; 99 + const char *real_tag; 100 + const char *real_name; 101 + }; 102 + 103 + struct lg4ff_alternate_mode { 104 + const u16 product_id; 105 + const char *tag; 106 + const char *name; 107 + }; 108 + 105 109 static const struct lg4ff_wheel lg4ff_devices[] = { 106 110 {USB_DEVICE_ID_LOGITECH_WHEEL, lg4ff_wheel_effects, 40, 270, NULL}, 107 111 {USB_DEVICE_ID_LOGITECH_MOMO_WHEEL, lg4ff_wheel_effects, 40, 270, NULL}, ··· 142 88 {USB_DEVICE_ID_LOGITECH_WII_WHEEL, lg4ff_wheel_effects, 40, 270, NULL} 143 89 }; 144 90 145 - struct lg4ff_native_cmd { 146 - const __u8 cmd_num; /* Number of commands to send */ 147 - const __u8 cmd[]; 91 + static const struct lg4ff_multimode_wheel lg4ff_multimode_wheels[] = { 92 + {USB_DEVICE_ID_LOGITECH_DFP_WHEEL, 93 + LG4FF_MODE_NATIVE | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 94 + LG4FF_DFP_TAG, LG4FF_DFP_NAME}, 95 + {USB_DEVICE_ID_LOGITECH_G25_WHEEL, 96 + LG4FF_MODE_NATIVE | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 97 + LG4FF_G25_TAG, LG4FF_G25_NAME}, 98 + {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, 99 + LG4FF_MODE_NATIVE | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 100 + LG4FF_DFGT_TAG, LG4FF_DFGT_NAME}, 101 + {USB_DEVICE_ID_LOGITECH_G27_WHEEL, 102 + LG4FF_MODE_NATIVE | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 103 + LG4FF_G27_TAG, LG4FF_G27_NAME}, 148 104 }; 149 105 150 - struct lg4ff_usb_revision { 151 - const __u16 rev_maj; 152 - const __u16 rev_min; 153 - const struct lg4ff_native_cmd *command; 106 + static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = { 107 + [LG4FF_MODE_NATIVE_IDX] = {0, "native", ""}, 108 + [LG4FF_MODE_DFEX_IDX] = {USB_DEVICE_ID_LOGITECH_WHEEL, LG4FF_DFEX_TAG, LG4FF_DFEX_NAME}, 109 + [LG4FF_MODE_DFP_IDX] = {USB_DEVICE_ID_LOGITECH_DFP_WHEEL, LG4FF_DFP_TAG, LG4FF_DFP_NAME}, 110 + [LG4FF_MODE_G25_IDX] = {USB_DEVICE_ID_LOGITECH_G25_WHEEL, LG4FF_G25_TAG, LG4FF_G25_NAME}, 111 + [LG4FF_MODE_DFGT_IDX] = {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, LG4FF_DFGT_TAG, LG4FF_DFGT_NAME}, 112 + [LG4FF_MODE_G27_IDX] = {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_G27_TAG, LG4FF_G27_NAME} 154 113 }; 155 114 156 - static const struct lg4ff_native_cmd native_dfp = { 115 + /* Multimode wheel identificators */ 116 + static const struct lg4ff_wheel_ident_info lg4ff_dfp_ident_info = { 117 + 0xf000, 118 + 0x1000, 119 + USB_DEVICE_ID_LOGITECH_DFP_WHEEL 120 + }; 121 + 122 + static const struct lg4ff_wheel_ident_info lg4ff_g25_ident_info = { 123 + 0xff00, 124 + 0x1200, 125 + USB_DEVICE_ID_LOGITECH_G25_WHEEL 126 + }; 127 + 128 + static const struct lg4ff_wheel_ident_info lg4ff_g27_ident_info = { 129 + 0xfff0, 130 + 0x1230, 131 + USB_DEVICE_ID_LOGITECH_G27_WHEEL 132 + }; 133 + 134 + static const struct lg4ff_wheel_ident_info lg4ff_dfgt_ident_info = { 135 + 0xff00, 136 + 0x1300, 137 + USB_DEVICE_ID_LOGITECH_DFGT_WHEEL 138 + }; 139 + 140 + /* Multimode wheel identification checklists */ 141 + static const struct lg4ff_wheel_ident_checklist lg4ff_main_checklist = { 142 + 4, 143 + {&lg4ff_dfgt_ident_info, 144 + &lg4ff_g27_ident_info, 145 + &lg4ff_g25_ident_info, 146 + &lg4ff_dfp_ident_info} 147 + }; 148 + 149 + /* Compatibility mode switching commands */ 150 + /* EXT_CMD9 - Understood by G27 and DFGT */ 151 + static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_dfex = { 152 + 2, 153 + {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, /* Revert mode upon USB reset */ 154 + 0xf8, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00} /* Switch mode to DF-EX with detach */ 155 + }; 156 + 157 + static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_dfp = { 158 + 2, 159 + {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, /* Revert mode upon USB reset */ 160 + 0xf8, 0x09, 0x01, 0x01, 0x00, 0x00, 0x00} /* Switch mode to DFP with detach */ 161 + }; 162 + 163 + static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_g25 = { 164 + 2, 165 + {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, /* Revert mode upon USB reset */ 166 + 0xf8, 0x09, 0x02, 0x01, 0x00, 0x00, 0x00} /* Switch mode to G25 with detach */ 167 + }; 168 + 169 + static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_dfgt = { 170 + 2, 171 + {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, /* Revert mode upon USB reset */ 172 + 0xf8, 0x09, 0x03, 0x01, 0x00, 0x00, 0x00} /* Switch mode to DFGT with detach */ 173 + }; 174 + 175 + static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_g27 = { 176 + 2, 177 + {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, /* Revert mode upon USB reset */ 178 + 0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00} /* Switch mode to G27 with detach */ 179 + }; 180 + 181 + /* EXT_CMD1 - Understood by DFP, G25, G27 and DFGT */ 182 + static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext01_dfp = { 157 183 1, 158 184 {0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00} 159 185 }; 160 186 161 - static const struct lg4ff_native_cmd native_dfgt = { 162 - 2, 163 - {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1st command */ 164 - 0xf8, 0x09, 0x03, 0x01, 0x00, 0x00, 0x00} /* 2nd command */ 165 - }; 166 - 167 - static const struct lg4ff_native_cmd native_g25 = { 187 + /* EXT_CMD16 - Understood by G25 and G27 */ 188 + static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext16_g25 = { 168 189 1, 169 190 {0xf8, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00} 170 - }; 171 - 172 - static const struct lg4ff_native_cmd native_g27 = { 173 - 2, 174 - {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1st command */ 175 - 0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00} /* 2nd command */ 176 - }; 177 - 178 - static const struct lg4ff_usb_revision lg4ff_revs[] = { 179 - {DFGT_REV_MAJ, DFGT_REV_MIN, &native_dfgt}, /* Driving Force GT */ 180 - {DFGT_REV_MAJ, DFGT2_REV_MIN, &native_dfgt}, /* Driving Force GT v2 */ 181 - {DFP_REV_MAJ, DFP_REV_MIN, &native_dfp}, /* Driving Force Pro */ 182 - {G25_REV_MAJ, G25_REV_MIN, &native_g25}, /* G25 */ 183 - {G27_REV_MAJ, G27_REV_MIN, &native_g27}, /* G27 */ 184 - {G27_REV_MAJ, G27_2_REV_MIN, &native_g27}, /* G27 v2 */ 185 191 }; 186 192 187 193 /* Recalculates X axis value accordingly to currently selected range */ ··· 510 396 hid_hw_request(hid, report, HID_REQ_SET_REPORT); 511 397 } 512 398 513 - static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_native_cmd *cmd) 399 + static const struct lg4ff_compat_mode_switch *lg4ff_get_mode_switch_command(const u16 real_product_id, const u16 target_product_id) 400 + { 401 + switch (real_product_id) { 402 + case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: 403 + switch (target_product_id) { 404 + case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: 405 + return &lg4ff_mode_switch_ext01_dfp; 406 + /* DFP can only be switched to its native mode */ 407 + default: 408 + return NULL; 409 + } 410 + break; 411 + case USB_DEVICE_ID_LOGITECH_G25_WHEEL: 412 + switch (target_product_id) { 413 + case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: 414 + return &lg4ff_mode_switch_ext01_dfp; 415 + case USB_DEVICE_ID_LOGITECH_G25_WHEEL: 416 + return &lg4ff_mode_switch_ext16_g25; 417 + /* G25 can only be switched to DFP mode or its native mode */ 418 + default: 419 + return NULL; 420 + } 421 + break; 422 + case USB_DEVICE_ID_LOGITECH_G27_WHEEL: 423 + switch (target_product_id) { 424 + case USB_DEVICE_ID_LOGITECH_WHEEL: 425 + return &lg4ff_mode_switch_ext09_dfex; 426 + case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: 427 + return &lg4ff_mode_switch_ext09_dfp; 428 + case USB_DEVICE_ID_LOGITECH_G25_WHEEL: 429 + return &lg4ff_mode_switch_ext09_g25; 430 + case USB_DEVICE_ID_LOGITECH_G27_WHEEL: 431 + return &lg4ff_mode_switch_ext09_g27; 432 + /* G27 can only be switched to DF-EX, DFP, G25 or its native mode */ 433 + default: 434 + return NULL; 435 + } 436 + break; 437 + case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL: 438 + switch (target_product_id) { 439 + case USB_DEVICE_ID_LOGITECH_WHEEL: 440 + return &lg4ff_mode_switch_ext09_dfex; 441 + case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: 442 + return &lg4ff_mode_switch_ext09_dfp; 443 + case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL: 444 + return &lg4ff_mode_switch_ext09_dfgt; 445 + /* DFGT can only be switched to DF-EX, DFP or its native mode */ 446 + default: 447 + return NULL; 448 + } 449 + break; 450 + /* No other wheels have multiple modes */ 451 + default: 452 + return NULL; 453 + } 454 + } 455 + 456 + static int lg4ff_switch_compatibility_mode(struct hid_device *hid, const struct lg4ff_compat_mode_switch *s) 514 457 { 515 458 struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; 516 459 struct hid_report *report = list_entry(report_list->next, struct hid_report, list); 517 - __u8 i, j; 460 + __s32 *value = report->field[0]->value; 461 + u8 i; 518 462 519 - j = 0; 520 - while (j < 7*cmd->cmd_num) { 521 - for (i = 0; i < 7; i++) 522 - report->field[0]->value[i] = cmd->cmd[j++]; 463 + for (i = 0; i < s->cmd_count; i++) { 464 + u8 j; 465 + 466 + for (j = 0; j < 7; j++) 467 + value[j] = s->cmd[j + (7*i)]; 523 468 524 469 hid_hw_request(hid, report, HID_REQ_SET_REPORT); 525 470 } 471 + hid_hw_wait(hid); 472 + return 0; 526 473 } 474 + 475 + static ssize_t lg4ff_alternate_modes_show(struct device *dev, struct device_attribute *attr, char *buf) 476 + { 477 + struct hid_device *hid = to_hid_device(dev); 478 + struct lg4ff_device_entry *entry; 479 + struct lg_drv_data *drv_data; 480 + ssize_t count = 0; 481 + int i; 482 + 483 + drv_data = hid_get_drvdata(hid); 484 + if (!drv_data) { 485 + hid_err(hid, "Private driver data not found!\n"); 486 + return 0; 487 + } 488 + 489 + entry = drv_data->device_props; 490 + if (!entry) { 491 + hid_err(hid, "Device properties not found!\n"); 492 + return 0; 493 + } 494 + 495 + if (!entry->real_name) { 496 + hid_err(hid, "NULL pointer to string\n"); 497 + return 0; 498 + } 499 + 500 + for (i = 0; i < LG4FF_MODE_MAX_IDX; i++) { 501 + if (entry->alternate_modes & BIT(i)) { 502 + /* Print tag and full name */ 503 + count += scnprintf(buf + count, PAGE_SIZE - count, "%s: %s", 504 + lg4ff_alternate_modes[i].tag, 505 + !lg4ff_alternate_modes[i].product_id ? entry->real_name : lg4ff_alternate_modes[i].name); 506 + if (count >= PAGE_SIZE - 1) 507 + return count; 508 + 509 + /* Mark the currently active mode with an asterisk */ 510 + if (lg4ff_alternate_modes[i].product_id == entry->product_id || 511 + (lg4ff_alternate_modes[i].product_id == 0 && entry->product_id == entry->real_product_id)) 512 + count += scnprintf(buf + count, PAGE_SIZE - count, " *\n"); 513 + else 514 + count += scnprintf(buf + count, PAGE_SIZE - count, "\n"); 515 + 516 + if (count >= PAGE_SIZE - 1) 517 + return count; 518 + } 519 + } 520 + 521 + return count; 522 + } 523 + 524 + static ssize_t lg4ff_alternate_modes_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 525 + { 526 + struct hid_device *hid = to_hid_device(dev); 527 + struct lg4ff_device_entry *entry; 528 + struct lg_drv_data *drv_data; 529 + const struct lg4ff_compat_mode_switch *s; 530 + u16 target_product_id = 0; 531 + int i, ret; 532 + char *lbuf; 533 + 534 + drv_data = hid_get_drvdata(hid); 535 + if (!drv_data) { 536 + hid_err(hid, "Private driver data not found!\n"); 537 + return -EINVAL; 538 + } 539 + 540 + entry = drv_data->device_props; 541 + if (!entry) { 542 + hid_err(hid, "Device properties not found!\n"); 543 + return -EINVAL; 544 + } 545 + 546 + /* Allow \n at the end of the input parameter */ 547 + lbuf = kasprintf(GFP_KERNEL, "%s", buf); 548 + if (!lbuf) 549 + return -ENOMEM; 550 + 551 + i = strlen(lbuf); 552 + if (lbuf[i-1] == '\n') { 553 + if (i == 1) { 554 + kfree(lbuf); 555 + return -EINVAL; 556 + } 557 + lbuf[i-1] = '\0'; 558 + } 559 + 560 + for (i = 0; i < LG4FF_MODE_MAX_IDX; i++) { 561 + const u16 mode_product_id = lg4ff_alternate_modes[i].product_id; 562 + const char *tag = lg4ff_alternate_modes[i].tag; 563 + 564 + if (entry->alternate_modes & BIT(i)) { 565 + if (!strcmp(tag, lbuf)) { 566 + if (!mode_product_id) 567 + target_product_id = entry->real_product_id; 568 + else 569 + target_product_id = mode_product_id; 570 + break; 571 + } 572 + } 573 + } 574 + 575 + if (i == LG4FF_MODE_MAX_IDX) { 576 + hid_info(hid, "Requested mode \"%s\" is not supported by the device\n", lbuf); 577 + kfree(lbuf); 578 + return -EINVAL; 579 + } 580 + kfree(lbuf); /* Not needed anymore */ 581 + 582 + if (target_product_id == entry->product_id) /* Nothing to do */ 583 + return count; 584 + 585 + /* Automatic switching has to be disabled for the switch to DF-EX mode to work correctly */ 586 + if (target_product_id == USB_DEVICE_ID_LOGITECH_WHEEL && !lg4ff_no_autoswitch) { 587 + hid_info(hid, "\"%s\" cannot be switched to \"DF-EX\" mode. Load the \"hid_logitech\" module with \"lg4ff_no_autoswitch=1\" parameter set and try again\n", 588 + entry->real_name); 589 + return -EINVAL; 590 + } 591 + 592 + /* Take care of hardware limitations */ 593 + if ((entry->real_product_id == USB_DEVICE_ID_LOGITECH_DFP_WHEEL || entry->real_product_id == USB_DEVICE_ID_LOGITECH_G25_WHEEL) && 594 + entry->product_id > target_product_id) { 595 + hid_info(hid, "\"%s\" cannot be switched back into \"%s\" mode\n", entry->real_name, lg4ff_alternate_modes[i].name); 596 + return -EINVAL; 597 + } 598 + 599 + s = lg4ff_get_mode_switch_command(entry->real_product_id, target_product_id); 600 + if (!s) { 601 + hid_err(hid, "Invalid target product ID %X\n", target_product_id); 602 + return -EINVAL; 603 + } 604 + 605 + ret = lg4ff_switch_compatibility_mode(hid, s); 606 + return (ret == 0 ? count : ret); 607 + } 608 + static DEVICE_ATTR(alternate_modes, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, lg4ff_alternate_modes_show, lg4ff_alternate_modes_store); 527 609 528 610 /* Read current range and display it in terminal */ 529 611 static ssize_t range_show(struct device *dev, struct device_attribute *attr, ··· 781 471 return count; 782 472 } 783 473 static DEVICE_ATTR_RW(range); 474 + 475 + static ssize_t lg4ff_real_id_show(struct device *dev, struct device_attribute *attr, char *buf) 476 + { 477 + struct hid_device *hid = to_hid_device(dev); 478 + struct lg4ff_device_entry *entry; 479 + struct lg_drv_data *drv_data; 480 + size_t count; 481 + 482 + drv_data = hid_get_drvdata(hid); 483 + if (!drv_data) { 484 + hid_err(hid, "Private driver data not found!\n"); 485 + return 0; 486 + } 487 + 488 + entry = drv_data->device_props; 489 + if (!entry) { 490 + hid_err(hid, "Device properties not found!\n"); 491 + return 0; 492 + } 493 + 494 + if (!entry->real_tag || !entry->real_name) { 495 + hid_err(hid, "NULL pointer to string\n"); 496 + return 0; 497 + } 498 + 499 + count = scnprintf(buf, PAGE_SIZE, "%s: %s\n", entry->real_tag, entry->real_name); 500 + return count; 501 + } 502 + 503 + static ssize_t lg4ff_real_id_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 504 + { 505 + /* Real ID is a read-only value */ 506 + return -EPERM; 507 + } 508 + static DEVICE_ATTR(real_id, S_IRUGO, lg4ff_real_id_show, lg4ff_real_id_store); 784 509 785 510 #ifdef CONFIG_LEDS_CLASS 786 511 static void lg4ff_set_leds(struct hid_device *hid, __u8 leds) ··· 900 555 } 901 556 #endif 902 557 558 + static u16 lg4ff_identify_multimode_wheel(struct hid_device *hid, const u16 reported_product_id, const u16 bcdDevice) 559 + { 560 + const struct lg4ff_wheel_ident_checklist *checklist; 561 + int i, from_idx, to_idx; 562 + 563 + switch (reported_product_id) { 564 + case USB_DEVICE_ID_LOGITECH_WHEEL: 565 + case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: 566 + checklist = &lg4ff_main_checklist; 567 + from_idx = 0; 568 + to_idx = checklist->count - 1; 569 + break; 570 + case USB_DEVICE_ID_LOGITECH_G25_WHEEL: 571 + checklist = &lg4ff_main_checklist; 572 + from_idx = 0; 573 + to_idx = checklist->count - 2; /* End identity check at G25 */ 574 + break; 575 + case USB_DEVICE_ID_LOGITECH_G27_WHEEL: 576 + checklist = &lg4ff_main_checklist; 577 + from_idx = 1; /* Start identity check at G27 */ 578 + to_idx = checklist->count - 3; /* End identity check at G27 */ 579 + break; 580 + case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL: 581 + checklist = &lg4ff_main_checklist; 582 + from_idx = 0; 583 + to_idx = checklist->count - 4; /* End identity check at DFGT */ 584 + break; 585 + default: 586 + return 0; 587 + } 588 + 589 + for (i = from_idx; i <= to_idx; i++) { 590 + const u16 mask = checklist->models[i]->mask; 591 + const u16 result = checklist->models[i]->result; 592 + const u16 real_product_id = checklist->models[i]->real_product_id; 593 + 594 + if ((bcdDevice & mask) == result) { 595 + dbg_hid("Found wheel with real PID %X whose reported PID is %X\n", real_product_id, reported_product_id); 596 + return real_product_id; 597 + } 598 + } 599 + 600 + /* No match found. This is either Driving Force or an unknown 601 + * wheel model, do not touch it */ 602 + dbg_hid("Wheel with bcdDevice %X was not recognized as multimode wheel, leaving in its current mode\n", bcdDevice); 603 + return 0; 604 + } 605 + 606 + static int lg4ff_handle_multimode_wheel(struct hid_device *hid, u16 *real_product_id, const u16 bcdDevice) 607 + { 608 + const u16 reported_product_id = hid->product; 609 + int ret; 610 + 611 + *real_product_id = lg4ff_identify_multimode_wheel(hid, reported_product_id, bcdDevice); 612 + /* Probed wheel is not a multimode wheel */ 613 + if (!*real_product_id) { 614 + *real_product_id = reported_product_id; 615 + dbg_hid("Wheel is not a multimode wheel\n"); 616 + return LG4FF_MMODE_NOT_MULTIMODE; 617 + } 618 + 619 + /* Switch from "Driving Force" mode to native mode automatically. 620 + * Otherwise keep the wheel in its current mode */ 621 + if (reported_product_id == USB_DEVICE_ID_LOGITECH_WHEEL && 622 + reported_product_id != *real_product_id && 623 + !lg4ff_no_autoswitch) { 624 + const struct lg4ff_compat_mode_switch *s = lg4ff_get_mode_switch_command(*real_product_id, *real_product_id); 625 + 626 + if (!s) { 627 + hid_err(hid, "Invalid product id %X\n", *real_product_id); 628 + return LG4FF_MMODE_NOT_MULTIMODE; 629 + } 630 + 631 + ret = lg4ff_switch_compatibility_mode(hid, s); 632 + if (ret) { 633 + /* Wheel could not have been switched to native mode, 634 + * leave it in "Driving Force" mode and continue */ 635 + hid_err(hid, "Unable to switch wheel mode, errno %d\n", ret); 636 + return LG4FF_MMODE_IS_MULTIMODE; 637 + } 638 + return LG4FF_MMODE_SWITCHED; 639 + } 640 + 641 + return LG4FF_MMODE_IS_MULTIMODE; 642 + } 643 + 644 + 903 645 int lg4ff_init(struct hid_device *hid) 904 646 { 905 647 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); 906 648 struct input_dev *dev = hidinput->input; 649 + const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor); 650 + const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice); 907 651 struct lg4ff_device_entry *entry; 908 652 struct lg_drv_data *drv_data; 909 - struct usb_device_descriptor *udesc; 910 653 int error, i, j; 911 - __u16 bcdDevice, rev_maj, rev_min; 654 + int mmode_ret, mmode_idx = -1; 655 + u16 real_product_id; 912 656 913 657 /* Check that the report looks ok */ 914 658 if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) 915 659 return -1; 660 + 661 + /* Check if a multimode wheel has been connected and 662 + * handle it appropriately */ 663 + mmode_ret = lg4ff_handle_multimode_wheel(hid, &real_product_id, bcdDevice); 664 + 665 + /* Wheel has been told to switch to native mode. There is no point in going on 666 + * with the initialization as the wheel will do a USB reset when it switches mode 667 + */ 668 + if (mmode_ret == LG4FF_MMODE_SWITCHED) 669 + return 0; 916 670 917 671 /* Check what wheel has been connected */ 918 672 for (i = 0; i < ARRAY_SIZE(lg4ff_devices); i++) { ··· 1027 583 return -1; 1028 584 } 1029 585 1030 - /* Attempt to switch wheel to native mode when applicable */ 1031 - udesc = &(hid_to_usb_dev(hid)->descriptor); 1032 - if (!udesc) { 1033 - hid_err(hid, "NULL USB device descriptor\n"); 1034 - return -1; 1035 - } 1036 - bcdDevice = le16_to_cpu(udesc->bcdDevice); 1037 - rev_maj = bcdDevice >> 8; 1038 - rev_min = bcdDevice & 0xff; 586 + if (mmode_ret == LG4FF_MMODE_IS_MULTIMODE) { 587 + for (mmode_idx = 0; mmode_idx < ARRAY_SIZE(lg4ff_multimode_wheels); mmode_idx++) { 588 + if (real_product_id == lg4ff_multimode_wheels[mmode_idx].product_id) 589 + break; 590 + } 1039 591 1040 - if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_WHEEL) { 1041 - dbg_hid("Generic wheel detected, can it do native?\n"); 1042 - dbg_hid("USB revision: %2x.%02x\n", rev_maj, rev_min); 1043 - 1044 - for (j = 0; j < ARRAY_SIZE(lg4ff_revs); j++) { 1045 - if (lg4ff_revs[j].rev_maj == rev_maj && lg4ff_revs[j].rev_min == rev_min) { 1046 - hid_lg4ff_switch_native(hid, lg4ff_revs[j].command); 1047 - hid_info(hid, "Switched to native mode\n"); 1048 - } 592 + if (mmode_idx == ARRAY_SIZE(lg4ff_multimode_wheels)) { 593 + hid_err(hid, "Device product ID %X is not listed as a multimode wheel", real_product_id); 594 + return -1; 1049 595 } 1050 596 } 1051 597 ··· 1064 630 drv_data->device_props = entry; 1065 631 1066 632 entry->product_id = lg4ff_devices[i].product_id; 633 + entry->real_product_id = real_product_id; 1067 634 entry->min_range = lg4ff_devices[i].min_range; 1068 635 entry->max_range = lg4ff_devices[i].max_range; 1069 636 entry->set_range = lg4ff_devices[i].set_range; 637 + if (mmode_ret == LG4FF_MMODE_IS_MULTIMODE) { 638 + BUG_ON(mmode_idx == -1); 639 + entry->alternate_modes = lg4ff_multimode_wheels[mmode_idx].alternate_modes; 640 + entry->real_tag = lg4ff_multimode_wheels[mmode_idx].real_tag; 641 + entry->real_name = lg4ff_multimode_wheels[mmode_idx].real_name; 642 + } 1070 643 1071 644 /* Check if autocentering is available and 1072 645 * set the centering force to zero by default */ 1073 646 if (test_bit(FF_AUTOCENTER, dev->ffbit)) { 1074 - if (rev_maj == FFEX_REV_MAJ && rev_min == FFEX_REV_MIN) /* Formula Force EX expects different autocentering command */ 647 + /* Formula Force EX expects different autocentering command */ 648 + if ((bcdDevice >> 8) == LG4FF_FFEX_REV_MAJ && 649 + (bcdDevice & 0xff) == LG4FF_FFEX_REV_MIN) 1075 650 dev->ff->set_autocenter = hid_lg4ff_set_autocenter_ffex; 1076 651 else 1077 652 dev->ff->set_autocenter = hid_lg4ff_set_autocenter_default; ··· 1092 649 error = device_create_file(&hid->dev, &dev_attr_range); 1093 650 if (error) 1094 651 return error; 652 + if (mmode_ret == LG4FF_MMODE_IS_MULTIMODE) { 653 + error = device_create_file(&hid->dev, &dev_attr_real_id); 654 + if (error) 655 + return error; 656 + error = device_create_file(&hid->dev, &dev_attr_alternate_modes); 657 + if (error) 658 + return error; 659 + } 1095 660 dbg_hid("sysfs interface created\n"); 1096 661 1097 662 /* Set the maximum range to start with */ ··· 1162 711 return 0; 1163 712 } 1164 713 1165 - 1166 - 1167 714 int lg4ff_deinit(struct hid_device *hid) 1168 715 { 1169 716 struct lg4ff_device_entry *entry; 1170 717 struct lg_drv_data *drv_data; 1171 - 1172 - device_remove_file(&hid->dev, &dev_attr_range); 1173 718 1174 719 drv_data = hid_get_drvdata(hid); 1175 720 if (!drv_data) { ··· 1173 726 return -1; 1174 727 } 1175 728 entry = drv_data->device_props; 1176 - if (!entry) { 1177 - hid_err(hid, "Error while deinitializing device, no device properties data.\n"); 1178 - return -1; 729 + if (!entry) 730 + goto out; /* Nothing more to do */ 731 + 732 + device_remove_file(&hid->dev, &dev_attr_range); 733 + 734 + /* Multimode devices will have at least the "MODE_NATIVE" bit set */ 735 + if (entry->alternate_modes) { 736 + device_remove_file(&hid->dev, &dev_attr_real_id); 737 + device_remove_file(&hid->dev, &dev_attr_alternate_modes); 1179 738 } 1180 739 1181 740 #ifdef CONFIG_LEDS_CLASS ··· 1205 752 /* Deallocate memory */ 1206 753 kfree(entry); 1207 754 755 + out: 1208 756 dbg_hid("Device successfully unregistered\n"); 1209 757 return 0; 1210 758 }
+18
drivers/hid/hid-lg4ff.h
··· 1 + #ifndef __HID_LG4FF_H 2 + #define __HID_LG4FF_H 3 + 4 + #ifdef CONFIG_LOGIWHEELS_FF 5 + extern int lg4ff_no_autoswitch; /* From hid-lg.c */ 6 + 7 + int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field, 8 + struct hid_usage *usage, __s32 value, struct lg_drv_data *drv_data); 9 + int lg4ff_init(struct hid_device *hdev); 10 + int lg4ff_deinit(struct hid_device *hdev); 11 + #else 12 + static inline int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field, 13 + struct hid_usage *usage, __s32 value, struct lg_drv_data *drv_data) { return 0; } 14 + static inline int lg4ff_init(struct hid_device *hdev) { return -1; } 15 + static inline int lg4ff_deinit(struct hid_device *hdev) { return -1; } 16 + #endif 17 + 18 + #endif
+11
drivers/hid/hid-logitech-hidpp.c
··· 28 28 MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>"); 29 29 MODULE_AUTHOR("Nestor Lopez Casado <nlopezcasad@logitech.com>"); 30 30 31 + static bool disable_raw_mode; 32 + module_param(disable_raw_mode, bool, 0644); 33 + MODULE_PARM_DESC(disable_raw_mode, 34 + "Disable Raw mode reporting for touchpads and keep firmware gestures."); 35 + 31 36 #define REPORT_ID_HIDPP_SHORT 0x10 32 37 #define REPORT_ID_HIDPP_LONG 0x11 33 38 ··· 1193 1188 1194 1189 hidpp->quirks = id->driver_data; 1195 1190 1191 + if (disable_raw_mode) { 1192 + hidpp->quirks &= ~HIDPP_QUIRK_CLASS_WTP; 1193 + hidpp->quirks &= ~HIDPP_QUIRK_DELAYED_INIT; 1194 + } 1195 + 1196 1196 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { 1197 1197 ret = wtp_allocate(hdev, id); 1198 1198 if (ret) ··· 1220 1210 connected = hidpp_is_connected(hidpp); 1221 1211 if (id->group != HID_GROUP_LOGITECH_DJ_DEVICE) { 1222 1212 if (!connected) { 1213 + ret = -ENODEV; 1223 1214 hid_err(hdev, "Device not connected"); 1224 1215 hid_device_io_stop(hdev); 1225 1216 goto hid_parse_fail;
+25 -1
drivers/hid/hid-multitouch.c
··· 42 42 #include <linux/hid.h> 43 43 #include <linux/module.h> 44 44 #include <linux/slab.h> 45 - #include <linux/usb.h> 46 45 #include <linux/input/mt.h> 47 46 #include <linux/string.h> 48 47 ··· 70 71 71 72 #define MT_INPUTMODE_TOUCHSCREEN 0x02 72 73 #define MT_INPUTMODE_TOUCHPAD 0x03 74 + 75 + #define MT_BUTTONTYPE_CLICKPAD 0 73 76 74 77 struct mt_slot { 75 78 __s32 x, y, cx, cy, p, w, h; ··· 117 116 __u8 touches_by_report; /* how many touches are present in one report: 118 117 * 1 means we should use a serial protocol 119 118 * > 1 means hybrid (multitouch) protocol */ 119 + __u8 buttons_count; /* number of physical buttons per touchpad */ 120 + bool is_buttonpad; /* is this device a button pad? */ 120 121 bool serial_maybe; /* need to check for serial protocol */ 121 122 bool curvalid; /* is the current contact valid? */ 122 123 unsigned mt_flags; /* flags to pass to input-mt */ ··· 337 334 td->maxcontacts = td->mtclass.maxcontacts; 338 335 339 336 break; 337 + case HID_DG_BUTTONTYPE: 338 + if (usage->usage_index >= field->report_count) { 339 + dev_err(&hdev->dev, "HID_DG_BUTTONTYPE out of range\n"); 340 + break; 341 + } 342 + 343 + if (field->value[usage->usage_index] == MT_BUTTONTYPE_CLICKPAD) 344 + td->is_buttonpad = true; 345 + 346 + break; 340 347 } 341 348 } 342 349 ··· 391 378 td->mt_flags |= INPUT_MT_POINTER; 392 379 td->inputmode_value = MT_INPUTMODE_TOUCHPAD; 393 380 } 381 + 382 + /* count the buttons on touchpads */ 383 + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) 384 + td->buttons_count++; 394 385 395 386 if (usage->usage_index) 396 387 prev_usage = &field->usage[usage->usage_index - 1]; ··· 744 727 745 728 if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) 746 729 td->mt_flags |= INPUT_MT_DROP_UNUSED; 730 + 731 + /* check for clickpads */ 732 + if ((td->mt_flags & INPUT_MT_POINTER) && (td->buttons_count == 1)) 733 + td->is_buttonpad = true; 734 + 735 + if (td->is_buttonpad) 736 + __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); 747 737 748 738 input_mt_init_slots(input, td->maxcontacts, td->mt_flags); 749 739
+174 -3
drivers/hid/hid-rmi.c
··· 104 104 105 105 unsigned long flags; 106 106 107 + struct rmi_function f01; 107 108 struct rmi_function f11; 108 109 struct rmi_function f30; 109 110 ··· 125 124 struct hid_device *hdev; 126 125 127 126 unsigned long device_flags; 127 + unsigned long firmware_id; 128 128 }; 129 129 130 130 #define RMI_PAGE(addr) (((addr) >> 8) & 0xff) ··· 272 270 static inline int rmi_read(struct hid_device *hdev, u16 addr, void *buf) 273 271 { 274 272 return rmi_read_block(hdev, addr, buf, 1); 273 + } 274 + 275 + static int rmi_write_block(struct hid_device *hdev, u16 addr, void *buf, 276 + const int len) 277 + { 278 + struct rmi_data *data = hid_get_drvdata(hdev); 279 + int ret; 280 + 281 + mutex_lock(&data->page_mutex); 282 + 283 + if (RMI_PAGE(addr) != data->page) { 284 + ret = rmi_set_page(hdev, RMI_PAGE(addr)); 285 + if (ret < 0) 286 + goto exit; 287 + } 288 + 289 + data->writeReport[0] = RMI_WRITE_REPORT_ID; 290 + data->writeReport[1] = len; 291 + data->writeReport[2] = addr & 0xFF; 292 + data->writeReport[3] = (addr >> 8) & 0xFF; 293 + memcpy(&data->writeReport[4], buf, len); 294 + 295 + ret = rmi_write_report(hdev, data->writeReport, 296 + data->output_report_size); 297 + if (ret < 0) { 298 + dev_err(&hdev->dev, 299 + "failed to write request output report (%d)\n", 300 + ret); 301 + goto exit; 302 + } 303 + ret = 0; 304 + 305 + exit: 306 + mutex_unlock(&data->page_mutex); 307 + return ret; 308 + } 309 + 310 + static inline int rmi_write(struct hid_device *hdev, u16 addr, void *buf) 311 + { 312 + return rmi_write_block(hdev, addr, buf, 1); 275 313 } 276 314 277 315 static void rmi_f11_process_touch(struct rmi_data *hdata, int slot, ··· 574 532 u16 page_base = page << 8; 575 533 576 534 switch (pdt_entry->function_number) { 535 + case 0x01: 536 + f = &data->f01; 537 + break; 577 538 case 0x11: 578 539 f = &data->f11; 579 540 break; ··· 649 604 return retval; 650 605 } 651 606 607 + #define RMI_DEVICE_F01_BASIC_QUERY_LEN 11 608 + 609 + static int rmi_populate_f01(struct hid_device *hdev) 610 + { 611 + struct rmi_data *data = hid_get_drvdata(hdev); 612 + u8 basic_queries[RMI_DEVICE_F01_BASIC_QUERY_LEN]; 613 + u8 info[3]; 614 + int ret; 615 + bool has_query42; 616 + bool has_lts; 617 + bool has_sensor_id; 618 + bool has_ds4_queries = false; 619 + bool has_build_id_query = false; 620 + bool has_package_id_query = false; 621 + u16 query_offset = data->f01.query_base_addr; 622 + u16 prod_info_addr; 623 + u8 ds4_query_len; 624 + 625 + ret = rmi_read_block(hdev, query_offset, basic_queries, 626 + RMI_DEVICE_F01_BASIC_QUERY_LEN); 627 + if (ret) { 628 + hid_err(hdev, "Can not read basic queries from Function 0x1.\n"); 629 + return ret; 630 + } 631 + 632 + has_lts = !!(basic_queries[0] & BIT(2)); 633 + has_sensor_id = !!(basic_queries[1] & BIT(3)); 634 + has_query42 = !!(basic_queries[1] & BIT(7)); 635 + 636 + query_offset += 11; 637 + prod_info_addr = query_offset + 6; 638 + query_offset += 10; 639 + 640 + if (has_lts) 641 + query_offset += 20; 642 + 643 + if (has_sensor_id) 644 + query_offset++; 645 + 646 + if (has_query42) { 647 + ret = rmi_read(hdev, query_offset, info); 648 + if (ret) { 649 + hid_err(hdev, "Can not read query42.\n"); 650 + return ret; 651 + } 652 + has_ds4_queries = !!(info[0] & BIT(0)); 653 + query_offset++; 654 + } 655 + 656 + if (has_ds4_queries) { 657 + ret = rmi_read(hdev, query_offset, &ds4_query_len); 658 + if (ret) { 659 + hid_err(hdev, "Can not read DS4 Query length.\n"); 660 + return ret; 661 + } 662 + query_offset++; 663 + 664 + if (ds4_query_len > 0) { 665 + ret = rmi_read(hdev, query_offset, info); 666 + if (ret) { 667 + hid_err(hdev, "Can not read DS4 query.\n"); 668 + return ret; 669 + } 670 + 671 + has_package_id_query = !!(info[0] & BIT(0)); 672 + has_build_id_query = !!(info[0] & BIT(1)); 673 + } 674 + } 675 + 676 + if (has_package_id_query) 677 + prod_info_addr++; 678 + 679 + if (has_build_id_query) { 680 + ret = rmi_read_block(hdev, prod_info_addr, info, 3); 681 + if (ret) { 682 + hid_err(hdev, "Can not read product info.\n"); 683 + return ret; 684 + } 685 + 686 + data->firmware_id = info[1] << 8 | info[0]; 687 + data->firmware_id += info[2] * 65536; 688 + } 689 + 690 + return 0; 691 + } 692 + 652 693 static int rmi_populate_f11(struct hid_device *hdev) 653 694 { 654 695 struct rmi_data *data = hid_get_drvdata(hdev); ··· 751 620 bool has_gestures; 752 621 bool has_rel; 753 622 bool has_data40 = false; 623 + bool has_dribble = false; 624 + bool has_palm_detect = false; 754 625 unsigned x_size, y_size; 755 626 u16 query_offset; 756 627 ··· 794 661 has_rel = !!(buf[0] & BIT(3)); 795 662 has_gestures = !!(buf[0] & BIT(5)); 796 663 664 + ret = rmi_read(hdev, data->f11.query_base_addr + 5, buf); 665 + if (ret) { 666 + hid_err(hdev, "can not get absolute data sources: %d.\n", ret); 667 + return ret; 668 + } 669 + 670 + has_dribble = !!(buf[0] & BIT(4)); 671 + 797 672 /* 798 673 * At least 4 queries are guaranteed to be present in F11 799 674 * +1 for query 5 which is present since absolute events are ··· 821 680 ret); 822 681 return ret; 823 682 } 683 + has_palm_detect = !!(buf[0] & BIT(0)); 824 684 has_query10 = !!(buf[0] & BIT(2)); 825 685 826 686 query_offset += 2; /* query 7 and 8 are present */ ··· 908 766 * retrieve the ctrl registers 909 767 * the ctrl register has a size of 20 but a fw bug split it into 16 + 4, 910 768 * and there is no way to know if the first 20 bytes are here or not. 911 - * We use only the first 10 bytes, so get only them. 769 + * We use only the first 12 bytes, so get only them. 912 770 */ 913 - ret = rmi_read_block(hdev, data->f11.control_base_addr, buf, 10); 771 + ret = rmi_read_block(hdev, data->f11.control_base_addr, buf, 12); 914 772 if (ret) { 915 - hid_err(hdev, "can not read ctrl block of size 10: %d.\n", ret); 773 + hid_err(hdev, "can not read ctrl block of size 11: %d.\n", ret); 916 774 return ret; 917 775 } 918 776 919 777 data->max_x = buf[6] | (buf[7] << 8); 920 778 data->max_y = buf[8] | (buf[9] << 8); 779 + 780 + if (has_dribble) { 781 + buf[0] = buf[0] & ~BIT(6); 782 + ret = rmi_write(hdev, data->f11.control_base_addr, buf); 783 + if (ret) { 784 + hid_err(hdev, "can not write to control reg 0: %d.\n", 785 + ret); 786 + return ret; 787 + } 788 + } 789 + 790 + if (has_palm_detect) { 791 + buf[11] = buf[11] & ~BIT(0); 792 + ret = rmi_write(hdev, data->f11.control_base_addr + 11, 793 + &buf[11]); 794 + if (ret) { 795 + hid_err(hdev, "can not write to control reg 11: %d.\n", 796 + ret); 797 + return ret; 798 + } 799 + } 921 800 922 801 return 0; 923 802 } ··· 1021 858 return ret; 1022 859 } 1023 860 861 + ret = rmi_populate_f01(hdev); 862 + if (ret) { 863 + hid_err(hdev, "Error while initializing F01 (%d).\n", ret); 864 + return ret; 865 + } 866 + 1024 867 ret = rmi_populate_f11(hdev); 1025 868 if (ret) { 1026 869 hid_err(hdev, "Error while initializing F11 (%d).\n", ret); ··· 1075 906 ret = rmi_populate(hdev); 1076 907 if (ret) 1077 908 goto exit; 909 + 910 + hid_info(hdev, "firmware id: %ld\n", data->firmware_id); 1078 911 1079 912 __set_bit(EV_ABS, input->evbit); 1080 913 input_set_abs_params(input, ABS_MT_POSITION_X, 1, data->max_x, 0, 0);
+849
drivers/hid/hid-sensor-custom.c
··· 1 + /* 2 + * hid-sensor-custom.c 3 + * Copyright (c) 2015, Intel Corporation. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms and conditions of the GNU General Public License, 7 + * version 2, as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + */ 14 + 15 + #include <linux/kernel.h> 16 + #include <linux/module.h> 17 + #include <linux/init.h> 18 + #include <linux/miscdevice.h> 19 + #include <linux/kfifo.h> 20 + #include <linux/sched.h> 21 + #include <linux/wait.h> 22 + #include <linux/poll.h> 23 + #include <linux/bsearch.h> 24 + #include <linux/platform_device.h> 25 + #include <linux/hid-sensor-hub.h> 26 + 27 + #define HID_CUSTOM_NAME_LENGTH 64 28 + #define HID_CUSTOM_MAX_CORE_ATTRS 10 29 + #define HID_CUSTOM_TOTAL_ATTRS (HID_CUSTOM_MAX_CORE_ATTRS + 1) 30 + #define HID_CUSTOM_FIFO_SIZE 4096 31 + #define HID_CUSTOM_MAX_FEATURE_BYTES 64 32 + 33 + struct hid_sensor_custom_field { 34 + int report_id; 35 + char group_name[HID_CUSTOM_NAME_LENGTH]; 36 + struct hid_sensor_hub_attribute_info attribute; 37 + struct device_attribute sd_attrs[HID_CUSTOM_MAX_CORE_ATTRS]; 38 + char attr_name[HID_CUSTOM_TOTAL_ATTRS][HID_CUSTOM_NAME_LENGTH]; 39 + struct attribute *attrs[HID_CUSTOM_TOTAL_ATTRS]; 40 + struct attribute_group hid_custom_attribute_group; 41 + }; 42 + 43 + struct hid_sensor_custom { 44 + struct mutex mutex; 45 + struct platform_device *pdev; 46 + struct hid_sensor_hub_device *hsdev; 47 + struct hid_sensor_hub_callbacks callbacks; 48 + int sensor_field_count; 49 + struct hid_sensor_custom_field *fields; 50 + int input_field_count; 51 + int input_report_size; 52 + int input_report_recd_size; 53 + bool input_skip_sample; 54 + bool enable; 55 + struct hid_sensor_custom_field *power_state; 56 + struct hid_sensor_custom_field *report_state; 57 + struct miscdevice custom_dev; 58 + struct kfifo data_fifo; 59 + unsigned long misc_opened; 60 + wait_queue_head_t wait; 61 + }; 62 + 63 + /* Header for each sample to user space via dev interface */ 64 + struct hid_sensor_sample { 65 + u32 usage_id; 66 + u64 timestamp; 67 + u32 raw_len; 68 + } __packed; 69 + 70 + static struct attribute hid_custom_attrs[] = { 71 + {.name = "name", .mode = S_IRUGO}, 72 + {.name = "units", .mode = S_IRUGO}, 73 + {.name = "unit-expo", .mode = S_IRUGO}, 74 + {.name = "minimum", .mode = S_IRUGO}, 75 + {.name = "maximum", .mode = S_IRUGO}, 76 + {.name = "size", .mode = S_IRUGO}, 77 + {.name = "value", .mode = S_IWUSR | S_IRUGO}, 78 + {.name = NULL} 79 + }; 80 + 81 + static const struct hid_custom_usage_desc { 82 + int usage_id; 83 + char *desc; 84 + } hid_custom_usage_desc_table[] = { 85 + {0x200201, "event-sensor-state"}, 86 + {0x200202, "event-sensor-event"}, 87 + {0x200301, "property-friendly-name"}, 88 + {0x200302, "property-persistent-unique-id"}, 89 + {0x200303, "property-sensor-status"}, 90 + {0x200304, "property-min-report-interval"}, 91 + {0x200305, "property-sensor-manufacturer"}, 92 + {0x200306, "property-sensor-model"}, 93 + {0x200307, "property-sensor-serial-number"}, 94 + {0x200308, "property-sensor-description"}, 95 + {0x200309, "property-sensor-connection-type"}, 96 + {0x20030A, "property-sensor-device-path"}, 97 + {0x20030B, "property-hardware-revision"}, 98 + {0x20030C, "property-firmware-version"}, 99 + {0x20030D, "property-release-date"}, 100 + {0x20030E, "property-report-interval"}, 101 + {0x20030F, "property-change-sensitivity-absolute"}, 102 + {0x200310, "property-change-sensitivity-percent-range"}, 103 + {0x200311, "property-change-sensitivity-percent-relative"}, 104 + {0x200312, "property-accuracy"}, 105 + {0x200313, "property-resolution"}, 106 + {0x200314, "property-maximum"}, 107 + {0x200315, "property-minimum"}, 108 + {0x200316, "property-reporting-state"}, 109 + {0x200317, "property-sampling-rate"}, 110 + {0x200318, "property-response-curve"}, 111 + {0x200319, "property-power-state"}, 112 + {0x200540, "data-field-custom"}, 113 + {0x200541, "data-field-custom-usage"}, 114 + {0x200542, "data-field-custom-boolean-array"}, 115 + {0x200543, "data-field-custom-value"}, 116 + {0x200544, "data-field-custom-value_1"}, 117 + {0x200545, "data-field-custom-value_2"}, 118 + {0x200546, "data-field-custom-value_3"}, 119 + {0x200547, "data-field-custom-value_4"}, 120 + {0x200548, "data-field-custom-value_5"}, 121 + {0x200549, "data-field-custom-value_6"}, 122 + {0x20054A, "data-field-custom-value_7"}, 123 + {0x20054B, "data-field-custom-value_8"}, 124 + {0x20054C, "data-field-custom-value_9"}, 125 + {0x20054D, "data-field-custom-value_10"}, 126 + {0x20054E, "data-field-custom-value_11"}, 127 + {0x20054F, "data-field-custom-value_12"}, 128 + {0x200550, "data-field-custom-value_13"}, 129 + {0x200551, "data-field-custom-value_14"}, 130 + {0x200552, "data-field-custom-value_15"}, 131 + {0x200553, "data-field-custom-value_16"}, 132 + {0x200554, "data-field-custom-value_17"}, 133 + {0x200555, "data-field-custom-value_18"}, 134 + {0x200556, "data-field-custom-value_19"}, 135 + {0x200557, "data-field-custom-value_20"}, 136 + {0x200558, "data-field-custom-value_21"}, 137 + {0x200559, "data-field-custom-value_22"}, 138 + {0x20055A, "data-field-custom-value_23"}, 139 + {0x20055B, "data-field-custom-value_24"}, 140 + {0x20055C, "data-field-custom-value_25"}, 141 + {0x20055D, "data-field-custom-value_26"}, 142 + {0x20055E, "data-field-custom-value_27"}, 143 + {0x20055F, "data-field-custom-value_28"}, 144 + }; 145 + 146 + static int usage_id_cmp(const void *p1, const void *p2) 147 + { 148 + if (*(int *)p1 < *(int *)p2) 149 + return -1; 150 + 151 + if (*(int *)p1 > *(int *)p2) 152 + return 1; 153 + 154 + return 0; 155 + } 156 + 157 + static ssize_t enable_sensor_show(struct device *dev, 158 + struct device_attribute *attr, char *buf) 159 + { 160 + struct platform_device *pdev = to_platform_device(dev); 161 + struct hid_sensor_custom *sensor_inst = platform_get_drvdata(pdev); 162 + 163 + return sprintf(buf, "%d\n", sensor_inst->enable); 164 + } 165 + 166 + static int set_power_report_state(struct hid_sensor_custom *sensor_inst, 167 + bool state) 168 + { 169 + int power_val = -1; 170 + int report_val = -1; 171 + u32 power_state_usage_id; 172 + u32 report_state_usage_id; 173 + int ret; 174 + 175 + /* 176 + * It is possible that the power/report state ids are not present. 177 + * In this case this function will return success. But if the 178 + * ids are present, then it will return error if set fails. 179 + */ 180 + if (state) { 181 + power_state_usage_id = 182 + HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM; 183 + report_state_usage_id = 184 + HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM; 185 + } else { 186 + power_state_usage_id = 187 + HID_USAGE_SENSOR_PROP_POWER_STATE_D4_POWER_OFF_ENUM; 188 + report_state_usage_id = 189 + HID_USAGE_SENSOR_PROP_REPORTING_STATE_NO_EVENTS_ENUM; 190 + } 191 + 192 + if (sensor_inst->power_state) 193 + power_val = hid_sensor_get_usage_index(sensor_inst->hsdev, 194 + sensor_inst->power_state->attribute.report_id, 195 + sensor_inst->power_state->attribute.index, 196 + power_state_usage_id); 197 + if (sensor_inst->report_state) 198 + report_val = hid_sensor_get_usage_index(sensor_inst->hsdev, 199 + sensor_inst->report_state->attribute.report_id, 200 + sensor_inst->report_state->attribute.index, 201 + report_state_usage_id); 202 + 203 + if (power_val >= 0) { 204 + power_val += 205 + sensor_inst->power_state->attribute.logical_minimum; 206 + ret = sensor_hub_set_feature(sensor_inst->hsdev, 207 + sensor_inst->power_state->attribute.report_id, 208 + sensor_inst->power_state->attribute.index, 209 + sizeof(power_val), 210 + &power_val); 211 + if (ret) { 212 + hid_err(sensor_inst->hsdev->hdev, 213 + "Set power state failed\n"); 214 + return ret; 215 + } 216 + } 217 + 218 + if (report_val >= 0) { 219 + report_val += 220 + sensor_inst->report_state->attribute.logical_minimum; 221 + ret = sensor_hub_set_feature(sensor_inst->hsdev, 222 + sensor_inst->report_state->attribute.report_id, 223 + sensor_inst->report_state->attribute.index, 224 + sizeof(report_val), 225 + &report_val); 226 + if (ret) { 227 + hid_err(sensor_inst->hsdev->hdev, 228 + "Set report state failed\n"); 229 + return ret; 230 + } 231 + } 232 + 233 + return 0; 234 + } 235 + 236 + static ssize_t enable_sensor_store(struct device *dev, 237 + struct device_attribute *attr, 238 + const char *buf, size_t count) 239 + { 240 + struct platform_device *pdev = to_platform_device(dev); 241 + struct hid_sensor_custom *sensor_inst = platform_get_drvdata(pdev); 242 + int value; 243 + int ret = -EINVAL; 244 + 245 + if (kstrtoint(buf, 0, &value) != 0) 246 + return -EINVAL; 247 + 248 + mutex_lock(&sensor_inst->mutex); 249 + if (value && !sensor_inst->enable) { 250 + ret = sensor_hub_device_open(sensor_inst->hsdev); 251 + if (ret) 252 + goto unlock_state; 253 + 254 + ret = set_power_report_state(sensor_inst, true); 255 + if (ret) { 256 + sensor_hub_device_close(sensor_inst->hsdev); 257 + goto unlock_state; 258 + } 259 + sensor_inst->enable = true; 260 + } else if (!value && sensor_inst->enable) { 261 + ret = set_power_report_state(sensor_inst, false); 262 + sensor_hub_device_close(sensor_inst->hsdev); 263 + sensor_inst->enable = false; 264 + } 265 + unlock_state: 266 + mutex_unlock(&sensor_inst->mutex); 267 + if (ret < 0) 268 + return ret; 269 + 270 + return count; 271 + } 272 + static DEVICE_ATTR_RW(enable_sensor); 273 + 274 + static struct attribute *enable_sensor_attrs[] = { 275 + &dev_attr_enable_sensor.attr, 276 + NULL, 277 + }; 278 + 279 + static struct attribute_group enable_sensor_attr_group = { 280 + .attrs = enable_sensor_attrs, 281 + }; 282 + 283 + static ssize_t show_value(struct device *dev, struct device_attribute *attr, 284 + char *buf) 285 + { 286 + struct platform_device *pdev = to_platform_device(dev); 287 + struct hid_sensor_custom *sensor_inst = platform_get_drvdata(pdev); 288 + struct hid_sensor_hub_attribute_info *attribute; 289 + int index, usage, field_index; 290 + char name[HID_CUSTOM_NAME_LENGTH]; 291 + bool feature = false; 292 + bool input = false; 293 + int value = 0; 294 + 295 + if (sscanf(attr->attr.name, "feature-%d-%x-%s", &index, &usage, 296 + name) == 3) { 297 + feature = true; 298 + field_index = index + sensor_inst->input_field_count; 299 + } else if (sscanf(attr->attr.name, "input-%d-%x-%s", &index, &usage, 300 + name) == 3) { 301 + input = true; 302 + field_index = index; 303 + } else 304 + return -EINVAL; 305 + 306 + if (!strncmp(name, "value", strlen("value"))) { 307 + u32 report_id; 308 + int ret; 309 + 310 + attribute = &sensor_inst->fields[field_index].attribute; 311 + report_id = attribute->report_id; 312 + if (feature) { 313 + u8 values[HID_CUSTOM_MAX_FEATURE_BYTES]; 314 + int len = 0; 315 + u64 value = 0; 316 + int i = 0; 317 + 318 + ret = sensor_hub_get_feature(sensor_inst->hsdev, 319 + report_id, 320 + index, 321 + sizeof(values), values); 322 + if (ret < 0) 323 + return ret; 324 + 325 + while (i < ret) { 326 + if (i + attribute->size > ret) { 327 + len += snprintf(&buf[len], 328 + PAGE_SIZE - len, 329 + "%d ", values[i]); 330 + break; 331 + } 332 + switch (attribute->size) { 333 + case 2: 334 + value = (u64) *(u16 *)&values[i]; 335 + i += attribute->size; 336 + break; 337 + case 4: 338 + value = (u64) *(u32 *)&values[i]; 339 + i += attribute->size; 340 + break; 341 + case 8: 342 + value = *(u64 *)&values[i]; 343 + i += attribute->size; 344 + break; 345 + default: 346 + value = (u64) values[i]; 347 + ++i; 348 + break; 349 + } 350 + len += snprintf(&buf[len], PAGE_SIZE - len, 351 + "%lld ", value); 352 + } 353 + len += snprintf(&buf[len], PAGE_SIZE - len, "\n"); 354 + 355 + return len; 356 + } else if (input) 357 + value = sensor_hub_input_attr_get_raw_value( 358 + sensor_inst->hsdev, 359 + sensor_inst->hsdev->usage, 360 + usage, report_id, 361 + SENSOR_HUB_SYNC); 362 + } else if (!strncmp(name, "units", strlen("units"))) 363 + value = sensor_inst->fields[field_index].attribute.units; 364 + else if (!strncmp(name, "unit-expo", strlen("unit-expo"))) 365 + value = sensor_inst->fields[field_index].attribute.unit_expo; 366 + else if (!strncmp(name, "size", strlen("size"))) 367 + value = sensor_inst->fields[field_index].attribute.size; 368 + else if (!strncmp(name, "minimum", strlen("minimum"))) 369 + value = sensor_inst->fields[field_index].attribute. 370 + logical_minimum; 371 + else if (!strncmp(name, "maximum", strlen("maximum"))) 372 + value = sensor_inst->fields[field_index].attribute. 373 + logical_maximum; 374 + else if (!strncmp(name, "name", strlen("name"))) { 375 + struct hid_custom_usage_desc *usage_desc; 376 + 377 + usage_desc = bsearch(&usage, hid_custom_usage_desc_table, 378 + ARRAY_SIZE(hid_custom_usage_desc_table), 379 + sizeof(struct hid_custom_usage_desc), 380 + usage_id_cmp); 381 + if (usage_desc) 382 + return snprintf(buf, PAGE_SIZE, "%s\n", 383 + usage_desc->desc); 384 + else 385 + return sprintf(buf, "not-specified\n"); 386 + } else 387 + return -EINVAL; 388 + 389 + return sprintf(buf, "%d\n", value); 390 + } 391 + 392 + static ssize_t store_value(struct device *dev, struct device_attribute *attr, 393 + const char *buf, size_t count) 394 + { 395 + struct platform_device *pdev = to_platform_device(dev); 396 + struct hid_sensor_custom *sensor_inst = platform_get_drvdata(pdev); 397 + int index, field_index, usage; 398 + char name[HID_CUSTOM_NAME_LENGTH]; 399 + int value; 400 + 401 + if (sscanf(attr->attr.name, "feature-%d-%x-%s", &index, &usage, 402 + name) == 3) { 403 + field_index = index + sensor_inst->input_field_count; 404 + } else 405 + return -EINVAL; 406 + 407 + if (!strncmp(name, "value", strlen("value"))) { 408 + u32 report_id; 409 + int ret; 410 + 411 + if (kstrtoint(buf, 0, &value) != 0) 412 + return -EINVAL; 413 + 414 + report_id = sensor_inst->fields[field_index].attribute. 415 + report_id; 416 + ret = sensor_hub_set_feature(sensor_inst->hsdev, report_id, 417 + index, sizeof(value), &value); 418 + } else 419 + return -EINVAL; 420 + 421 + return count; 422 + } 423 + 424 + static int hid_sensor_capture_sample(struct hid_sensor_hub_device *hsdev, 425 + unsigned usage_id, size_t raw_len, 426 + char *raw_data, void *priv) 427 + { 428 + struct hid_sensor_custom *sensor_inst = platform_get_drvdata(priv); 429 + struct hid_sensor_sample header; 430 + 431 + /* If any error occurs in a sample, rest of the fields are ignored */ 432 + if (sensor_inst->input_skip_sample) { 433 + hid_err(sensor_inst->hsdev->hdev, "Skipped remaining data\n"); 434 + return 0; 435 + } 436 + 437 + hid_dbg(sensor_inst->hsdev->hdev, "%s received %d of %d\n", __func__, 438 + (int) (sensor_inst->input_report_recd_size + raw_len), 439 + sensor_inst->input_report_size); 440 + 441 + if (!test_bit(0, &sensor_inst->misc_opened)) 442 + return 0; 443 + 444 + if (!sensor_inst->input_report_recd_size) { 445 + int required_size = sizeof(struct hid_sensor_sample) + 446 + sensor_inst->input_report_size; 447 + header.usage_id = hsdev->usage; 448 + header.raw_len = sensor_inst->input_report_size; 449 + header.timestamp = ktime_get_real_ns(); 450 + if (kfifo_avail(&sensor_inst->data_fifo) >= required_size) { 451 + kfifo_in(&sensor_inst->data_fifo, 452 + (unsigned char *)&header, 453 + sizeof(header)); 454 + } else 455 + sensor_inst->input_skip_sample = true; 456 + } 457 + if (kfifo_avail(&sensor_inst->data_fifo) >= raw_len) 458 + kfifo_in(&sensor_inst->data_fifo, (unsigned char *)raw_data, 459 + raw_len); 460 + 461 + sensor_inst->input_report_recd_size += raw_len; 462 + 463 + return 0; 464 + } 465 + 466 + static int hid_sensor_send_event(struct hid_sensor_hub_device *hsdev, 467 + unsigned usage_id, void *priv) 468 + { 469 + struct hid_sensor_custom *sensor_inst = platform_get_drvdata(priv); 470 + 471 + if (!test_bit(0, &sensor_inst->misc_opened)) 472 + return 0; 473 + 474 + sensor_inst->input_report_recd_size = 0; 475 + sensor_inst->input_skip_sample = false; 476 + 477 + wake_up(&sensor_inst->wait); 478 + 479 + return 0; 480 + } 481 + 482 + static int hid_sensor_custom_add_field(struct hid_sensor_custom *sensor_inst, 483 + int index, int report_type, 484 + struct hid_report *report, 485 + struct hid_field *field) 486 + { 487 + struct hid_sensor_custom_field *sensor_field; 488 + void *fields; 489 + 490 + fields = krealloc(sensor_inst->fields, 491 + (sensor_inst->sensor_field_count + 1) * 492 + sizeof(struct hid_sensor_custom_field), GFP_KERNEL); 493 + if (!fields) { 494 + kfree(sensor_inst->fields); 495 + return -ENOMEM; 496 + } 497 + sensor_inst->fields = fields; 498 + sensor_field = &sensor_inst->fields[sensor_inst->sensor_field_count]; 499 + sensor_field->attribute.usage_id = sensor_inst->hsdev->usage; 500 + if (field->logical) 501 + sensor_field->attribute.attrib_id = field->logical; 502 + else 503 + sensor_field->attribute.attrib_id = field->usage[0].hid; 504 + 505 + sensor_field->attribute.index = index; 506 + sensor_field->attribute.report_id = report->id; 507 + sensor_field->attribute.units = field->unit; 508 + sensor_field->attribute.unit_expo = field->unit_exponent; 509 + sensor_field->attribute.size = (field->report_size / 8); 510 + sensor_field->attribute.logical_minimum = field->logical_minimum; 511 + sensor_field->attribute.logical_maximum = field->logical_maximum; 512 + 513 + if (report_type == HID_FEATURE_REPORT) 514 + snprintf(sensor_field->group_name, 515 + sizeof(sensor_field->group_name), "feature-%x-%x", 516 + sensor_field->attribute.index, 517 + sensor_field->attribute.attrib_id); 518 + else if (report_type == HID_INPUT_REPORT) { 519 + snprintf(sensor_field->group_name, 520 + sizeof(sensor_field->group_name), 521 + "input-%x-%x", sensor_field->attribute.index, 522 + sensor_field->attribute.attrib_id); 523 + sensor_inst->input_field_count++; 524 + sensor_inst->input_report_size += (field->report_size * 525 + field->report_count) / 8; 526 + } 527 + 528 + memset(&sensor_field->hid_custom_attribute_group, 0, 529 + sizeof(struct attribute_group)); 530 + sensor_inst->sensor_field_count++; 531 + 532 + return 0; 533 + } 534 + 535 + static int hid_sensor_custom_add_fields(struct hid_sensor_custom *sensor_inst, 536 + struct hid_report_enum *report_enum, 537 + int report_type) 538 + { 539 + int i; 540 + int ret; 541 + struct hid_report *report; 542 + struct hid_field *field; 543 + struct hid_sensor_hub_device *hsdev = sensor_inst->hsdev; 544 + 545 + list_for_each_entry(report, &report_enum->report_list, list) { 546 + for (i = 0; i < report->maxfield; ++i) { 547 + field = report->field[i]; 548 + if (field->maxusage && 549 + ((field->usage[0].collection_index >= 550 + hsdev->start_collection_index) && 551 + (field->usage[0].collection_index < 552 + hsdev->end_collection_index))) { 553 + 554 + ret = hid_sensor_custom_add_field(sensor_inst, 555 + i, 556 + report_type, 557 + report, 558 + field); 559 + if (ret) 560 + return ret; 561 + 562 + } 563 + } 564 + } 565 + 566 + return 0; 567 + } 568 + 569 + static int hid_sensor_custom_add_attributes(struct hid_sensor_custom 570 + *sensor_inst) 571 + { 572 + struct hid_sensor_hub_device *hsdev = sensor_inst->hsdev; 573 + struct hid_device *hdev = hsdev->hdev; 574 + int ret = -1; 575 + int i, j; 576 + 577 + for (j = 0; j < HID_REPORT_TYPES; ++j) { 578 + if (j == HID_OUTPUT_REPORT) 579 + continue; 580 + 581 + ret = hid_sensor_custom_add_fields(sensor_inst, 582 + &hdev->report_enum[j], j); 583 + if (ret) 584 + return ret; 585 + 586 + } 587 + 588 + /* Create sysfs attributes */ 589 + for (i = 0; i < sensor_inst->sensor_field_count; ++i) { 590 + j = 0; 591 + while (j < HID_CUSTOM_TOTAL_ATTRS && 592 + hid_custom_attrs[j].name) { 593 + struct device_attribute *device_attr; 594 + 595 + device_attr = &sensor_inst->fields[i].sd_attrs[j]; 596 + 597 + snprintf((char *)&sensor_inst->fields[i].attr_name[j], 598 + HID_CUSTOM_NAME_LENGTH, "%s-%s", 599 + sensor_inst->fields[i].group_name, 600 + hid_custom_attrs[j].name); 601 + sysfs_attr_init(&device_attr->attr); 602 + device_attr->attr.name = 603 + (char *)&sensor_inst->fields[i].attr_name[j]; 604 + device_attr->attr.mode = hid_custom_attrs[j].mode; 605 + device_attr->show = show_value; 606 + if (hid_custom_attrs[j].mode & S_IWUSR) 607 + device_attr->store = store_value; 608 + sensor_inst->fields[i].attrs[j] = &device_attr->attr; 609 + ++j; 610 + } 611 + sensor_inst->fields[i].attrs[j] = NULL; 612 + sensor_inst->fields[i].hid_custom_attribute_group.attrs = 613 + sensor_inst->fields[i].attrs; 614 + sensor_inst->fields[i].hid_custom_attribute_group.name = 615 + sensor_inst->fields[i].group_name; 616 + ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj, 617 + &sensor_inst->fields[i]. 618 + hid_custom_attribute_group); 619 + if (ret) 620 + break; 621 + 622 + /* For power or report field store indexes */ 623 + if (sensor_inst->fields[i].attribute.attrib_id == 624 + HID_USAGE_SENSOR_PROY_POWER_STATE) 625 + sensor_inst->power_state = &sensor_inst->fields[i]; 626 + else if (sensor_inst->fields[i].attribute.attrib_id == 627 + HID_USAGE_SENSOR_PROP_REPORT_STATE) 628 + sensor_inst->report_state = &sensor_inst->fields[i]; 629 + } 630 + 631 + return ret; 632 + } 633 + 634 + static void hid_sensor_custom_remove_attributes(struct hid_sensor_custom * 635 + sensor_inst) 636 + { 637 + int i; 638 + 639 + for (i = 0; i < sensor_inst->sensor_field_count; ++i) 640 + sysfs_remove_group(&sensor_inst->pdev->dev.kobj, 641 + &sensor_inst->fields[i]. 642 + hid_custom_attribute_group); 643 + 644 + kfree(sensor_inst->fields); 645 + } 646 + 647 + static ssize_t hid_sensor_custom_read(struct file *file, char __user *buf, 648 + size_t count, loff_t *f_ps) 649 + { 650 + struct hid_sensor_custom *sensor_inst; 651 + unsigned int copied; 652 + int ret; 653 + 654 + sensor_inst = container_of(file->private_data, 655 + struct hid_sensor_custom, custom_dev); 656 + 657 + if (count < sizeof(struct hid_sensor_sample)) 658 + return -EINVAL; 659 + 660 + do { 661 + if (kfifo_is_empty(&sensor_inst->data_fifo)) { 662 + if (file->f_flags & O_NONBLOCK) 663 + return -EAGAIN; 664 + 665 + ret = wait_event_interruptible(sensor_inst->wait, 666 + !kfifo_is_empty(&sensor_inst->data_fifo)); 667 + if (ret) 668 + return ret; 669 + } 670 + ret = kfifo_to_user(&sensor_inst->data_fifo, buf, count, 671 + &copied); 672 + if (ret) 673 + return ret; 674 + 675 + } while (copied == 0); 676 + 677 + return copied; 678 + } 679 + 680 + static int hid_sensor_custom_release(struct inode *inode, struct file *file) 681 + { 682 + struct hid_sensor_custom *sensor_inst; 683 + 684 + sensor_inst = container_of(file->private_data, 685 + struct hid_sensor_custom, custom_dev); 686 + 687 + clear_bit(0, &sensor_inst->misc_opened); 688 + 689 + return 0; 690 + } 691 + 692 + static int hid_sensor_custom_open(struct inode *inode, struct file *file) 693 + { 694 + struct hid_sensor_custom *sensor_inst; 695 + 696 + sensor_inst = container_of(file->private_data, 697 + struct hid_sensor_custom, custom_dev); 698 + /* We essentially have single reader and writer */ 699 + if (test_and_set_bit(0, &sensor_inst->misc_opened)) 700 + return -EBUSY; 701 + 702 + return nonseekable_open(inode, file); 703 + } 704 + 705 + static unsigned int hid_sensor_custom_poll(struct file *file, 706 + struct poll_table_struct *wait) 707 + { 708 + struct hid_sensor_custom *sensor_inst; 709 + unsigned int mask = 0; 710 + 711 + sensor_inst = container_of(file->private_data, 712 + struct hid_sensor_custom, custom_dev); 713 + 714 + poll_wait(file, &sensor_inst->wait, wait); 715 + 716 + if (!kfifo_is_empty(&sensor_inst->data_fifo)) 717 + mask = POLLIN | POLLRDNORM; 718 + 719 + return mask; 720 + } 721 + 722 + static const struct file_operations hid_sensor_custom_fops = { 723 + .open = hid_sensor_custom_open, 724 + .read = hid_sensor_custom_read, 725 + .release = hid_sensor_custom_release, 726 + .poll = hid_sensor_custom_poll, 727 + .llseek = noop_llseek, 728 + }; 729 + 730 + static int hid_sensor_custom_dev_if_add(struct hid_sensor_custom *sensor_inst) 731 + { 732 + int ret; 733 + 734 + ret = kfifo_alloc(&sensor_inst->data_fifo, HID_CUSTOM_FIFO_SIZE, 735 + GFP_KERNEL); 736 + if (ret) 737 + return ret; 738 + 739 + init_waitqueue_head(&sensor_inst->wait); 740 + 741 + sensor_inst->custom_dev.minor = MISC_DYNAMIC_MINOR; 742 + sensor_inst->custom_dev.name = dev_name(&sensor_inst->pdev->dev); 743 + sensor_inst->custom_dev.fops = &hid_sensor_custom_fops, 744 + ret = misc_register(&sensor_inst->custom_dev); 745 + if (ret) { 746 + kfifo_free(&sensor_inst->data_fifo); 747 + return ret; 748 + } 749 + return 0; 750 + } 751 + 752 + static void hid_sensor_custom_dev_if_remove(struct hid_sensor_custom 753 + *sensor_inst) 754 + { 755 + wake_up(&sensor_inst->wait); 756 + misc_deregister(&sensor_inst->custom_dev); 757 + kfifo_free(&sensor_inst->data_fifo); 758 + 759 + } 760 + 761 + static int hid_sensor_custom_probe(struct platform_device *pdev) 762 + { 763 + struct hid_sensor_custom *sensor_inst; 764 + struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; 765 + int ret; 766 + 767 + sensor_inst = devm_kzalloc(&pdev->dev, sizeof(*sensor_inst), 768 + GFP_KERNEL); 769 + if (!sensor_inst) 770 + return -ENOMEM; 771 + 772 + sensor_inst->callbacks.capture_sample = hid_sensor_capture_sample; 773 + sensor_inst->callbacks.send_event = hid_sensor_send_event; 774 + sensor_inst->callbacks.pdev = pdev; 775 + sensor_inst->hsdev = hsdev; 776 + sensor_inst->pdev = pdev; 777 + mutex_init(&sensor_inst->mutex); 778 + platform_set_drvdata(pdev, sensor_inst); 779 + ret = sensor_hub_register_callback(hsdev, hsdev->usage, 780 + &sensor_inst->callbacks); 781 + if (ret < 0) { 782 + dev_err(&pdev->dev, "callback reg failed\n"); 783 + return ret; 784 + } 785 + 786 + ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj, 787 + &enable_sensor_attr_group); 788 + if (ret) 789 + goto err_remove_callback; 790 + 791 + ret = hid_sensor_custom_add_attributes(sensor_inst); 792 + if (ret) 793 + goto err_remove_group; 794 + 795 + ret = hid_sensor_custom_dev_if_add(sensor_inst); 796 + if (ret) 797 + goto err_remove_attributes; 798 + 799 + return 0; 800 + 801 + err_remove_attributes: 802 + hid_sensor_custom_remove_attributes(sensor_inst); 803 + err_remove_group: 804 + sysfs_remove_group(&sensor_inst->pdev->dev.kobj, 805 + &enable_sensor_attr_group); 806 + err_remove_callback: 807 + sensor_hub_remove_callback(hsdev, hsdev->usage); 808 + 809 + return ret; 810 + } 811 + 812 + static int hid_sensor_custom_remove(struct platform_device *pdev) 813 + { 814 + struct hid_sensor_custom *sensor_inst = platform_get_drvdata(pdev); 815 + struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; 816 + 817 + hid_sensor_custom_dev_if_remove(sensor_inst); 818 + hid_sensor_custom_remove_attributes(sensor_inst); 819 + sysfs_remove_group(&sensor_inst->pdev->dev.kobj, 820 + &enable_sensor_attr_group); 821 + sensor_hub_remove_callback(hsdev, hsdev->usage); 822 + 823 + return 0; 824 + } 825 + 826 + static struct platform_device_id hid_sensor_custom_ids[] = { 827 + { 828 + .name = "HID-SENSOR-2000e1", 829 + }, 830 + { 831 + .name = "HID-SENSOR-2000e2", 832 + }, 833 + { /* sentinel */ } 834 + }; 835 + MODULE_DEVICE_TABLE(platform, hid_sensor_custom_ids); 836 + 837 + static struct platform_driver hid_sensor_custom_platform_driver = { 838 + .id_table = hid_sensor_custom_ids, 839 + .driver = { 840 + .name = KBUILD_MODNAME, 841 + }, 842 + .probe = hid_sensor_custom_probe, 843 + .remove = hid_sensor_custom_remove, 844 + }; 845 + module_platform_driver(hid_sensor_custom_platform_driver); 846 + 847 + MODULE_DESCRIPTION("HID Sensor Custom and Generic sensor Driver"); 848 + MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); 849 + MODULE_LICENSE("GPL");
+123 -73
drivers/hid/hid-sensor-hub.c
··· 29 29 #define HID_SENSOR_HUB_ENUM_QUIRK 0x01 30 30 31 31 /** 32 - * struct sensor_hub_pending - Synchronous read pending information 33 - * @status: Pending status true/false. 34 - * @ready: Completion synchronization data. 35 - * @usage_id: Usage id for physical device, E.g. Gyro usage id. 36 - * @attr_usage_id: Usage Id of a field, E.g. X-AXIS for a gyro. 37 - * @raw_size: Response size for a read request. 38 - * @raw_data: Place holder for received response. 39 - */ 40 - struct sensor_hub_pending { 41 - bool status; 42 - struct completion ready; 43 - u32 usage_id; 44 - u32 attr_usage_id; 45 - int raw_size; 46 - u8 *raw_data; 47 - }; 48 - 49 - /** 50 32 * struct sensor_hub_data - Hold a instance data for a HID hub device 51 33 * @hsdev: Stored hid instance for current hub device. 52 34 * @mutex: Mutex to serialize synchronous request. 53 35 * @lock: Spin lock to protect pending request structure. 54 - * @pending: Holds information of pending sync read request. 55 36 * @dyn_callback_list: Holds callback function 56 37 * @dyn_callback_lock: spin lock to protect callback list 57 38 * @hid_sensor_hub_client_devs: Stores all MFD cells for a hub instance. ··· 42 61 struct sensor_hub_data { 43 62 struct mutex mutex; 44 63 spinlock_t lock; 45 - struct sensor_hub_pending pending; 46 64 struct list_head dyn_callback_list; 47 65 spinlock_t dyn_callback_lock; 48 66 struct mfd_cell *hid_sensor_hub_client_devs; ··· 86 106 87 107 for (i = 0; i < hdev->maxcollection; ++i) { 88 108 struct hid_collection *collection = &hdev->collection[i]; 89 - if (collection->type == HID_COLLECTION_PHYSICAL) 109 + if (collection->type == HID_COLLECTION_PHYSICAL || 110 + collection->type == HID_COLLECTION_APPLICATION) 90 111 ++count; 91 112 } 92 113 ··· 120 139 121 140 spin_lock_irqsave(&pdata->dyn_callback_lock, flags); 122 141 list_for_each_entry(callback, &pdata->dyn_callback_list, list) 123 - if (callback->usage_id == usage_id && 142 + if ((callback->usage_id == usage_id || 143 + callback->usage_id == HID_USAGE_SENSOR_COLLECTION) && 124 144 (collection_index >= 125 145 callback->hsdev->start_collection_index) && 126 146 (collection_index < ··· 161 179 callback->usage_callback = usage_callback; 162 180 callback->usage_id = usage_id; 163 181 callback->priv = NULL; 164 - list_add_tail(&callback->list, &pdata->dyn_callback_list); 182 + /* 183 + * If there is a handler registered for the collection type, then 184 + * it will handle all reports for sensors in this collection. If 185 + * there is also an individual sensor handler registration, then 186 + * we want to make sure that the reports are directed to collection 187 + * handler, as this may be a fusion sensor. So add collection handlers 188 + * to the beginning of the list, so that they are matched first. 189 + */ 190 + if (usage_id == HID_USAGE_SENSOR_COLLECTION) 191 + list_add(&callback->list, &pdata->dyn_callback_list); 192 + else 193 + list_add_tail(&callback->list, &pdata->dyn_callback_list); 165 194 spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); 166 195 167 196 return 0; ··· 201 208 EXPORT_SYMBOL_GPL(sensor_hub_remove_callback); 202 209 203 210 int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, 204 - u32 field_index, s32 value) 211 + u32 field_index, int buffer_size, void *buffer) 205 212 { 206 213 struct hid_report *report; 207 214 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); 215 + __s32 *buf32 = buffer; 216 + int i = 0; 217 + int remaining_bytes; 218 + __s32 value; 208 219 int ret = 0; 209 220 210 221 mutex_lock(&data->mutex); ··· 217 220 ret = -EINVAL; 218 221 goto done_proc; 219 222 } 220 - hid_set_field(report->field[field_index], 0, value); 223 + 224 + remaining_bytes = do_div(buffer_size, sizeof(__s32)); 225 + if (buffer_size) { 226 + for (i = 0; i < buffer_size; ++i) { 227 + hid_set_field(report->field[field_index], i, 228 + (__force __s32)cpu_to_le32(*buf32)); 229 + ++buf32; 230 + } 231 + } 232 + if (remaining_bytes) { 233 + value = 0; 234 + memcpy(&value, (u8 *)buf32, remaining_bytes); 235 + hid_set_field(report->field[field_index], i, 236 + (__force __s32)cpu_to_le32(value)); 237 + } 221 238 hid_hw_request(hsdev->hdev, report, HID_REQ_SET_REPORT); 222 239 hid_hw_wait(hsdev->hdev); 223 240 ··· 243 232 EXPORT_SYMBOL_GPL(sensor_hub_set_feature); 244 233 245 234 int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, 246 - u32 field_index, s32 *value) 235 + u32 field_index, int buffer_size, void *buffer) 247 236 { 248 237 struct hid_report *report; 249 238 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); 239 + int report_size; 250 240 int ret = 0; 251 241 252 242 mutex_lock(&data->mutex); ··· 259 247 } 260 248 hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); 261 249 hid_hw_wait(hsdev->hdev); 262 - *value = report->field[field_index]->value[0]; 250 + 251 + /* calculate number of bytes required to read this field */ 252 + report_size = DIV_ROUND_UP(report->field[field_index]->report_size, 253 + 8) * 254 + report->field[field_index]->report_count; 255 + if (!report_size) { 256 + ret = -EINVAL; 257 + goto done_proc; 258 + } 259 + ret = min(report_size, buffer_size); 260 + memcpy(buffer, report->field[field_index]->value, ret); 263 261 264 262 done_proc: 265 263 mutex_unlock(&data->mutex); ··· 281 259 282 260 int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, 283 261 u32 usage_id, 284 - u32 attr_usage_id, u32 report_id) 262 + u32 attr_usage_id, u32 report_id, 263 + enum sensor_hub_read_flags flag) 285 264 { 286 265 struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); 287 266 unsigned long flags; 288 267 struct hid_report *report; 289 268 int ret_val = 0; 290 269 291 - mutex_lock(&data->mutex); 292 - memset(&data->pending, 0, sizeof(data->pending)); 293 - init_completion(&data->pending.ready); 294 - data->pending.usage_id = usage_id; 295 - data->pending.attr_usage_id = attr_usage_id; 296 - data->pending.raw_size = 0; 297 - 298 - spin_lock_irqsave(&data->lock, flags); 299 - data->pending.status = true; 300 - spin_unlock_irqrestore(&data->lock, flags); 301 - report = sensor_hub_report(report_id, hsdev->hdev, HID_INPUT_REPORT); 270 + report = sensor_hub_report(report_id, hsdev->hdev, 271 + HID_INPUT_REPORT); 302 272 if (!report) 303 - goto err_free; 273 + return -EINVAL; 304 274 305 - hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); 306 - wait_for_completion_interruptible_timeout(&data->pending.ready, HZ*5); 307 - switch (data->pending.raw_size) { 308 - case 1: 309 - ret_val = *(u8 *)data->pending.raw_data; 310 - break; 311 - case 2: 312 - ret_val = *(u16 *)data->pending.raw_data; 313 - break; 314 - case 4: 315 - ret_val = *(u32 *)data->pending.raw_data; 316 - break; 317 - default: 318 - ret_val = 0; 275 + mutex_lock(&hsdev->mutex); 276 + if (flag == SENSOR_HUB_SYNC) { 277 + memset(&hsdev->pending, 0, sizeof(hsdev->pending)); 278 + init_completion(&hsdev->pending.ready); 279 + hsdev->pending.usage_id = usage_id; 280 + hsdev->pending.attr_usage_id = attr_usage_id; 281 + hsdev->pending.raw_size = 0; 282 + 283 + spin_lock_irqsave(&data->lock, flags); 284 + hsdev->pending.status = true; 285 + spin_unlock_irqrestore(&data->lock, flags); 319 286 } 320 - kfree(data->pending.raw_data); 321 - 322 - err_free: 323 - data->pending.status = false; 287 + mutex_lock(&data->mutex); 288 + hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); 324 289 mutex_unlock(&data->mutex); 290 + if (flag == SENSOR_HUB_SYNC) { 291 + wait_for_completion_interruptible_timeout( 292 + &hsdev->pending.ready, HZ*5); 293 + switch (hsdev->pending.raw_size) { 294 + case 1: 295 + ret_val = *(u8 *)hsdev->pending.raw_data; 296 + break; 297 + case 2: 298 + ret_val = *(u16 *)hsdev->pending.raw_data; 299 + break; 300 + case 4: 301 + ret_val = *(u32 *)hsdev->pending.raw_data; 302 + break; 303 + default: 304 + ret_val = 0; 305 + } 306 + kfree(hsdev->pending.raw_data); 307 + hsdev->pending.status = false; 308 + } 309 + mutex_unlock(&hsdev->mutex); 325 310 326 311 return ret_val; 327 312 } ··· 484 455 report->field[i]->report_count)/8); 485 456 sz = (report->field[i]->report_size * 486 457 report->field[i]->report_count)/8; 487 - if (pdata->pending.status && pdata->pending.attr_usage_id == 488 - report->field[i]->usage->hid) { 489 - hid_dbg(hdev, "data was pending ...\n"); 490 - pdata->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC); 491 - if (pdata->pending.raw_data) 492 - pdata->pending.raw_size = sz; 493 - else 494 - pdata->pending.raw_size = 0; 495 - complete(&pdata->pending.ready); 496 - } 497 458 collection = &hdev->collection[ 498 459 report->field[i]->usage->collection_index]; 499 460 hid_dbg(hdev, "collection->usage %x\n", ··· 493 474 report->field[i]->physical, 494 475 report->field[i]->usage[0].collection_index, 495 476 &hsdev, &priv); 496 - 497 - if (callback && callback->capture_sample) { 477 + if (!callback) { 478 + ptr += sz; 479 + continue; 480 + } 481 + if (hsdev->pending.status && (hsdev->pending.attr_usage_id == 482 + report->field[i]->usage->hid || 483 + hsdev->pending.attr_usage_id == 484 + report->field[i]->logical)) { 485 + hid_dbg(hdev, "data was pending ...\n"); 486 + hsdev->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC); 487 + if (hsdev->pending.raw_data) 488 + hsdev->pending.raw_size = sz; 489 + else 490 + hsdev->pending.raw_size = 0; 491 + complete(&hsdev->pending.ready); 492 + } 493 + if (callback->capture_sample) { 498 494 if (report->field[i]->logical) 499 495 callback->capture_sample(hsdev, 500 496 report->field[i]->logical, sz, ptr, ··· 606 572 int dev_cnt; 607 573 struct hid_sensor_hub_device *hsdev; 608 574 struct hid_sensor_hub_device *last_hsdev = NULL; 575 + struct hid_sensor_hub_device *collection_hsdev = NULL; 609 576 610 577 sd = devm_kzalloc(&hdev->dev, sizeof(*sd), GFP_KERNEL); 611 578 if (!sd) { ··· 653 618 for (i = 0; i < hdev->maxcollection; ++i) { 654 619 struct hid_collection *collection = &hdev->collection[i]; 655 620 656 - if (collection->type == HID_COLLECTION_PHYSICAL) { 621 + if (collection->type == HID_COLLECTION_PHYSICAL || 622 + collection->type == HID_COLLECTION_APPLICATION) { 657 623 658 624 hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev), 659 625 GFP_KERNEL); ··· 666 630 hsdev->hdev = hdev; 667 631 hsdev->vendor_id = hdev->vendor; 668 632 hsdev->product_id = hdev->product; 633 + hsdev->usage = collection->usage; 634 + mutex_init(&hsdev->mutex); 669 635 hsdev->start_collection_index = i; 670 636 if (last_hsdev) 671 637 last_hsdev->end_collection_index = i; ··· 691 653 hid_dbg(hdev, "Adding %s:%d\n", name, 692 654 hsdev->start_collection_index); 693 655 sd->hid_sensor_client_cnt++; 656 + if (collection_hsdev) 657 + collection_hsdev->end_collection_index = i; 658 + if (collection->type == HID_COLLECTION_APPLICATION && 659 + collection->usage == HID_USAGE_SENSOR_COLLECTION) 660 + collection_hsdev = hsdev; 694 661 } 695 662 } 696 663 if (last_hsdev) 697 664 last_hsdev->end_collection_index = i; 665 + if (collection_hsdev) 666 + collection_hsdev->end_collection_index = i; 698 667 699 668 ret = mfd_add_hotplug_devices(&hdev->dev, 700 669 sd->hid_sensor_hub_client_devs, ··· 721 676 { 722 677 struct sensor_hub_data *data = hid_get_drvdata(hdev); 723 678 unsigned long flags; 679 + int i; 724 680 725 681 hid_dbg(hdev, " hardware removed\n"); 726 682 hid_hw_close(hdev); 727 683 hid_hw_stop(hdev); 728 684 spin_lock_irqsave(&data->lock, flags); 729 - if (data->pending.status) 730 - complete(&data->pending.ready); 685 + for (i = 0; i < data->hid_sensor_client_cnt; ++i) { 686 + struct hid_sensor_hub_device *hsdev = 687 + data->hid_sensor_hub_client_devs[i].platform_data; 688 + if (hsdev->pending.status) 689 + complete(&hsdev->pending.ready); 690 + } 731 691 spin_unlock_irqrestore(&data->lock, flags); 732 692 mfd_remove_devices(&hdev->dev); 733 693 hid_set_drvdata(hdev, NULL);
+26 -5
drivers/hid/hid-sony.c
··· 802 802 #define DS4_REPORT_0x05_SIZE 32 803 803 #define DS4_REPORT_0x11_SIZE 78 804 804 #define DS4_REPORT_0x81_SIZE 7 805 - #define SIXAXIS_REPORT_0xF2_SIZE 18 805 + #define SIXAXIS_REPORT_0xF2_SIZE 17 806 + #define SIXAXIS_REPORT_0xF5_SIZE 8 806 807 807 808 static DEFINE_SPINLOCK(sony_dev_list_lock); 808 809 static LIST_HEAD(sony_device_list); ··· 1132 1131 */ 1133 1132 static int sixaxis_set_operational_usb(struct hid_device *hdev) 1134 1133 { 1134 + const int buf_size = 1135 + max(SIXAXIS_REPORT_0xF2_SIZE, SIXAXIS_REPORT_0xF5_SIZE); 1136 + __u8 *buf; 1135 1137 int ret; 1136 - char *buf = kmalloc(18, GFP_KERNEL); 1137 1138 1139 + buf = kmalloc(buf_size, GFP_KERNEL); 1138 1140 if (!buf) 1139 1141 return -ENOMEM; 1140 1142 1141 - ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT, 1142 - HID_REQ_GET_REPORT); 1143 + ret = hid_hw_raw_request(hdev, 0xf2, buf, SIXAXIS_REPORT_0xF2_SIZE, 1144 + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 1145 + if (ret < 0) { 1146 + hid_err(hdev, "can't set operational mode: step 1\n"); 1147 + goto out; 1148 + } 1143 1149 1150 + /* 1151 + * Some compatible controllers like the Speedlink Strike FX and 1152 + * Gasia need another query plus an USB interrupt to get operational. 1153 + */ 1154 + ret = hid_hw_raw_request(hdev, 0xf5, buf, SIXAXIS_REPORT_0xF5_SIZE, 1155 + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 1156 + if (ret < 0) { 1157 + hid_err(hdev, "can't set operational mode: step 2\n"); 1158 + goto out; 1159 + } 1160 + 1161 + ret = hid_hw_output_report(hdev, buf, 1); 1144 1162 if (ret < 0) 1145 - hid_err(hdev, "can't set operational mode\n"); 1163 + hid_err(hdev, "can't set operational mode: step 3\n"); 1146 1164 1165 + out: 1147 1166 kfree(buf); 1148 1167 1149 1168 return ret;
-1
drivers/hid/hid-steelseries.c
··· 12 12 */ 13 13 14 14 #include <linux/device.h> 15 - #include <linux/usb.h> 16 15 #include <linux/hid.h> 17 16 #include <linux/module.h> 18 17
+324 -1
drivers/hid/hid-uclogic.c
··· 1 1 /* 2 2 * HID driver for UC-Logic devices not fully compliant with HID standard 3 3 * 4 - * Copyright (c) 2010 Nikolai Kondrashov 4 + * Copyright (c) 2010-2014 Nikolai Kondrashov 5 + * Copyright (c) 2013 Martin Rusko 5 6 */ 6 7 7 8 /* ··· 16 15 #include <linux/hid.h> 17 16 #include <linux/module.h> 18 17 #include <linux/usb.h> 18 + #include <asm/unaligned.h> 19 + #include "usbhid/usbhid.h" 19 20 20 21 #include "hid-ids.h" 21 22 ··· 549 546 0xC0 /* End Collection */ 550 547 }; 551 548 549 + /* Report descriptor template placeholder head */ 550 + #define UCLOGIC_PH_HEAD 0xFE, 0xED, 0x1D 551 + 552 + /* Report descriptor template placeholder IDs */ 553 + enum uclogic_ph_id { 554 + UCLOGIC_PH_ID_X_LM, 555 + UCLOGIC_PH_ID_X_PM, 556 + UCLOGIC_PH_ID_Y_LM, 557 + UCLOGIC_PH_ID_Y_PM, 558 + UCLOGIC_PH_ID_PRESSURE_LM, 559 + UCLOGIC_PH_ID_NUM 560 + }; 561 + 562 + /* Report descriptor template placeholder */ 563 + #define UCLOGIC_PH(_ID) UCLOGIC_PH_HEAD, UCLOGIC_PH_ID_##_ID 564 + #define UCLOGIC_PEN_REPORT_ID 0x07 565 + 566 + /* Fixed report descriptor template */ 567 + static const __u8 uclogic_tablet_rdesc_template[] = { 568 + 0x05, 0x0D, /* Usage Page (Digitizer), */ 569 + 0x09, 0x02, /* Usage (Pen), */ 570 + 0xA1, 0x01, /* Collection (Application), */ 571 + 0x85, 0x07, /* Report ID (7), */ 572 + 0x09, 0x20, /* Usage (Stylus), */ 573 + 0xA0, /* Collection (Physical), */ 574 + 0x14, /* Logical Minimum (0), */ 575 + 0x25, 0x01, /* Logical Maximum (1), */ 576 + 0x75, 0x01, /* Report Size (1), */ 577 + 0x09, 0x42, /* Usage (Tip Switch), */ 578 + 0x09, 0x44, /* Usage (Barrel Switch), */ 579 + 0x09, 0x46, /* Usage (Tablet Pick), */ 580 + 0x95, 0x03, /* Report Count (3), */ 581 + 0x81, 0x02, /* Input (Variable), */ 582 + 0x95, 0x03, /* Report Count (3), */ 583 + 0x81, 0x03, /* Input (Constant, Variable), */ 584 + 0x09, 0x32, /* Usage (In Range), */ 585 + 0x95, 0x01, /* Report Count (1), */ 586 + 0x81, 0x02, /* Input (Variable), */ 587 + 0x95, 0x01, /* Report Count (1), */ 588 + 0x81, 0x03, /* Input (Constant, Variable), */ 589 + 0x75, 0x10, /* Report Size (16), */ 590 + 0x95, 0x01, /* Report Count (1), */ 591 + 0xA4, /* Push, */ 592 + 0x05, 0x01, /* Usage Page (Desktop), */ 593 + 0x65, 0x13, /* Unit (Inch), */ 594 + 0x55, 0xFD, /* Unit Exponent (-3), */ 595 + 0x34, /* Physical Minimum (0), */ 596 + 0x09, 0x30, /* Usage (X), */ 597 + 0x27, UCLOGIC_PH(X_LM), /* Logical Maximum (PLACEHOLDER), */ 598 + 0x47, UCLOGIC_PH(X_PM), /* Physical Maximum (PLACEHOLDER), */ 599 + 0x81, 0x02, /* Input (Variable), */ 600 + 0x09, 0x31, /* Usage (Y), */ 601 + 0x27, UCLOGIC_PH(Y_LM), /* Logical Maximum (PLACEHOLDER), */ 602 + 0x47, UCLOGIC_PH(Y_PM), /* Physical Maximum (PLACEHOLDER), */ 603 + 0x81, 0x02, /* Input (Variable), */ 604 + 0xB4, /* Pop, */ 605 + 0x09, 0x30, /* Usage (Tip Pressure), */ 606 + 0x27, 607 + UCLOGIC_PH(PRESSURE_LM),/* Logical Maximum (PLACEHOLDER), */ 608 + 0x81, 0x02, /* Input (Variable), */ 609 + 0xC0, /* End Collection, */ 610 + 0xC0 /* End Collection */ 611 + }; 612 + 613 + /* Parameter indices */ 614 + enum uclogic_prm { 615 + UCLOGIC_PRM_X_LM = 1, 616 + UCLOGIC_PRM_Y_LM = 2, 617 + UCLOGIC_PRM_PRESSURE_LM = 4, 618 + UCLOGIC_PRM_RESOLUTION = 5, 619 + UCLOGIC_PRM_NUM 620 + }; 621 + 622 + /* Driver data */ 623 + struct uclogic_drvdata { 624 + __u8 *rdesc; 625 + unsigned int rsize; 626 + bool invert_pen_inrange; 627 + bool ignore_pen_usage; 628 + }; 629 + 552 630 static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc, 553 631 unsigned int *rsize) 554 632 { 555 633 struct usb_interface *iface = to_usb_interface(hdev->dev.parent); 556 634 __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; 635 + struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev); 557 636 558 637 switch (hdev->product) { 559 638 case USB_DEVICE_ID_UCLOGIC_TABLET_PF1209: ··· 706 621 break; 707 622 } 708 623 break; 624 + default: 625 + if (drvdata->rdesc != NULL) { 626 + rdesc = drvdata->rdesc; 627 + *rsize = drvdata->rsize; 628 + } 709 629 } 710 630 711 631 return rdesc; 632 + } 633 + 634 + static int uclogic_input_mapping(struct hid_device *hdev, struct hid_input *hi, 635 + struct hid_field *field, struct hid_usage *usage, 636 + unsigned long **bit, int *max) 637 + { 638 + struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev); 639 + 640 + /* discard the unused pen interface */ 641 + if ((drvdata->ignore_pen_usage) && 642 + (field->application == HID_DG_PEN)) 643 + return -1; 644 + 645 + /* let hid-core decide what to do */ 646 + return 0; 647 + } 648 + 649 + static void uclogic_input_configured(struct hid_device *hdev, 650 + struct hid_input *hi) 651 + { 652 + char *name; 653 + const char *suffix = NULL; 654 + struct hid_field *field; 655 + size_t len; 656 + 657 + /* no report associated (HID_QUIRK_MULTI_INPUT not set) */ 658 + if (!hi->report) 659 + return; 660 + 661 + field = hi->report->field[0]; 662 + 663 + switch (field->application) { 664 + case HID_GD_KEYBOARD: 665 + suffix = "Keyboard"; 666 + break; 667 + case HID_GD_MOUSE: 668 + suffix = "Mouse"; 669 + break; 670 + case HID_GD_KEYPAD: 671 + suffix = "Pad"; 672 + break; 673 + case HID_DG_PEN: 674 + suffix = "Pen"; 675 + break; 676 + case HID_CP_CONSUMER_CONTROL: 677 + suffix = "Consumer Control"; 678 + break; 679 + case HID_GD_SYSTEM_CONTROL: 680 + suffix = "System Control"; 681 + break; 682 + } 683 + 684 + if (suffix) { 685 + len = strlen(hdev->name) + 2 + strlen(suffix); 686 + name = devm_kzalloc(&hi->input->dev, len, GFP_KERNEL); 687 + if (name) { 688 + snprintf(name, len, "%s %s", hdev->name, suffix); 689 + hi->input->name = name; 690 + } 691 + } 692 + } 693 + 694 + /** 695 + * Enable fully-functional tablet mode and determine device parameters. 696 + * 697 + * @hdev: HID device 698 + */ 699 + static int uclogic_tablet_enable(struct hid_device *hdev) 700 + { 701 + int rc; 702 + struct usb_device *usb_dev = hid_to_usb_dev(hdev); 703 + struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev); 704 + __le16 *buf = NULL; 705 + size_t len; 706 + s32 params[UCLOGIC_PH_ID_NUM]; 707 + s32 resolution; 708 + __u8 *p; 709 + s32 v; 710 + 711 + /* 712 + * Read string descriptor containing tablet parameters. The specific 713 + * string descriptor and data were discovered by sniffing the Windows 714 + * driver traffic. 715 + * NOTE: This enables fully-functional tablet mode. 716 + */ 717 + len = UCLOGIC_PRM_NUM * sizeof(*buf); 718 + buf = kmalloc(len, GFP_KERNEL); 719 + if (buf == NULL) { 720 + hid_err(hdev, "failed to allocate parameter buffer\n"); 721 + rc = -ENOMEM; 722 + goto cleanup; 723 + } 724 + rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 725 + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, 726 + (USB_DT_STRING << 8) + 0x64, 727 + 0x0409, buf, len, 728 + USB_CTRL_GET_TIMEOUT); 729 + if (rc == -EPIPE) { 730 + hid_err(hdev, "device parameters not found\n"); 731 + rc = -ENODEV; 732 + goto cleanup; 733 + } else if (rc < 0) { 734 + hid_err(hdev, "failed to get device parameters: %d\n", rc); 735 + rc = -ENODEV; 736 + goto cleanup; 737 + } else if (rc != len) { 738 + hid_err(hdev, "invalid device parameters\n"); 739 + rc = -ENODEV; 740 + goto cleanup; 741 + } 742 + 743 + /* Extract device parameters */ 744 + params[UCLOGIC_PH_ID_X_LM] = le16_to_cpu(buf[UCLOGIC_PRM_X_LM]); 745 + params[UCLOGIC_PH_ID_Y_LM] = le16_to_cpu(buf[UCLOGIC_PRM_Y_LM]); 746 + params[UCLOGIC_PH_ID_PRESSURE_LM] = 747 + le16_to_cpu(buf[UCLOGIC_PRM_PRESSURE_LM]); 748 + resolution = le16_to_cpu(buf[UCLOGIC_PRM_RESOLUTION]); 749 + if (resolution == 0) { 750 + params[UCLOGIC_PH_ID_X_PM] = 0; 751 + params[UCLOGIC_PH_ID_Y_PM] = 0; 752 + } else { 753 + params[UCLOGIC_PH_ID_X_PM] = params[UCLOGIC_PH_ID_X_LM] * 754 + 1000 / resolution; 755 + params[UCLOGIC_PH_ID_Y_PM] = params[UCLOGIC_PH_ID_Y_LM] * 756 + 1000 / resolution; 757 + } 758 + 759 + /* Allocate fixed report descriptor */ 760 + drvdata->rdesc = devm_kzalloc(&hdev->dev, 761 + sizeof(uclogic_tablet_rdesc_template), 762 + GFP_KERNEL); 763 + if (drvdata->rdesc == NULL) { 764 + hid_err(hdev, "failed to allocate fixed rdesc\n"); 765 + rc = -ENOMEM; 766 + goto cleanup; 767 + } 768 + drvdata->rsize = sizeof(uclogic_tablet_rdesc_template); 769 + 770 + /* Format fixed report descriptor */ 771 + memcpy(drvdata->rdesc, uclogic_tablet_rdesc_template, 772 + drvdata->rsize); 773 + for (p = drvdata->rdesc; 774 + p <= drvdata->rdesc + drvdata->rsize - 4;) { 775 + if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D && 776 + p[3] < sizeof(params)) { 777 + v = params[p[3]]; 778 + put_unaligned(cpu_to_le32(v), (s32 *)p); 779 + p += 4; 780 + } else { 781 + p++; 782 + } 783 + } 784 + 785 + rc = 0; 786 + 787 + cleanup: 788 + kfree(buf); 789 + return rc; 790 + } 791 + 792 + static int uclogic_probe(struct hid_device *hdev, 793 + const struct hid_device_id *id) 794 + { 795 + int rc; 796 + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 797 + struct uclogic_drvdata *drvdata; 798 + 799 + /* 800 + * libinput requires the pad interface to be on a different node 801 + * than the pen, so use QUIRK_MULTI_INPUT for all tablets. 802 + */ 803 + hdev->quirks |= HID_QUIRK_MULTI_INPUT; 804 + hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT; 805 + 806 + /* Allocate and assign driver data */ 807 + drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL); 808 + if (drvdata == NULL) 809 + return -ENOMEM; 810 + 811 + hid_set_drvdata(hdev, drvdata); 812 + 813 + switch (id->product) { 814 + case USB_DEVICE_ID_HUION_TABLET: 815 + /* If this is the pen interface */ 816 + if (intf->cur_altsetting->desc.bInterfaceNumber == 0) { 817 + rc = uclogic_tablet_enable(hdev); 818 + if (rc) { 819 + hid_err(hdev, "tablet enabling failed\n"); 820 + return rc; 821 + } 822 + drvdata->invert_pen_inrange = true; 823 + } else { 824 + drvdata->ignore_pen_usage = true; 825 + } 826 + break; 827 + } 828 + 829 + rc = hid_parse(hdev); 830 + if (rc) { 831 + hid_err(hdev, "parse failed\n"); 832 + return rc; 833 + } 834 + 835 + rc = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 836 + if (rc) { 837 + hid_err(hdev, "hw start failed\n"); 838 + return rc; 839 + } 840 + 841 + return 0; 842 + } 843 + 844 + static int uclogic_raw_event(struct hid_device *hdev, struct hid_report *report, 845 + u8 *data, int size) 846 + { 847 + struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev); 848 + 849 + if ((drvdata->invert_pen_inrange) && 850 + (report->type == HID_INPUT_REPORT) && 851 + (report->id == UCLOGIC_PEN_REPORT_ID) && 852 + (size >= 2)) 853 + /* Invert the in-range bit */ 854 + data[1] ^= 0x40; 855 + 856 + return 0; 712 857 } 713 858 714 859 static const struct hid_device_id uclogic_devices[] = { ··· 956 641 USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850) }, 957 642 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, 958 643 USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60) }, 644 + { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) }, 645 + { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_HUION_TABLET) }, 959 646 { } 960 647 }; 961 648 MODULE_DEVICE_TABLE(hid, uclogic_devices); ··· 965 648 static struct hid_driver uclogic_driver = { 966 649 .name = "uclogic", 967 650 .id_table = uclogic_devices, 651 + .probe = uclogic_probe, 968 652 .report_fixup = uclogic_report_fixup, 653 + .raw_event = uclogic_raw_event, 654 + .input_mapping = uclogic_input_mapping, 655 + .input_configured = uclogic_input_configured, 969 656 }; 970 657 module_hid_driver(uclogic_driver); 971 658 659 + MODULE_AUTHOR("Martin Rusko"); 660 + MODULE_AUTHOR("Nikolai Kondrashov"); 972 661 MODULE_LICENSE("GPL");
+50 -18
drivers/hid/i2c-hid/i2c-hid.c
··· 37 37 #include <linux/mutex.h> 38 38 #include <linux/acpi.h> 39 39 #include <linux/of.h> 40 + #include <linux/gpio/consumer.h> 40 41 41 42 #include <linux/i2c/i2c-hid.h> 42 43 ··· 145 144 unsigned long flags; /* device flags */ 146 145 147 146 wait_queue_head_t wait; /* For waiting the interrupt */ 147 + struct gpio_desc *desc; 148 + int irq; 148 149 149 150 struct i2c_hid_platform_data pdata; 150 151 }; ··· 788 785 struct i2c_hid *ihid = i2c_get_clientdata(client); 789 786 int ret; 790 787 791 - dev_dbg(&client->dev, "Requesting IRQ: %d\n", client->irq); 788 + dev_dbg(&client->dev, "Requesting IRQ: %d\n", ihid->irq); 792 789 793 - ret = request_threaded_irq(client->irq, NULL, i2c_hid_irq, 790 + ret = request_threaded_irq(ihid->irq, NULL, i2c_hid_irq, 794 791 IRQF_TRIGGER_LOW | IRQF_ONESHOT, 795 792 client->name, ihid); 796 793 if (ret < 0) { 797 794 dev_warn(&client->dev, 798 795 "Could not register for %s interrupt, irq = %d," 799 796 " ret = %d\n", 800 - client->name, client->irq, ret); 797 + client->name, ihid->irq, ret); 801 798 802 799 return ret; 803 800 } ··· 844 841 } 845 842 846 843 #ifdef CONFIG_ACPI 844 + 845 + /* Default GPIO mapping */ 846 + static const struct acpi_gpio_params i2c_hid_irq_gpio = { 0, 0, true }; 847 + static const struct acpi_gpio_mapping i2c_hid_acpi_gpios[] = { 848 + { "gpios", &i2c_hid_irq_gpio, 1 }, 849 + { }, 850 + }; 851 + 847 852 static int i2c_hid_acpi_pdata(struct i2c_client *client, 848 853 struct i2c_hid_platform_data *pdata) 849 854 { ··· 877 866 pdata->hid_descriptor_address = obj->integer.value; 878 867 ACPI_FREE(obj); 879 868 880 - return 0; 869 + return acpi_dev_add_driver_gpios(adev, i2c_hid_acpi_gpios); 881 870 } 882 871 883 872 static const struct acpi_device_id i2c_hid_acpi_match[] = { ··· 941 930 942 931 dbg_hid("HID probe called for i2c 0x%02x\n", client->addr); 943 932 944 - if (!client->irq) { 945 - dev_err(&client->dev, 946 - "HID over i2c has not been provided an Int IRQ\n"); 947 - return -EINVAL; 948 - } 949 - 950 933 ihid = kzalloc(sizeof(struct i2c_hid), GFP_KERNEL); 951 934 if (!ihid) 952 935 return -ENOMEM; ··· 958 953 } 959 954 } else { 960 955 ihid->pdata = *platform_data; 956 + } 957 + 958 + if (client->irq > 0) { 959 + ihid->irq = client->irq; 960 + } else if (ACPI_COMPANION(&client->dev)) { 961 + ihid->desc = gpiod_get(&client->dev, NULL, GPIOD_IN); 962 + if (IS_ERR(ihid->desc)) { 963 + dev_err(&client->dev, "Failed to get GPIO interrupt\n"); 964 + return PTR_ERR(ihid->desc); 965 + } 966 + 967 + ihid->irq = gpiod_to_irq(ihid->desc); 968 + if (ihid->irq < 0) { 969 + gpiod_put(ihid->desc); 970 + dev_err(&client->dev, "Failed to convert GPIO to IRQ\n"); 971 + return ihid->irq; 972 + } 961 973 } 962 974 963 975 i2c_set_clientdata(client, ihid); ··· 1039 1017 hid_destroy_device(hid); 1040 1018 1041 1019 err_irq: 1042 - free_irq(client->irq, ihid); 1020 + free_irq(ihid->irq, ihid); 1043 1021 1044 1022 err_pm: 1045 1023 pm_runtime_put_noidle(&client->dev); 1046 1024 pm_runtime_disable(&client->dev); 1047 1025 1048 1026 err: 1027 + if (ihid->desc) 1028 + gpiod_put(ihid->desc); 1029 + 1049 1030 i2c_hid_free_buffers(ihid); 1050 1031 kfree(ihid); 1051 1032 return ret; ··· 1067 1042 hid = ihid->hid; 1068 1043 hid_destroy_device(hid); 1069 1044 1070 - free_irq(client->irq, ihid); 1045 + free_irq(ihid->irq, ihid); 1071 1046 1072 1047 if (ihid->bufsize) 1073 1048 i2c_hid_free_buffers(ihid); 1074 1049 1050 + if (ihid->desc) 1051 + gpiod_put(ihid->desc); 1052 + 1075 1053 kfree(ihid); 1054 + 1055 + acpi_dev_remove_driver_gpios(ACPI_COMPANION(&client->dev)); 1076 1056 1077 1057 return 0; 1078 1058 } ··· 1090 1060 struct hid_device *hid = ihid->hid; 1091 1061 int ret = 0; 1092 1062 1093 - disable_irq(client->irq); 1063 + disable_irq(ihid->irq); 1094 1064 if (device_may_wakeup(&client->dev)) 1095 - enable_irq_wake(client->irq); 1065 + enable_irq_wake(ihid->irq); 1096 1066 1097 1067 if (hid->driver && hid->driver->suspend) 1098 1068 ret = hid->driver->suspend(hid, PMSG_SUSPEND); ··· 1110 1080 struct i2c_hid *ihid = i2c_get_clientdata(client); 1111 1081 struct hid_device *hid = ihid->hid; 1112 1082 1113 - enable_irq(client->irq); 1083 + enable_irq(ihid->irq); 1114 1084 ret = i2c_hid_hwreset(client); 1115 1085 if (ret) 1116 1086 return ret; 1117 1087 1118 1088 if (device_may_wakeup(&client->dev)) 1119 - disable_irq_wake(client->irq); 1089 + disable_irq_wake(ihid->irq); 1120 1090 1121 1091 if (hid->driver && hid->driver->reset_resume) { 1122 1092 ret = hid->driver->reset_resume(hid); ··· 1131 1101 static int i2c_hid_runtime_suspend(struct device *dev) 1132 1102 { 1133 1103 struct i2c_client *client = to_i2c_client(dev); 1104 + struct i2c_hid *ihid = i2c_get_clientdata(client); 1134 1105 1135 1106 i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); 1136 - disable_irq(client->irq); 1107 + disable_irq(ihid->irq); 1137 1108 return 0; 1138 1109 } 1139 1110 1140 1111 static int i2c_hid_runtime_resume(struct device *dev) 1141 1112 { 1142 1113 struct i2c_client *client = to_i2c_client(dev); 1114 + struct i2c_hid *ihid = i2c_get_clientdata(client); 1143 1115 1144 - enable_irq(client->irq); 1116 + enable_irq(ihid->irq); 1145 1117 i2c_hid_set_power(client, I2C_HID_PWR_ON); 1146 1118 return 0; 1147 1119 }
+6
drivers/hid/usbhid/hid-pidff.c
··· 568 568 int type_id; 569 569 int error; 570 570 571 + pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0; 572 + if (old) { 573 + pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 574 + pidff->pid_id[effect->id]; 575 + } 576 + 571 577 switch (effect->type) { 572 578 case FF_CONSTANT: 573 579 if (!old) {
+8 -4
drivers/hid/usbhid/hid-quirks.c
··· 78 78 { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, 79 79 { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, 80 80 { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, 81 + { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL }, 82 + { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL }, 83 + { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, 81 84 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL }, 85 + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A, HID_QUIRK_ALWAYS_POLL }, 86 + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A, HID_QUIRK_ALWAYS_POLL }, 87 + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A, HID_QUIRK_ALWAYS_POLL }, 82 88 { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, 83 89 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS }, 84 90 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, HID_QUIRK_NO_INIT_REPORTS }, ··· 98 92 { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, 99 93 { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, 100 94 { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, 95 + { USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22, HID_QUIRK_ALWAYS_POLL }, 101 96 { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, 102 97 { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET }, 103 98 { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, ··· 114 107 { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, 115 108 { USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN, HID_QUIRK_NOGET }, 116 109 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, 117 - { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, 118 - { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, 119 110 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT }, 120 111 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60, HID_QUIRK_MULTI_INPUT }, 121 - { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U, HID_QUIRK_MULTI_INPUT }, 122 - { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT }, 123 112 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT }, 124 113 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT }, 125 114 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET, HID_QUIRK_MULTI_INPUT }, ··· 131 128 { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT }, 132 129 { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2, HID_QUIRK_MULTI_INPUT }, 133 130 { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT }, 131 + { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912, HID_QUIRK_MULTI_INPUT }, 134 132 { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS }, 135 133 { USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS }, 136 134 { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS1, HID_QUIRK_NO_INIT_REPORTS },
+1 -7
drivers/hid/wacom.h
··· 131 131 schedule_work(&wacom->work); 132 132 } 133 133 134 - static inline void wacom_notify_battery(struct wacom_wac *wacom_wac) 135 - { 136 - struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); 137 - 138 - power_supply_changed(wacom->battery); 139 - } 140 - 141 134 extern const struct hid_device_id wacom_ids[]; 142 135 143 136 void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); ··· 144 151 int wacom_wac_event(struct hid_device *hdev, struct hid_field *field, 145 152 struct hid_usage *usage, __s32 value); 146 153 void wacom_wac_report(struct hid_device *hdev, struct hid_report *report); 154 + void wacom_battery_work(struct work_struct *work); 147 155 #endif
+77 -20
drivers/hid/wacom_sys.c
··· 406 406 else if (features->type == WACOM_27QHDT) { 407 407 return wacom_set_device_mode(hdev, 131, 3, 2); 408 408 } 409 + else if (features->type == BAMBOO_PAD) { 410 + return wacom_set_device_mode(hdev, 2, 2, 2); 411 + } 409 412 } else if (features->device_type == BTN_TOOL_PEN) { 410 413 if (features->type <= BAMBOO_PT && features->type != WIRELESS) { 411 414 return wacom_set_device_mode(hdev, 2, 2, 2); ··· 527 524 528 525 wacom_wac->shared = &data->shared; 529 526 527 + if (wacom_wac->features.device_type == BTN_TOOL_FINGER) 528 + wacom_wac->shared->touch = hdev; 529 + else if (wacom_wac->features.device_type == BTN_TOOL_PEN) 530 + wacom_wac->shared->pen = hdev; 531 + 530 532 out: 531 533 mutex_unlock(&wacom_udev_list_lock); 532 534 return retval; ··· 549 541 kfree(data); 550 542 } 551 543 552 - static void wacom_remove_shared_data(struct wacom_wac *wacom) 544 + static void wacom_remove_shared_data(struct wacom *wacom) 553 545 { 554 546 struct wacom_hdev_data *data; 547 + struct wacom_wac *wacom_wac = &wacom->wacom_wac; 555 548 556 - if (wacom->shared) { 557 - data = container_of(wacom->shared, struct wacom_hdev_data, shared); 549 + if (wacom_wac->shared) { 550 + data = container_of(wacom_wac->shared, struct wacom_hdev_data, 551 + shared); 552 + 553 + if (wacom_wac->shared->touch == wacom->hdev) 554 + wacom_wac->shared->touch = NULL; 555 + else if (wacom_wac->shared->pen == wacom->hdev) 556 + wacom_wac->shared->pen = NULL; 557 + 558 558 kref_put(&data->kref, wacom_release_shared_data); 559 - wacom->shared = NULL; 559 + wacom_wac->shared = NULL; 560 560 } 561 561 } 562 562 ··· 945 929 } 946 930 947 931 static enum power_supply_property wacom_battery_props[] = { 932 + POWER_SUPPLY_PROP_PRESENT, 948 933 POWER_SUPPLY_PROP_STATUS, 949 934 POWER_SUPPLY_PROP_SCOPE, 950 935 POWER_SUPPLY_PROP_CAPACITY ··· 965 948 int ret = 0; 966 949 967 950 switch (psp) { 951 + case POWER_SUPPLY_PROP_PRESENT: 952 + val->intval = wacom->wacom_wac.bat_connected; 953 + break; 968 954 case POWER_SUPPLY_PROP_SCOPE: 969 955 val->intval = POWER_SUPPLY_SCOPE_DEVICE; 970 956 break; ··· 981 961 else if (wacom->wacom_wac.battery_capacity == 100 && 982 962 wacom->wacom_wac.ps_connected) 983 963 val->intval = POWER_SUPPLY_STATUS_FULL; 964 + else if (wacom->wacom_wac.ps_connected) 965 + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 984 966 else 985 967 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 986 968 break; ··· 1067 1045 1068 1046 static void wacom_destroy_battery(struct wacom *wacom) 1069 1047 { 1070 - if ((wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) && 1071 - wacom->battery) { 1048 + if (wacom->battery) { 1072 1049 power_supply_unregister(wacom->battery); 1073 1050 wacom->battery = NULL; 1074 1051 power_supply_unregister(wacom->ac); ··· 1338 1317 return; 1339 1318 } 1340 1319 1320 + void wacom_battery_work(struct work_struct *work) 1321 + { 1322 + struct wacom *wacom = container_of(work, struct wacom, work); 1323 + 1324 + if ((wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) && 1325 + !wacom->battery) { 1326 + wacom_initialize_battery(wacom); 1327 + } 1328 + else if (!(wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) && 1329 + wacom->battery) { 1330 + wacom_destroy_battery(wacom); 1331 + } 1332 + } 1333 + 1341 1334 /* 1342 1335 * Not all devices report physical dimensions from HID. 1343 1336 * Compute the default from hardcoded logical dimension ··· 1412 1377 1413 1378 hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; 1414 1379 1380 + /* hid-core sets this quirk for the boot interface */ 1381 + hdev->quirks &= ~HID_QUIRK_NOGET; 1382 + 1415 1383 wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); 1416 1384 if (!wacom) 1417 1385 return -ENOMEM; ··· 1454 1416 goto fail_allocate_inputs; 1455 1417 } 1456 1418 1419 + /* 1420 + * Bamboo Pad has a generic hid handling for the Pen, and we switch it 1421 + * into debug mode for the touch part. 1422 + * We ignore the other interfaces. 1423 + */ 1424 + if (features->type == BAMBOO_PAD) { 1425 + if (features->pktlen == WACOM_PKGLEN_PENABLED) { 1426 + features->type = HID_GENERIC; 1427 + } else if ((features->pktlen != WACOM_PKGLEN_BPAD_TOUCH) && 1428 + (features->pktlen != WACOM_PKGLEN_BPAD_TOUCH_USB)) { 1429 + error = -ENODEV; 1430 + goto fail_shared_data; 1431 + } 1432 + } 1433 + 1457 1434 /* set the default size in case we do not get them from hid */ 1458 1435 wacom_set_default_phy(features); 1459 1436 ··· 1503 1450 features->y_max = 4096; 1504 1451 } 1505 1452 1453 + /* 1454 + * Same thing for Bamboo PAD 1455 + */ 1456 + if (features->type == BAMBOO_PAD) 1457 + features->device_type = BTN_TOOL_FINGER; 1458 + 1506 1459 if (hdev->bus == BUS_BLUETOOTH) 1507 1460 features->quirks |= WACOM_QUIRK_BATTERY; 1508 1461 ··· 1525 1466 snprintf(wacom_wac->pad_name, sizeof(wacom_wac->pad_name), 1526 1467 "%s Pad", features->name); 1527 1468 1528 - if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { 1529 - /* Append the device type to the name */ 1530 - if (features->device_type != BTN_TOOL_FINGER) 1531 - strlcat(wacom_wac->name, " Pen", WACOM_NAME_MAX); 1532 - else if (features->touch_max) 1533 - strlcat(wacom_wac->name, " Finger", WACOM_NAME_MAX); 1534 - else 1535 - strlcat(wacom_wac->name, " Pad", WACOM_NAME_MAX); 1469 + /* Append the device type to the name */ 1470 + if (features->device_type != BTN_TOOL_FINGER) 1471 + strlcat(wacom_wac->name, " Pen", WACOM_NAME_MAX); 1472 + else if (features->touch_max) 1473 + strlcat(wacom_wac->name, " Finger", WACOM_NAME_MAX); 1474 + else 1475 + strlcat(wacom_wac->name, " Pad", WACOM_NAME_MAX); 1536 1476 1537 - error = wacom_add_shared_data(hdev); 1538 - if (error) 1539 - goto fail_shared_data; 1540 - } 1477 + error = wacom_add_shared_data(hdev); 1478 + if (error) 1479 + goto fail_shared_data; 1541 1480 1542 1481 if (!(features->quirks & WACOM_QUIRK_MONITOR) && 1543 1482 (features->quirks & WACOM_QUIRK_BATTERY)) { ··· 1588 1531 wacom_clean_inputs(wacom); 1589 1532 wacom_destroy_battery(wacom); 1590 1533 fail_battery: 1591 - wacom_remove_shared_data(wacom_wac); 1534 + wacom_remove_shared_data(wacom); 1592 1535 fail_shared_data: 1593 1536 wacom_clean_inputs(wacom); 1594 1537 fail_allocate_inputs: ··· 1611 1554 if (hdev->bus == BUS_BLUETOOTH) 1612 1555 device_remove_file(&hdev->dev, &dev_attr_speed); 1613 1556 wacom_destroy_battery(wacom); 1614 - wacom_remove_shared_data(&wacom->wacom_wac); 1557 + wacom_remove_shared_data(wacom); 1615 1558 1616 1559 hid_set_drvdata(hdev, NULL); 1617 1560 kfree(wacom);
+275 -131
drivers/hid/wacom_wac.c
··· 45 45 */ 46 46 static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; 47 47 48 + static void wacom_notify_battery(struct wacom_wac *wacom_wac, 49 + int bat_capacity, bool bat_charging, bool bat_connected, 50 + bool ps_connected) 51 + { 52 + struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); 53 + bool changed = wacom_wac->battery_capacity != bat_capacity || 54 + wacom_wac->bat_charging != bat_charging || 55 + wacom_wac->bat_connected != bat_connected || 56 + wacom_wac->ps_connected != ps_connected; 57 + 58 + if (changed) { 59 + wacom_wac->battery_capacity = bat_capacity; 60 + wacom_wac->bat_charging = bat_charging; 61 + wacom_wac->bat_connected = bat_connected; 62 + wacom_wac->ps_connected = ps_connected; 63 + 64 + if (wacom->battery) 65 + power_supply_changed(wacom->battery); 66 + } 67 + } 68 + 48 69 static int wacom_penpartner_irq(struct wacom_wac *wacom) 49 70 { 50 71 unsigned char *data = wacom->data; ··· 440 419 rw = (data[7] >> 2 & 0x07); 441 420 battery_capacity = batcap_gr[rw]; 442 421 ps_connected = rw == 7; 443 - if ((wacom->battery_capacity != battery_capacity) || 444 - (wacom->ps_connected != ps_connected)) { 445 - wacom->battery_capacity = battery_capacity; 446 - wacom->ps_connected = ps_connected; 447 - wacom_notify_battery(wacom); 448 - } 422 + wacom_notify_battery(wacom, battery_capacity, ps_connected, 423 + 1, ps_connected); 449 424 } 450 425 exit: 451 426 return retval; 427 + } 428 + 429 + static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac) 430 + { 431 + struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); 432 + struct hid_report *r; 433 + struct hid_report_enum *re; 434 + 435 + re = &(wacom->hdev->report_enum[HID_FEATURE_REPORT]); 436 + r = re->report_id_hash[WACOM_REPORT_INTUOSREAD]; 437 + if (r) { 438 + hid_hw_request(wacom->hdev, r, HID_REQ_GET_REPORT); 439 + } 452 440 } 453 441 454 442 static int wacom_intuos_inout(struct wacom_wac *wacom) ··· 581 551 (features->type == CINTIQ && !(data[1] & 0x40))) 582 552 return 1; 583 553 584 - if (wacom->shared) { 585 - wacom->shared->stylus_in_proximity = true; 586 - 587 - if (wacom->shared->touch_down) 588 - return 1; 589 - } 554 + wacom->shared->stylus_in_proximity = true; 555 + if (wacom->shared->touch_down) 556 + return 1; 590 557 591 558 /* in Range while exiting */ 592 559 if (((data[1] & 0xfe) == 0x20) && wacom->reporting_data) { ··· 595 568 596 569 /* Exit report */ 597 570 if ((data[1] & 0xfe) == 0x80) { 598 - if (features->quirks & WACOM_QUIRK_MULTI_INPUT) 599 - wacom->shared->stylus_in_proximity = false; 571 + wacom->shared->stylus_in_proximity = false; 600 572 wacom->reporting_data = false; 601 573 602 574 /* don't report exit if we don't know the ID */ ··· 636 610 } 637 611 638 612 /* don't report other events if we don't know the ID */ 639 - if (!wacom->id[idx]) 613 + if (!wacom->id[idx]) { 614 + /* but reschedule a read of the current tool */ 615 + wacom_intuos_schedule_prox_event(wacom); 640 616 return 1; 617 + } 641 618 642 619 return 0; 643 620 } ··· 1052 1023 bat_charging = (power_raw & 0x08) ? 1 : 0; 1053 1024 ps_connected = (power_raw & 0x10) ? 1 : 0; 1054 1025 battery_capacity = batcap_i4[power_raw & 0x07]; 1055 - if ((wacom->battery_capacity != battery_capacity) || 1056 - (wacom->bat_charging != bat_charging) || 1057 - (wacom->ps_connected != ps_connected)) { 1058 - wacom->battery_capacity = battery_capacity; 1059 - wacom->bat_charging = bat_charging; 1060 - wacom->ps_connected = ps_connected; 1061 - wacom_notify_battery(wacom); 1062 - } 1063 - 1026 + wacom_notify_battery(wacom, battery_capacity, bat_charging, 1027 + battery_capacity || bat_charging, 1028 + ps_connected); 1064 1029 break; 1065 1030 default: 1066 1031 dev_dbg(wacom->input->dev.parent, ··· 1063 1040 return 0; 1064 1041 } 1065 1042 return 0; 1043 + } 1044 + 1045 + static int wacom_wac_finger_count_touches(struct wacom_wac *wacom) 1046 + { 1047 + struct input_dev *input = wacom->input; 1048 + unsigned touch_max = wacom->features.touch_max; 1049 + int count = 0; 1050 + int i; 1051 + 1052 + /* non-HID_GENERIC single touch input doesn't call this routine */ 1053 + if ((touch_max == 1) && (wacom->features.type == HID_GENERIC)) 1054 + return wacom->hid_data.tipswitch && 1055 + !wacom->shared->stylus_in_proximity; 1056 + 1057 + for (i = 0; i < input->mt->num_slots; i++) { 1058 + struct input_mt_slot *ps = &input->mt->slots[i]; 1059 + int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); 1060 + if (id >= 0) 1061 + count++; 1062 + } 1063 + 1064 + return count; 1066 1065 } 1067 1066 1068 1067 static int wacom_24hdt_irq(struct wacom_wac *wacom) ··· 1097 1052 int num_contacts_left = 4; /* maximum contacts per packet */ 1098 1053 int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET; 1099 1054 int y_offset = 2; 1100 - static int contact_with_no_pen_down_count = 0; 1101 1055 1102 1056 if (wacom->features.type == WACOM_27QHDT) { 1103 1057 current_num_contacts = data[63]; ··· 1109 1065 * First packet resets the counter since only the first 1110 1066 * packet in series will have non-zero current_num_contacts. 1111 1067 */ 1112 - if (current_num_contacts) { 1068 + if (current_num_contacts) 1113 1069 wacom->num_contacts_left = current_num_contacts; 1114 - contact_with_no_pen_down_count = 0; 1115 - } 1116 1070 1117 1071 contacts_to_send = min(num_contacts_left, wacom->num_contacts_left); 1118 1072 ··· 1143 1101 input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); 1144 1102 input_report_abs(input, ABS_MT_ORIENTATION, w > h); 1145 1103 } 1146 - contact_with_no_pen_down_count++; 1147 1104 } 1148 1105 } 1149 - input_mt_report_pointer_emulation(input, true); 1106 + input_mt_sync_frame(input); 1150 1107 1151 1108 wacom->num_contacts_left -= contacts_to_send; 1152 1109 if (wacom->num_contacts_left <= 0) { 1153 1110 wacom->num_contacts_left = 0; 1154 - wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); 1111 + wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom); 1155 1112 } 1156 1113 return 1; 1157 1114 } ··· 1163 1122 int current_num_contacts = data[2]; 1164 1123 int contacts_to_send = 0; 1165 1124 int x_offset = 0; 1166 - static int contact_with_no_pen_down_count = 0; 1167 1125 1168 1126 /* MTTPC does not support Height and Width */ 1169 1127 if (wacom->features.type == MTTPC || wacom->features.type == MTTPC_B) ··· 1172 1132 * First packet resets the counter since only the first 1173 1133 * packet in series will have non-zero current_num_contacts. 1174 1134 */ 1175 - if (current_num_contacts) { 1135 + if (current_num_contacts) 1176 1136 wacom->num_contacts_left = current_num_contacts; 1177 - contact_with_no_pen_down_count = 0; 1178 - } 1179 1137 1180 1138 /* There are at most 5 contacts per packet */ 1181 1139 contacts_to_send = min(5, wacom->num_contacts_left); ··· 1194 1156 int y = get_unaligned_le16(&data[offset + x_offset + 9]); 1195 1157 input_report_abs(input, ABS_MT_POSITION_X, x); 1196 1158 input_report_abs(input, ABS_MT_POSITION_Y, y); 1197 - contact_with_no_pen_down_count++; 1198 1159 } 1199 1160 } 1200 - input_mt_report_pointer_emulation(input, true); 1161 + input_mt_sync_frame(input); 1201 1162 1202 1163 wacom->num_contacts_left -= contacts_to_send; 1203 1164 if (wacom->num_contacts_left <= 0) { 1204 1165 wacom->num_contacts_left = 0; 1205 - wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); 1166 + wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom); 1206 1167 } 1207 1168 return 1; 1208 1169 } ··· 1210 1173 { 1211 1174 struct input_dev *input = wacom->input; 1212 1175 unsigned char *data = wacom->data; 1213 - int contact_with_no_pen_down_count = 0; 1214 1176 int i; 1215 1177 1216 1178 for (i = 0; i < 2; i++) { ··· 1224 1188 1225 1189 input_report_abs(input, ABS_MT_POSITION_X, x); 1226 1190 input_report_abs(input, ABS_MT_POSITION_Y, y); 1227 - contact_with_no_pen_down_count++; 1228 1191 } 1229 1192 } 1230 - input_mt_report_pointer_emulation(input, true); 1193 + input_mt_sync_frame(input); 1231 1194 1232 1195 /* keep touch state for pen event */ 1233 - wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); 1196 + wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom); 1234 1197 1235 1198 return 1; 1236 1199 } ··· 1557 1522 return 0; 1558 1523 } 1559 1524 1560 - static int wacom_wac_finger_count_touches(struct hid_device *hdev) 1561 - { 1562 - struct wacom *wacom = hid_get_drvdata(hdev); 1563 - struct wacom_wac *wacom_wac = &wacom->wacom_wac; 1564 - struct input_dev *input = wacom_wac->input; 1565 - unsigned touch_max = wacom_wac->features.touch_max; 1566 - int count = 0; 1567 - int i; 1568 - 1569 - if (touch_max == 1) 1570 - return wacom_wac->hid_data.tipswitch && 1571 - !wacom_wac->shared->stylus_in_proximity; 1572 - 1573 - for (i = 0; i < input->mt->num_slots; i++) { 1574 - struct input_mt_slot *ps = &input->mt->slots[i]; 1575 - int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); 1576 - if (id >= 0) 1577 - count++; 1578 - } 1579 - 1580 - return count; 1581 - } 1582 - 1583 1525 static void wacom_wac_finger_report(struct hid_device *hdev, 1584 1526 struct hid_report *report) 1585 1527 { ··· 1571 1559 input_sync(input); 1572 1560 1573 1561 /* keep touch state for pen event */ 1574 - wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(hdev); 1562 + wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac); 1575 1563 } 1576 1564 1577 1565 void wacom_wac_usage_mapping(struct hid_device *hdev, ··· 1631 1619 struct input_dev *pad_input = wacom->pad_input; 1632 1620 unsigned char *data = wacom->data; 1633 1621 int i; 1634 - int contact_with_no_pen_down_count = 0; 1635 1622 1636 1623 if (data[0] != 0x02) 1637 1624 return 0; ··· 1658 1647 } 1659 1648 input_report_abs(input, ABS_MT_POSITION_X, x); 1660 1649 input_report_abs(input, ABS_MT_POSITION_Y, y); 1661 - contact_with_no_pen_down_count++; 1662 1650 } 1663 1651 } 1664 1652 1665 - input_mt_report_pointer_emulation(input, true); 1653 + input_mt_sync_frame(input); 1666 1654 1667 1655 input_report_key(pad_input, BTN_LEFT, (data[1] & 0x08) != 0); 1668 1656 input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0); 1669 1657 input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0); 1670 1658 input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0); 1671 - wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); 1659 + wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom); 1672 1660 1673 1661 return 1; 1674 1662 } 1675 1663 1676 - static int wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data, int last_touch_count) 1664 + static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) 1677 1665 { 1678 1666 struct wacom_features *features = &wacom->features; 1679 1667 struct input_dev *input = wacom->input; ··· 1680 1670 int slot = input_mt_get_slot_by_key(input, data[0]); 1681 1671 1682 1672 if (slot < 0) 1683 - return 0; 1673 + return; 1684 1674 1685 1675 touch = touch && !wacom->shared->stylus_in_proximity; 1686 1676 ··· 1712 1702 input_report_abs(input, ABS_MT_POSITION_Y, y); 1713 1703 input_report_abs(input, ABS_MT_TOUCH_MAJOR, width); 1714 1704 input_report_abs(input, ABS_MT_TOUCH_MINOR, height); 1715 - last_touch_count++; 1716 1705 } 1717 - return last_touch_count; 1718 1706 } 1719 1707 1720 1708 static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data) ··· 1737 1729 unsigned char *data = wacom->data; 1738 1730 int count = data[1] & 0x07; 1739 1731 int i; 1740 - int contact_with_no_pen_down_count = 0; 1741 1732 1742 1733 if (data[0] != 0x02) 1743 1734 return 0; ··· 1747 1740 int msg_id = data[offset]; 1748 1741 1749 1742 if (msg_id >= 2 && msg_id <= 17) 1750 - contact_with_no_pen_down_count = 1751 - wacom_bpt3_touch_msg(wacom, data + offset, 1752 - contact_with_no_pen_down_count); 1743 + wacom_bpt3_touch_msg(wacom, data + offset); 1753 1744 else if (msg_id == 128) 1754 1745 wacom_bpt3_button_msg(wacom, data + offset); 1755 1746 1756 1747 } 1757 - input_mt_report_pointer_emulation(input, true); 1758 - wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); 1748 + input_mt_sync_frame(input); 1749 + wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom); 1759 1750 1760 1751 return 1; 1761 1752 } ··· 1765 1760 unsigned char *data = wacom->data; 1766 1761 int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; 1767 1762 1768 - if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_USB) 1763 + if (data[0] != WACOM_REPORT_PENABLED) 1769 1764 return 0; 1770 - 1771 - if (data[0] == WACOM_REPORT_USB) { 1772 - if (features->type == INTUOSHT && 1773 - wacom->shared->touch_input && 1774 - features->touch_max) { 1775 - input_report_switch(wacom->shared->touch_input, 1776 - SW_MUTE_DEVICE, data[8] & 0x40); 1777 - input_sync(wacom->shared->touch_input); 1778 - } 1779 - return 0; 1780 - } 1781 - 1782 - if (wacom->shared->touch_down) 1783 - return 0; 1784 1765 1785 1766 prox = (data[1] & 0x20) == 0x20; 1786 1767 ··· 1780 1789 * 1781 1790 * Hardware does report zero in most out-of-prox cases but not all. 1782 1791 */ 1783 - if (prox) { 1784 - if (!wacom->shared->stylus_in_proximity) { 1785 - if (data[1] & 0x08) { 1786 - wacom->tool[0] = BTN_TOOL_RUBBER; 1787 - wacom->id[0] = ERASER_DEVICE_ID; 1788 - } else { 1789 - wacom->tool[0] = BTN_TOOL_PEN; 1790 - wacom->id[0] = STYLUS_DEVICE_ID; 1791 - } 1792 - wacom->shared->stylus_in_proximity = true; 1792 + if (!wacom->shared->stylus_in_proximity) { 1793 + if (data[1] & 0x08) { 1794 + wacom->tool[0] = BTN_TOOL_RUBBER; 1795 + wacom->id[0] = ERASER_DEVICE_ID; 1796 + } else { 1797 + wacom->tool[0] = BTN_TOOL_PEN; 1798 + wacom->id[0] = STYLUS_DEVICE_ID; 1793 1799 } 1800 + } 1801 + 1802 + wacom->shared->stylus_in_proximity = prox; 1803 + if (wacom->shared->touch_down) 1804 + return 0; 1805 + 1806 + if (prox) { 1794 1807 x = le16_to_cpup((__le16 *)&data[2]); 1795 1808 y = le16_to_cpup((__le16 *)&data[4]); 1796 1809 p = le16_to_cpup((__le16 *)&data[6]); ··· 1810 1815 pen = data[1] & 0x01; 1811 1816 btn1 = data[1] & 0x02; 1812 1817 btn2 = data[1] & 0x04; 1818 + } else { 1819 + wacom->id[0] = 0; 1813 1820 } 1814 1821 1815 1822 input_report_key(input, BTN_TOUCH, pen); ··· 1822 1825 input_report_abs(input, ABS_Y, y); 1823 1826 input_report_abs(input, ABS_PRESSURE, p); 1824 1827 input_report_abs(input, ABS_DISTANCE, d); 1825 - 1826 - if (!prox) { 1827 - wacom->id[0] = 0; 1828 - wacom->shared->stylus_in_proximity = false; 1829 - } 1830 1828 1831 1829 input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */ 1832 1830 input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */ ··· 1841 1849 return 0; 1842 1850 } 1843 1851 1852 + static void wacom_bamboo_pad_pen_event(struct wacom_wac *wacom, 1853 + unsigned char *data) 1854 + { 1855 + unsigned char prefix; 1856 + 1857 + /* 1858 + * We need to reroute the event from the debug interface to the 1859 + * pen interface. 1860 + * We need to add the report ID to the actual pen report, so we 1861 + * temporary overwrite the first byte to prevent having to kzalloc/kfree 1862 + * and memcpy the report. 1863 + */ 1864 + prefix = data[0]; 1865 + data[0] = WACOM_REPORT_BPAD_PEN; 1866 + 1867 + /* 1868 + * actually reroute the event. 1869 + * No need to check if wacom->shared->pen is valid, hid_input_report() 1870 + * will check for us. 1871 + */ 1872 + hid_input_report(wacom->shared->pen, HID_INPUT_REPORT, data, 1873 + WACOM_PKGLEN_PENABLED, 1); 1874 + 1875 + data[0] = prefix; 1876 + } 1877 + 1878 + static int wacom_bamboo_pad_touch_event(struct wacom_wac *wacom, 1879 + unsigned char *data) 1880 + { 1881 + struct input_dev *input = wacom->input; 1882 + unsigned char *finger_data, prefix; 1883 + unsigned id; 1884 + int x, y; 1885 + bool valid; 1886 + 1887 + prefix = data[0]; 1888 + 1889 + for (id = 0; id < wacom->features.touch_max; id++) { 1890 + valid = !!(prefix & BIT(id)) && 1891 + !wacom->shared->stylus_in_proximity; 1892 + 1893 + input_mt_slot(input, id); 1894 + input_mt_report_slot_state(input, MT_TOOL_FINGER, valid); 1895 + 1896 + if (!valid) 1897 + continue; 1898 + 1899 + finger_data = data + 1 + id * 3; 1900 + x = finger_data[0] | ((finger_data[1] & 0x0f) << 8); 1901 + y = (finger_data[2] << 4) | (finger_data[1] >> 4); 1902 + 1903 + input_report_abs(input, ABS_MT_POSITION_X, x); 1904 + input_report_abs(input, ABS_MT_POSITION_Y, y); 1905 + } 1906 + 1907 + input_mt_sync_frame(input); 1908 + 1909 + input_report_key(input, BTN_LEFT, prefix & 0x40); 1910 + input_report_key(input, BTN_RIGHT, prefix & 0x80); 1911 + 1912 + /* keep touch state for pen event */ 1913 + wacom->shared->touch_down = !!prefix && 1914 + !wacom->shared->stylus_in_proximity; 1915 + 1916 + return 1; 1917 + } 1918 + 1919 + static int wacom_bamboo_pad_irq(struct wacom_wac *wacom, size_t len) 1920 + { 1921 + unsigned char *data = wacom->data; 1922 + 1923 + if (!((len == WACOM_PKGLEN_BPAD_TOUCH) || 1924 + (len == WACOM_PKGLEN_BPAD_TOUCH_USB)) || 1925 + (data[0] != WACOM_REPORT_BPAD_TOUCH)) 1926 + return 0; 1927 + 1928 + if (data[1] & 0x01) 1929 + wacom_bamboo_pad_pen_event(wacom, &data[1]); 1930 + 1931 + if (data[1] & 0x02) 1932 + return wacom_bamboo_pad_touch_event(wacom, &data[9]); 1933 + 1934 + return 0; 1935 + } 1936 + 1844 1937 static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) 1845 1938 { 1846 1939 unsigned char *data = wacom->data; ··· 1936 1859 1937 1860 connected = data[1] & 0x01; 1938 1861 if (connected) { 1939 - int pid, battery, ps_connected; 1862 + int pid, battery, charging; 1940 1863 1941 1864 if ((wacom->shared->type == INTUOSHT) && 1942 1865 wacom->shared->touch_input && ··· 1948 1871 1949 1872 pid = get_unaligned_be16(&data[6]); 1950 1873 battery = (data[5] & 0x3f) * 100 / 31; 1951 - ps_connected = !!(data[5] & 0x80); 1874 + charging = !!(data[5] & 0x80); 1952 1875 if (wacom->pid != pid) { 1953 1876 wacom->pid = pid; 1954 1877 wacom_schedule_work(wacom); 1955 1878 } 1956 1879 1957 - if (wacom->shared->type && 1958 - (battery != wacom->battery_capacity || 1959 - ps_connected != wacom->ps_connected)) { 1960 - wacom->battery_capacity = battery; 1961 - wacom->ps_connected = ps_connected; 1962 - wacom->bat_charging = ps_connected && 1963 - wacom->battery_capacity < 100; 1964 - wacom_notify_battery(wacom); 1965 - } 1880 + if (wacom->shared->type) 1881 + wacom_notify_battery(wacom, battery, charging, 1, 0); 1882 + 1966 1883 } else if (wacom->pid != 0) { 1967 1884 /* disconnected while previously connected */ 1968 1885 wacom->pid = 0; 1969 1886 wacom_schedule_work(wacom); 1970 - wacom->battery_capacity = 0; 1971 - wacom->bat_charging = 0; 1972 - wacom->ps_connected = 0; 1887 + wacom_notify_battery(wacom, 0, 0, 0, 0); 1973 1888 } 1974 1889 1890 + return 0; 1891 + } 1892 + 1893 + static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) 1894 + { 1895 + struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); 1896 + struct wacom_features *features = &wacom_wac->features; 1897 + unsigned char *data = wacom_wac->data; 1898 + 1899 + if (data[0] != WACOM_REPORT_USB) 1900 + return 0; 1901 + 1902 + if (features->type == INTUOSHT && 1903 + wacom_wac->shared->touch_input && 1904 + features->touch_max) { 1905 + input_report_switch(wacom_wac->shared->touch_input, 1906 + SW_MUTE_DEVICE, data[8] & 0x40); 1907 + input_sync(wacom_wac->shared->touch_input); 1908 + } 1909 + 1910 + if (data[9] & 0x02) { /* wireless module is attached */ 1911 + int battery = (data[8] & 0x3f) * 100 / 31; 1912 + bool charging = !!(data[8] & 0x80); 1913 + 1914 + wacom_notify_battery(wacom_wac, battery, charging, 1915 + battery || charging, 1); 1916 + 1917 + if (!wacom->battery && 1918 + !(features->quirks & WACOM_QUIRK_BATTERY)) { 1919 + features->quirks |= WACOM_QUIRK_BATTERY; 1920 + INIT_WORK(&wacom->work, wacom_battery_work); 1921 + wacom_schedule_work(wacom_wac); 1922 + } 1923 + } 1924 + else if ((features->quirks & WACOM_QUIRK_BATTERY) && 1925 + wacom->battery) { 1926 + features->quirks &= ~WACOM_QUIRK_BATTERY; 1927 + INIT_WORK(&wacom->work, wacom_battery_work); 1928 + wacom_schedule_work(wacom_wac); 1929 + wacom_notify_battery(wacom_wac, 0, 0, 0, 0); 1930 + } 1975 1931 return 0; 1976 1932 } 1977 1933 ··· 2077 1967 case INTUOSPL: 2078 1968 if (len == WACOM_PKGLEN_BBTOUCH3) 2079 1969 sync = wacom_bpt3_touch(wacom_wac); 1970 + else if (wacom_wac->data[0] == WACOM_REPORT_USB) 1971 + sync = wacom_status_irq(wacom_wac, len); 2080 1972 else 2081 1973 sync = wacom_intuos_irq(wacom_wac); 2082 1974 break; ··· 2094 1982 2095 1983 case BAMBOO_PT: 2096 1984 case INTUOSHT: 2097 - sync = wacom_bpt_irq(wacom_wac, len); 1985 + if (wacom_wac->data[0] == WACOM_REPORT_USB) 1986 + sync = wacom_status_irq(wacom_wac, len); 1987 + else 1988 + sync = wacom_bpt_irq(wacom_wac, len); 1989 + break; 1990 + 1991 + case BAMBOO_PAD: 1992 + sync = wacom_bamboo_pad_irq(wacom_wac, len); 2098 1993 break; 2099 1994 2100 1995 case WIRELESS: ··· 2172 2053 features->x_max = 1023; 2173 2054 features->y_max = 1023; 2174 2055 } 2175 - 2176 - /* these device have multiple inputs */ 2177 - if (features->type >= WIRELESS || 2178 - (features->type >= INTUOS5S && features->type <= INTUOSHT) || 2179 - (features->oVid && features->oPid)) 2180 - features->quirks |= WACOM_QUIRK_MULTI_INPUT; 2181 2056 2182 2057 /* quirk for bamboo touch with 2 low res touches */ 2183 2058 if (features->type == BAMBOO_PT && ··· 2435 2322 features->distance_max, 2436 2323 0, 0); 2437 2324 } 2325 + break; 2326 + case BAMBOO_PAD: 2327 + __clear_bit(ABS_MISC, input_dev->absbit); 2328 + input_mt_init_slots(input_dev, features->touch_max, 2329 + INPUT_MT_POINTER); 2330 + __set_bit(BTN_LEFT, input_dev->keybit); 2331 + __set_bit(BTN_RIGHT, input_dev->keybit); 2438 2332 break; 2439 2333 } 2440 2334 return 0; ··· 2892 2772 { "Wacom Cintiq 13HD", 59152, 33448, 1023, 63, 2893 2773 WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 2894 2774 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET }; 2775 + static const struct wacom_features wacom_features_0x333 = 2776 + { "Wacom Cintiq 13HD touch", 59152, 33448, 2047, 63, 2777 + WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 2778 + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, 2779 + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x335 }; 2780 + static const struct wacom_features wacom_features_0x335 = 2781 + { "Wacom Cintiq 13HD touch", .type = WACOM_24HDT, /* Touch */ 2782 + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x333, .touch_max = 10, 2783 + .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; 2895 2784 static const struct wacom_features wacom_features_0xC7 = 2896 2785 { "Wacom DTU1931", 37832, 30305, 511, 0, 2897 2786 PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; ··· 3105 2976 { "Wacom ISDv5 30C", .type = WACOM_24HDT, /* Touch */ 3106 2977 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10, 3107 2978 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; 2979 + static const struct wacom_features wacom_features_0x318 = 2980 + { "Wacom USB Bamboo PAD", 4095, 4095, /* Touch */ 2981 + .type = BAMBOO_PAD, 35, 48, .touch_max = 4 }; 2982 + static const struct wacom_features wacom_features_0x319 = 2983 + { "Wacom Wireless Bamboo PAD", 4095, 4095, /* Touch */ 2984 + .type = BAMBOO_PAD, 35, 48, .touch_max = 4 }; 3108 2985 static const struct wacom_features wacom_features_0x323 = 3109 2986 { "Wacom Intuos P M", 21600, 13500, 1023, 31, 3110 2987 INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, ··· 3125 2990 3126 2991 #define BT_DEVICE_WACOM(prod) \ 3127 2992 HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ 2993 + .driver_data = (kernel_ulong_t)&wacom_features_##prod 2994 + 2995 + #define I2C_DEVICE_WACOM(prod) \ 2996 + HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ 3128 2997 .driver_data = (kernel_ulong_t)&wacom_features_##prod 3129 2998 3130 2999 #define USB_DEVICE_LENOVO(prod) \ ··· 3263 3124 { USB_DEVICE_WACOM(0x314) }, 3264 3125 { USB_DEVICE_WACOM(0x315) }, 3265 3126 { USB_DEVICE_WACOM(0x317) }, 3127 + { USB_DEVICE_WACOM(0x318) }, 3128 + { USB_DEVICE_WACOM(0x319) }, 3266 3129 { USB_DEVICE_WACOM(0x323) }, 3267 3130 { USB_DEVICE_WACOM(0x32A) }, 3268 3131 { USB_DEVICE_WACOM(0x32B) }, 3269 3132 { USB_DEVICE_WACOM(0x32C) }, 3270 3133 { USB_DEVICE_WACOM(0x32F) }, 3134 + { USB_DEVICE_WACOM(0x333) }, 3135 + { USB_DEVICE_WACOM(0x335) }, 3271 3136 { USB_DEVICE_WACOM(0x4001) }, 3272 3137 { USB_DEVICE_WACOM(0x4004) }, 3273 3138 { USB_DEVICE_WACOM(0x5000) }, ··· 3279 3136 { USB_DEVICE_LENOVO(0x6004) }, 3280 3137 3281 3138 { USB_DEVICE_WACOM(HID_ANY_ID) }, 3139 + { I2C_DEVICE_WACOM(HID_ANY_ID) }, 3282 3140 { } 3283 3141 }; 3284 3142 MODULE_DEVICE_TABLE(hid, wacom_ids);
+12 -5
drivers/hid/wacom_wac.h
··· 33 33 #define WACOM_PKGLEN_MTTPC 40 34 34 #define WACOM_PKGLEN_DTUS 68 35 35 #define WACOM_PKGLEN_PENABLED 8 36 + #define WACOM_PKGLEN_BPAD_TOUCH 32 37 + #define WACOM_PKGLEN_BPAD_TOUCH_USB 64 36 38 37 39 /* wacom data size per MT contact */ 38 40 #define WACOM_BYTES_PER_MT_PACKET 11 ··· 69 67 #define WACOM_REPORT_24HDT 1 70 68 #define WACOM_REPORT_WL 128 71 69 #define WACOM_REPORT_USB 192 70 + #define WACOM_REPORT_BPAD_PEN 3 71 + #define WACOM_REPORT_BPAD_TOUCH 16 72 72 73 73 /* device quirks */ 74 - #define WACOM_QUIRK_MULTI_INPUT 0x0001 75 - #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 76 - #define WACOM_QUIRK_NO_INPUT 0x0004 77 - #define WACOM_QUIRK_MONITOR 0x0008 78 - #define WACOM_QUIRK_BATTERY 0x0010 74 + #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0001 75 + #define WACOM_QUIRK_NO_INPUT 0x0002 76 + #define WACOM_QUIRK_MONITOR 0x0004 77 + #define WACOM_QUIRK_BATTERY 0x0008 79 78 80 79 #define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \ 81 80 ((f)->physical == HID_DG_STYLUS) || \ ··· 125 122 BAMBOO_PT, 126 123 WACOM_24HDT, 127 124 WACOM_27QHDT, 125 + BAMBOO_PAD, 128 126 TABLETPC, /* add new TPC below */ 129 127 TABLETPCE, 130 128 TABLETPC2FG, ··· 173 169 unsigned touch_max; 174 170 int type; 175 171 struct input_dev *touch_input; 172 + struct hid_device *pen; 173 + struct hid_device *touch; 176 174 }; 177 175 178 176 struct hid_data { ··· 211 205 int battery_capacity; 212 206 int num_contacts_left; 213 207 int bat_charging; 208 + int bat_connected; 214 209 int ps_connected; 215 210 u8 bt_features; 216 211 u8 bt_high_speed;
+2 -1
drivers/iio/accel/hid-sensor-accel-3d.c
··· 123 123 *val = sensor_hub_input_attr_get_raw_value( 124 124 accel_state->common_attributes.hsdev, 125 125 HID_USAGE_SENSOR_ACCEL_3D, address, 126 - report_id); 126 + report_id, 127 + SENSOR_HUB_SYNC); 127 128 else { 128 129 *val = 0; 129 130 hid_sensor_power_state(&accel_state->common_attributes,
+12 -12
drivers/iio/common/hid-sensors/hid-sensor-attributes.c
··· 153 153 int ret; 154 154 155 155 ret = sensor_hub_get_feature(st->hsdev, 156 - st->poll.report_id, 157 - st->poll.index, &value); 156 + st->poll.report_id, 157 + st->poll.index, sizeof(value), &value); 158 158 159 159 if (ret < 0 || value < 0) { 160 160 return -EINVAL; ··· 174 174 int ret; 175 175 176 176 ret = sensor_hub_get_feature(st->hsdev, 177 - st->poll.report_id, 178 - st->poll.index, &value); 177 + st->poll.report_id, 178 + st->poll.index, sizeof(value), &value); 179 179 if (ret < 0 || value < 0) { 180 180 *val1 = *val2 = 0; 181 181 return -EINVAL; ··· 212 212 else 213 213 value = 0; 214 214 } 215 - ret = sensor_hub_set_feature(st->hsdev, 216 - st->poll.report_id, 217 - st->poll.index, value); 215 + ret = sensor_hub_set_feature(st->hsdev, st->poll.report_id, 216 + st->poll.index, sizeof(value), &value); 218 217 if (ret < 0 || value < 0) 219 218 ret = -EINVAL; 220 219 ··· 228 229 int ret; 229 230 230 231 ret = sensor_hub_get_feature(st->hsdev, 231 - st->sensitivity.report_id, 232 - st->sensitivity.index, &value); 232 + st->sensitivity.report_id, 233 + st->sensitivity.index, sizeof(value), 234 + &value); 233 235 if (ret < 0 || value < 0) { 234 236 *val1 = *val2 = 0; 235 237 return -EINVAL; ··· 253 253 value = convert_to_vtf_format(st->sensitivity.size, 254 254 st->sensitivity.unit_expo, 255 255 val1, val2); 256 - ret = sensor_hub_set_feature(st->hsdev, 257 - st->sensitivity.report_id, 258 - st->sensitivity.index, value); 256 + ret = sensor_hub_set_feature(st->hsdev, st->sensitivity.report_id, 257 + st->sensitivity.index, sizeof(value), 258 + &value); 259 259 if (ret < 0 || value < 0) 260 260 ret = -EINVAL; 261 261
+7 -6
drivers/iio/common/hid-sensors/hid-sensor-trigger.c
··· 68 68 if (state_val >= 0) { 69 69 state_val += st->power_state.logical_minimum; 70 70 sensor_hub_set_feature(st->hsdev, st->power_state.report_id, 71 - st->power_state.index, 72 - (s32)state_val); 71 + st->power_state.index, sizeof(state_val), 72 + &state_val); 73 73 } 74 74 75 75 if (report_val >= 0) { 76 76 report_val += st->report_state.logical_minimum; 77 77 sensor_hub_set_feature(st->hsdev, st->report_state.report_id, 78 - st->report_state.index, 79 - (s32)report_val); 78 + st->report_state.index, 79 + sizeof(report_val), 80 + &report_val); 80 81 } 81 82 82 83 sensor_hub_get_feature(st->hsdev, st->power_state.report_id, 83 - st->power_state.index, 84 - &state_val); 84 + st->power_state.index, 85 + sizeof(state_val), &state_val); 85 86 if (state && poll_value) 86 87 msleep_interruptible(poll_value * 2); 87 88
+2 -1
drivers/iio/gyro/hid-sensor-gyro-3d.c
··· 123 123 *val = sensor_hub_input_attr_get_raw_value( 124 124 gyro_state->common_attributes.hsdev, 125 125 HID_USAGE_SENSOR_GYRO_3D, address, 126 - report_id); 126 + report_id, 127 + SENSOR_HUB_SYNC); 127 128 else { 128 129 *val = 0; 129 130 hid_sensor_power_state(&gyro_state->common_attributes,
+2 -1
drivers/iio/light/hid-sensor-als.c
··· 101 101 *val = sensor_hub_input_attr_get_raw_value( 102 102 als_state->common_attributes.hsdev, 103 103 HID_USAGE_SENSOR_ALS, address, 104 - report_id); 104 + report_id, 105 + SENSOR_HUB_SYNC); 105 106 hid_sensor_power_state(&als_state->common_attributes, 106 107 false); 107 108 } else {
+2 -1
drivers/iio/light/hid-sensor-prox.c
··· 96 96 *val = sensor_hub_input_attr_get_raw_value( 97 97 prox_state->common_attributes.hsdev, 98 98 HID_USAGE_SENSOR_PROX, address, 99 - report_id); 99 + report_id, 100 + SENSOR_HUB_SYNC); 100 101 hid_sensor_power_state(&prox_state->common_attributes, 101 102 false); 102 103 } else {
+2 -1
drivers/iio/magnetometer/hid-sensor-magn-3d.c
··· 170 170 *val = sensor_hub_input_attr_get_raw_value( 171 171 magn_state->common_attributes.hsdev, 172 172 HID_USAGE_SENSOR_COMPASS_3D, address, 173 - report_id); 173 + report_id, 174 + SENSOR_HUB_SYNC); 174 175 else { 175 176 *val = 0; 176 177 hid_sensor_power_state(&magn_state->common_attributes,
+2 -1
drivers/iio/orientation/hid-sensor-incl-3d.c
··· 124 124 *val = sensor_hub_input_attr_get_raw_value( 125 125 incl_state->common_attributes.hsdev, 126 126 HID_USAGE_SENSOR_INCLINOMETER_3D, address, 127 - report_id); 127 + report_id, 128 + SENSOR_HUB_SYNC); 128 129 else { 129 130 hid_sensor_power_state(&incl_state->common_attributes, 130 131 false);
+2 -1
drivers/iio/pressure/hid-sensor-press.c
··· 100 100 *val = sensor_hub_input_attr_get_raw_value( 101 101 press_state->common_attributes.hsdev, 102 102 HID_USAGE_SENSOR_PRESSURE, address, 103 - report_id); 103 + report_id, 104 + SENSOR_HUB_SYNC); 104 105 hid_sensor_power_state(&press_state->common_attributes, 105 106 false); 106 107 } else {
+7 -2
drivers/input/input-mt.c
··· 88 88 goto err_mem; 89 89 } 90 90 91 - /* Mark slots as 'unused' */ 91 + /* Mark slots as 'inactive' */ 92 92 for (i = 0; i < num_slots; i++) 93 93 input_mt_set_value(&mt->slots[i], ABS_MT_TRACKING_ID, -1); 94 + 95 + /* Mark slots as 'unused' */ 96 + mt->frame = 1; 94 97 95 98 dev->mt = mt; 96 99 return 0; ··· 442 439 * set the key on the first unused slot and return. 443 440 * 444 441 * If no available slot can be found, -1 is returned. 442 + * Note that for this function to work properly, input_mt_sync_frame() has 443 + * to be called at each frame. 445 444 */ 446 445 int input_mt_get_slot_by_key(struct input_dev *dev, int key) 447 446 { ··· 458 453 return s - mt->slots; 459 454 460 455 for (s = mt->slots; s != mt->slots + mt->num_slots; s++) 461 - if (!input_mt_is_active(s)) { 456 + if (!input_mt_is_active(s) && !input_mt_is_used(mt, s)) { 462 457 s->key = key; 463 458 return s - mt->slots; 464 459 }
+1 -1
drivers/rtc/rtc-hid-sensor-time.c
··· 213 213 /* get a report with all values through requesting one value */ 214 214 sensor_hub_input_attr_get_raw_value(time_state->common_attributes.hsdev, 215 215 HID_USAGE_SENSOR_TIME, hid_time_addresses[0], 216 - time_state->info[0].report_id); 216 + time_state->info[0].report_id, SENSOR_HUB_SYNC); 217 217 /* wait for all values (event) */ 218 218 ret = wait_for_completion_killable_timeout( 219 219 &time_state->comp_last_time, HZ*6);
+45 -10
include/linux/hid-sensor-hub.h
··· 49 49 }; 50 50 51 51 /** 52 + * struct sensor_hub_pending - Synchronous read pending information 53 + * @status: Pending status true/false. 54 + * @ready: Completion synchronization data. 55 + * @usage_id: Usage id for physical device, E.g. Gyro usage id. 56 + * @attr_usage_id: Usage Id of a field, E.g. X-AXIS for a gyro. 57 + * @raw_size: Response size for a read request. 58 + * @raw_data: Place holder for received response. 59 + */ 60 + struct sensor_hub_pending { 61 + bool status; 62 + struct completion ready; 63 + u32 usage_id; 64 + u32 attr_usage_id; 65 + int raw_size; 66 + u8 *raw_data; 67 + }; 68 + 69 + /** 52 70 * struct hid_sensor_hub_device - Stores the hub instance data 53 71 * @hdev: Stores the hid instance. 54 72 * @vendor_id: Vendor id of hub device. 55 73 * @product_id: Product id of hub device. 74 + * @usage: Usage id for this hub device instance. 56 75 * @start_collection_index: Starting index for a phy type collection 57 76 * @end_collection_index: Last index for a phy type collection 77 + * @mutex: synchronizing mutex. 78 + * @pending: Holds information of pending sync read request. 58 79 */ 59 80 struct hid_sensor_hub_device { 60 81 struct hid_device *hdev; 61 82 u32 vendor_id; 62 83 u32 product_id; 84 + u32 usage; 63 85 int start_collection_index; 64 86 int end_collection_index; 87 + struct mutex mutex; 88 + struct sensor_hub_pending pending; 65 89 }; 66 90 67 91 /** ··· 176 152 * @usage_id: Attribute usage id of parent physical device as per spec 177 153 * @attr_usage_id: Attribute usage id as per spec 178 154 * @report_id: Report id to look for 155 + * @flag: Synchronous or asynchronous read 179 156 * 180 - * Issues a synchronous read request for an input attribute. Returns 181 - * data upto 32 bits. Since client can get events, so this call should 182 - * not be used for data paths, this will impact performance. 157 + * Issues a synchronous or asynchronous read request for an input attribute. 158 + * Returns data upto 32 bits. 183 159 */ 184 160 161 + enum sensor_hub_read_flags { 162 + SENSOR_HUB_SYNC, 163 + SENSOR_HUB_ASYNC, 164 + }; 165 + 185 166 int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, 186 - u32 usage_id, 187 - u32 attr_usage_id, u32 report_id); 167 + u32 usage_id, 168 + u32 attr_usage_id, u32 report_id, 169 + enum sensor_hub_read_flags flag 170 + ); 171 + 188 172 /** 189 173 * sensor_hub_set_feature() - Feature set request 190 174 * @hsdev: Hub device instance. 191 175 * @report_id: Report id to look for 192 176 * @field_index: Field index inside a report 193 - * @value: Value to set 177 + * @buffer_size: size of the buffer 178 + * @buffer: buffer to use in the feature set 194 179 * 195 180 * Used to set a field in feature report. For example this can set polling 196 181 * interval, sensitivity, activate/deactivate state. 197 182 */ 198 183 int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, 199 - u32 field_index, s32 value); 184 + u32 field_index, int buffer_size, void *buffer); 200 185 201 186 /** 202 187 * sensor_hub_get_feature() - Feature get request 203 188 * @hsdev: Hub device instance. 204 189 * @report_id: Report id to look for 205 190 * @field_index: Field index inside a report 206 - * @value: Place holder for return value 191 + * @buffer_size: size of the buffer 192 + * @buffer: buffer to copy output 207 193 * 208 194 * Used to get a field in feature report. For example this can get polling 209 - * interval, sensitivity, activate/deactivate state. 195 + * interval, sensitivity, activate/deactivate state. On success it returns 196 + * number of bytes copied to buffer. On failure, it returns value < 0. 210 197 */ 211 198 int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, 212 - u32 field_index, s32 *value); 199 + u32 field_index, int buffer_size, void *buffer); 213 200 214 201 /* hid-sensor-attributes */ 215 202
+2
include/linux/hid-sensor-ids.h
··· 21 21 22 22 #define HID_MAX_PHY_DEVICES 0xFF 23 23 24 + #define HID_USAGE_SENSOR_COLLECTION 0x200001 25 + 24 26 /* Accel 3D (200073) */ 25 27 #define HID_USAGE_SENSOR_ACCEL_3D 0x200073 26 28 #define HID_USAGE_SENSOR_DATA_ACCELERATION 0x200452
+2
include/linux/hid.h
··· 159 159 #define HID_UP_LED 0x00080000 160 160 #define HID_UP_BUTTON 0x00090000 161 161 #define HID_UP_ORDINAL 0x000a0000 162 + #define HID_UP_TELEPHONY 0x000b0000 162 163 #define HID_UP_CONSUMER 0x000c0000 163 164 #define HID_UP_DIGITIZER 0x000d0000 164 165 #define HID_UP_PID 0x000f0000 ··· 270 269 #define HID_DG_DEVICEINDEX 0x000d0053 271 270 #define HID_DG_CONTACTCOUNT 0x000d0054 272 271 #define HID_DG_CONTACTMAX 0x000d0055 272 + #define HID_DG_BUTTONTYPE 0x000d0059 273 273 #define HID_DG_BARRELSWITCH2 0x000d005a 274 274 #define HID_DG_TOOLSERIALNUMBER 0x000d005b 275 275
+4
include/uapi/linux/input.h
··· 702 702 #define KEY_NUMERIC_9 0x209 703 703 #define KEY_NUMERIC_STAR 0x20a 704 704 #define KEY_NUMERIC_POUND 0x20b 705 + #define KEY_NUMERIC_A 0x20c /* Phone key A - HUT Telephony 0xb9 */ 706 + #define KEY_NUMERIC_B 0x20d 707 + #define KEY_NUMERIC_C 0x20e 708 + #define KEY_NUMERIC_D 0x20f 705 709 706 710 #define KEY_CAMERA_FOCUS 0x210 707 711 #define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */
+2
samples/hidraw/Makefile
··· 8 8 always := $(hostprogs-y) 9 9 10 10 HOSTCFLAGS_hid-example.o += -I$(objtree)/usr/include 11 + 12 + all: hid-example
+5 -1
samples/hidraw/hid-example.c
··· 46 46 char buf[256]; 47 47 struct hidraw_report_descriptor rpt_desc; 48 48 struct hidraw_devinfo info; 49 + char *device = "/dev/hidraw0"; 50 + 51 + if (argc > 1) 52 + device = argv[1]; 49 53 50 54 /* Open the Device with non-blocking reads. In real life, 51 55 don't use a hard coded path; use libudev instead. */ 52 - fd = open("/dev/hidraw0", O_RDWR|O_NONBLOCK); 56 + fd = open(device, O_RDWR|O_NONBLOCK); 53 57 54 58 if (fd < 0) { 55 59 perror("Unable to open device");