diff options
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/Kconfig | 16 | ||||
-rw-r--r-- | drivers/hid/hid-apple.c | 3 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 1 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 25 | ||||
-rw-r--r-- | drivers/hid/hid-logitech-dj.c | 5 | ||||
-rw-r--r-- | drivers/hid/hid-wacom.c | 302 | ||||
-rw-r--r-- | drivers/hid/hid-waltop.c | 230 | ||||
-rw-r--r-- | drivers/hid/hid-wiimote-core.c | 16 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 1 |
10 files changed, 453 insertions, 148 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 80175c37a6a5..e9c68fedfcff 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -32,9 +32,13 @@ config HID | |||
32 | If unsure, say Y. | 32 | If unsure, say Y. |
33 | 33 | ||
34 | config HID_BATTERY_STRENGTH | 34 | config HID_BATTERY_STRENGTH |
35 | bool | 35 | bool "Battery level reporting for HID devices" |
36 | depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY | 36 | depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY |
37 | default n | 37 | default n |
38 | ---help--- | ||
39 | This option adds support of reporting battery strength (for HID devices | ||
40 | that support this feature) through power_supply class so that userspace | ||
41 | tools, such as upower, can display it. | ||
38 | 42 | ||
39 | config HIDRAW | 43 | config HIDRAW |
40 | bool "/dev/hidraw raw HID device support" | 44 | bool "/dev/hidraw raw HID device support" |
@@ -613,16 +617,10 @@ config THRUSTMASTER_FF | |||
613 | config HID_WACOM | 617 | config HID_WACOM |
614 | tristate "Wacom Bluetooth devices support" | 618 | tristate "Wacom Bluetooth devices support" |
615 | depends on BT_HIDP | 619 | depends on BT_HIDP |
616 | ---help--- | 620 | depends on LEDS_CLASS |
617 | Support for Wacom Graphire Bluetooth tablet. | ||
618 | |||
619 | config HID_WACOM_POWER_SUPPLY | ||
620 | bool "Wacom Bluetooth devices power supply status support" | ||
621 | depends on HID_WACOM | ||
622 | select POWER_SUPPLY | 621 | select POWER_SUPPLY |
623 | ---help--- | 622 | ---help--- |
624 | Say Y here if you want to enable power supply status monitoring for | 623 | Support for Wacom Graphire Bluetooth and Intuos4 WL tablets. |
625 | Wacom Bluetooth devices. | ||
626 | 624 | ||
627 | config HID_WIIMOTE | 625 | config HID_WIIMOTE |
628 | tristate "Nintendo Wii Remote support" | 626 | tristate "Nintendo Wii Remote support" |
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 7a79e39efc7e..fa10f847f7db 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c | |||
@@ -458,6 +458,9 @@ static const struct hid_device_id apple_devices[] = { | |||
458 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO), | 458 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO), |
459 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | | 459 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
460 | APPLE_ISO_KEYBOARD }, | 460 | APPLE_ISO_KEYBOARD }, |
461 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | ||
462 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), | ||
463 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | ||
461 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), | 464 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), |
462 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 465 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
463 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), | 466 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 9831a2ccae3d..8e3a6b261477 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1511,7 +1511,6 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1511 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1511 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
1512 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, | 1512 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, |
1513 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, | 1513 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, |
1514 | { HID_USB_DEVICE(USB_VENDOR_ID_BAANTO, USB_DEVICE_ID_BAANTO_MT_190W2), }, | ||
1515 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, | 1514 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, |
1516 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, | 1515 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, |
1517 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, | 1516 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, |
@@ -1660,6 +1659,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1660 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_PID_0038) }, | 1659 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_PID_0038) }, |
1661 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, | 1660 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, |
1662 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) }, | 1661 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) }, |
1662 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET) }, | ||
1663 | { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) }, | 1663 | { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) }, |
1664 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, | 1664 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, |
1665 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, | 1665 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 4ff994166c04..9373f535dfe9 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -756,6 +756,7 @@ | |||
756 | #define USB_DEVICE_ID_WALTOP_PID_0038 0x0038 | 756 | #define USB_DEVICE_ID_WALTOP_PID_0038 0x0038 |
757 | #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH 0x0501 | 757 | #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH 0x0501 |
758 | #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH 0x0500 | 758 | #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH 0x0500 |
759 | #define USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET 0x0502 | ||
759 | 760 | ||
760 | #define USB_VENDOR_ID_WISEGROUP 0x0925 | 761 | #define USB_VENDOR_ID_WISEGROUP 0x0925 |
761 | #define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 | 762 | #define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 7b43186b022c..132b0019365e 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -225,7 +225,10 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | |||
225 | * Verify and convert units. | 225 | * Verify and convert units. |
226 | * See HID specification v1.11 6.2.2.7 Global Items for unit decoding | 226 | * See HID specification v1.11 6.2.2.7 Global Items for unit decoding |
227 | */ | 227 | */ |
228 | if (code == ABS_X || code == ABS_Y || code == ABS_Z) { | 228 | switch (code) { |
229 | case ABS_X: | ||
230 | case ABS_Y: | ||
231 | case ABS_Z: | ||
229 | if (field->unit == 0x11) { /* If centimeters */ | 232 | if (field->unit == 0x11) { /* If centimeters */ |
230 | /* Convert to millimeters */ | 233 | /* Convert to millimeters */ |
231 | unit_exponent += 1; | 234 | unit_exponent += 1; |
@@ -239,7 +242,13 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | |||
239 | } else { | 242 | } else { |
240 | return 0; | 243 | return 0; |
241 | } | 244 | } |
242 | } else if (code == ABS_RX || code == ABS_RY || code == ABS_RZ) { | 245 | break; |
246 | |||
247 | case ABS_RX: | ||
248 | case ABS_RY: | ||
249 | case ABS_RZ: | ||
250 | case ABS_TILT_X: | ||
251 | case ABS_TILT_Y: | ||
243 | if (field->unit == 0x14) { /* If degrees */ | 252 | if (field->unit == 0x14) { /* If degrees */ |
244 | /* Convert to radians */ | 253 | /* Convert to radians */ |
245 | prev = logical_extents; | 254 | prev = logical_extents; |
@@ -250,7 +259,9 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | |||
250 | } else if (field->unit != 0x12) { /* If not radians */ | 259 | } else if (field->unit != 0x12) { /* If not radians */ |
251 | return 0; | 260 | return 0; |
252 | } | 261 | } |
253 | } else { | 262 | break; |
263 | |||
264 | default: | ||
254 | return 0; | 265 | return 0; |
255 | } | 266 | } |
256 | 267 | ||
@@ -623,6 +634,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
623 | map_key_clear(BTN_TOOL_RUBBER); | 634 | map_key_clear(BTN_TOOL_RUBBER); |
624 | break; | 635 | break; |
625 | 636 | ||
637 | case 0x3d: /* X Tilt */ | ||
638 | map_abs_clear(ABS_TILT_X); | ||
639 | break; | ||
640 | |||
641 | case 0x3e: /* Y Tilt */ | ||
642 | map_abs_clear(ABS_TILT_Y); | ||
643 | break; | ||
644 | |||
626 | case 0x33: /* Touch */ | 645 | case 0x33: /* Touch */ |
627 | case 0x42: /* TipSwitch */ | 646 | case 0x42: /* TipSwitch */ |
628 | case 0x43: /* TipSwitch2 */ | 647 | case 0x43: /* TipSwitch2 */ |
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index e1c38bba4375..5e8a7ed42344 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/hid.h> | 26 | #include <linux/hid.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/usb.h> | 28 | #include <linux/usb.h> |
29 | #include <asm/unaligned.h> | ||
29 | #include "usbhid/usbhid.h" | 30 | #include "usbhid/usbhid.h" |
30 | #include "hid-ids.h" | 31 | #include "hid-ids.h" |
31 | #include "hid-logitech-dj.h" | 32 | #include "hid-logitech-dj.h" |
@@ -273,8 +274,8 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, | |||
273 | goto dj_device_allocate_fail; | 274 | goto dj_device_allocate_fail; |
274 | } | 275 | } |
275 | 276 | ||
276 | dj_dev->reports_supported = le32_to_cpu( | 277 | dj_dev->reports_supported = get_unaligned_le32( |
277 | dj_report->report_params[DEVICE_PAIRED_RF_REPORT_TYPE]); | 278 | dj_report->report_params + DEVICE_PAIRED_RF_REPORT_TYPE); |
278 | dj_dev->hdev = dj_hiddev; | 279 | dj_dev->hdev = dj_hiddev; |
279 | dj_dev->dj_receiver_dev = djrcv_dev; | 280 | dj_dev->dj_receiver_dev = djrcv_dev; |
280 | dj_dev->device_index = dj_report->device_index; | 281 | dj_dev->device_index = dj_report->device_index; |
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index 067e2963314c..fe23a1eb586b 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c | |||
@@ -24,15 +24,16 @@ | |||
24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
25 | #include <linux/hid.h> | 25 | #include <linux/hid.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/leds.h> | ||
27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
28 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | ||
29 | #include <linux/power_supply.h> | 29 | #include <linux/power_supply.h> |
30 | #endif | ||
31 | 30 | ||
32 | #include "hid-ids.h" | 31 | #include "hid-ids.h" |
33 | 32 | ||
34 | #define PAD_DEVICE_ID 0x0F | 33 | #define PAD_DEVICE_ID 0x0F |
35 | 34 | ||
35 | #define WAC_CMD_LED_CONTROL 0x20 | ||
36 | |||
36 | struct wacom_data { | 37 | struct wacom_data { |
37 | __u16 tool; | 38 | __u16 tool; |
38 | __u16 butstate; | 39 | __u16 butstate; |
@@ -41,16 +42,20 @@ struct wacom_data { | |||
41 | __u32 id; | 42 | __u32 id; |
42 | __u32 serial; | 43 | __u32 serial; |
43 | unsigned char high_speed; | 44 | unsigned char high_speed; |
44 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | 45 | __u8 battery_capacity; |
45 | int battery_capacity; | 46 | __u8 power_raw; |
47 | __u8 ps_connected; | ||
46 | struct power_supply battery; | 48 | struct power_supply battery; |
47 | struct power_supply ac; | 49 | struct power_supply ac; |
48 | #endif | 50 | __u8 led_selector; |
51 | struct led_classdev *leds[4]; | ||
49 | }; | 52 | }; |
50 | 53 | ||
51 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | 54 | /*percent of battery capacity for Graphire |
52 | /*percent of battery capacity, 0 means AC online*/ | 55 | 8th value means AC online and show 100% capacity */ |
53 | static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 }; | 56 | static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 }; |
57 | /*percent of battery capacity for Intuos4 WL, AC has a separate bit*/ | ||
58 | static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; | ||
54 | 59 | ||
55 | static enum power_supply_property wacom_battery_props[] = { | 60 | static enum power_supply_property wacom_battery_props[] = { |
56 | POWER_SUPPLY_PROP_PRESENT, | 61 | POWER_SUPPLY_PROP_PRESENT, |
@@ -64,13 +69,123 @@ static enum power_supply_property wacom_ac_props[] = { | |||
64 | POWER_SUPPLY_PROP_SCOPE, | 69 | POWER_SUPPLY_PROP_SCOPE, |
65 | }; | 70 | }; |
66 | 71 | ||
72 | static void wacom_leds_set_brightness(struct led_classdev *led_dev, | ||
73 | enum led_brightness value) | ||
74 | { | ||
75 | struct device *dev = led_dev->dev->parent; | ||
76 | struct hid_device *hdev; | ||
77 | struct wacom_data *wdata; | ||
78 | unsigned char *buf; | ||
79 | __u8 led = 0; | ||
80 | int i; | ||
81 | |||
82 | hdev = container_of(dev, struct hid_device, dev); | ||
83 | wdata = hid_get_drvdata(hdev); | ||
84 | for (i = 0; i < 4; ++i) { | ||
85 | if (wdata->leds[i] == led_dev) | ||
86 | wdata->led_selector = i; | ||
87 | } | ||
88 | |||
89 | led = wdata->led_selector | 0x04; | ||
90 | buf = kzalloc(9, GFP_KERNEL); | ||
91 | if (buf) { | ||
92 | buf[0] = WAC_CMD_LED_CONTROL; | ||
93 | buf[1] = led; | ||
94 | buf[2] = value; | ||
95 | hdev->hid_output_raw_report(hdev, buf, 9, HID_FEATURE_REPORT); | ||
96 | kfree(buf); | ||
97 | } | ||
98 | |||
99 | return; | ||
100 | } | ||
101 | |||
102 | static enum led_brightness wacom_leds_get_brightness(struct led_classdev *led_dev) | ||
103 | { | ||
104 | struct wacom_data *wdata; | ||
105 | struct device *dev = led_dev->dev->parent; | ||
106 | int value = 0; | ||
107 | int i; | ||
108 | |||
109 | wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev)); | ||
110 | |||
111 | for (i = 0; i < 4; ++i) { | ||
112 | if (wdata->leds[i] == led_dev) { | ||
113 | value = wdata->leds[i]->brightness; | ||
114 | break; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | return value; | ||
119 | } | ||
120 | |||
121 | |||
122 | static int wacom_initialize_leds(struct hid_device *hdev) | ||
123 | { | ||
124 | struct wacom_data *wdata = hid_get_drvdata(hdev); | ||
125 | struct led_classdev *led; | ||
126 | struct device *dev = &hdev->dev; | ||
127 | size_t namesz = strlen(dev_name(dev)) + 12; | ||
128 | char *name; | ||
129 | int i, ret; | ||
130 | |||
131 | wdata->led_selector = 0; | ||
132 | |||
133 | for (i = 0; i < 4; i++) { | ||
134 | led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL); | ||
135 | if (!led) { | ||
136 | hid_warn(hdev, | ||
137 | "can't allocate memory for LED selector\n"); | ||
138 | ret = -ENOMEM; | ||
139 | goto err; | ||
140 | } | ||
141 | |||
142 | name = (void *)&led[1]; | ||
143 | snprintf(name, namesz, "%s:selector:%d", dev_name(dev), i); | ||
144 | led->name = name; | ||
145 | led->brightness = 0; | ||
146 | led->max_brightness = 127; | ||
147 | led->brightness_get = wacom_leds_get_brightness; | ||
148 | led->brightness_set = wacom_leds_set_brightness; | ||
149 | |||
150 | wdata->leds[i] = led; | ||
151 | |||
152 | ret = led_classdev_register(dev, wdata->leds[i]); | ||
153 | |||
154 | if (ret) { | ||
155 | wdata->leds[i] = NULL; | ||
156 | kfree(led); | ||
157 | hid_warn(hdev, "can't register LED\n"); | ||
158 | goto err; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | err: | ||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | static void wacom_destroy_leds(struct hid_device *hdev) | ||
167 | { | ||
168 | struct wacom_data *wdata = hid_get_drvdata(hdev); | ||
169 | struct led_classdev *led; | ||
170 | int i; | ||
171 | |||
172 | for (i = 0; i < 4; ++i) { | ||
173 | if (wdata->leds[i]) { | ||
174 | led = wdata->leds[i]; | ||
175 | wdata->leds[i] = NULL; | ||
176 | led_classdev_unregister(led); | ||
177 | kfree(led); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | } | ||
182 | |||
67 | static int wacom_battery_get_property(struct power_supply *psy, | 183 | static int wacom_battery_get_property(struct power_supply *psy, |
68 | enum power_supply_property psp, | 184 | enum power_supply_property psp, |
69 | union power_supply_propval *val) | 185 | union power_supply_propval *val) |
70 | { | 186 | { |
71 | struct wacom_data *wdata = container_of(psy, | 187 | struct wacom_data *wdata = container_of(psy, |
72 | struct wacom_data, battery); | 188 | struct wacom_data, battery); |
73 | int power_state = batcap[wdata->battery_capacity]; | ||
74 | int ret = 0; | 189 | int ret = 0; |
75 | 190 | ||
76 | switch (psp) { | 191 | switch (psp) { |
@@ -81,11 +196,7 @@ static int wacom_battery_get_property(struct power_supply *psy, | |||
81 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | 196 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; |
82 | break; | 197 | break; |
83 | case POWER_SUPPLY_PROP_CAPACITY: | 198 | case POWER_SUPPLY_PROP_CAPACITY: |
84 | /* show 100% battery capacity when charging */ | 199 | val->intval = wdata->battery_capacity; |
85 | if (power_state == 0) | ||
86 | val->intval = 100; | ||
87 | else | ||
88 | val->intval = power_state; | ||
89 | break; | 200 | break; |
90 | default: | 201 | default: |
91 | ret = -EINVAL; | 202 | ret = -EINVAL; |
@@ -99,17 +210,13 @@ static int wacom_ac_get_property(struct power_supply *psy, | |||
99 | union power_supply_propval *val) | 210 | union power_supply_propval *val) |
100 | { | 211 | { |
101 | struct wacom_data *wdata = container_of(psy, struct wacom_data, ac); | 212 | struct wacom_data *wdata = container_of(psy, struct wacom_data, ac); |
102 | int power_state = batcap[wdata->battery_capacity]; | ||
103 | int ret = 0; | 213 | int ret = 0; |
104 | 214 | ||
105 | switch (psp) { | 215 | switch (psp) { |
106 | case POWER_SUPPLY_PROP_PRESENT: | 216 | case POWER_SUPPLY_PROP_PRESENT: |
107 | /* fall through */ | 217 | /* fall through */ |
108 | case POWER_SUPPLY_PROP_ONLINE: | 218 | case POWER_SUPPLY_PROP_ONLINE: |
109 | if (power_state == 0) | 219 | val->intval = wdata->ps_connected; |
110 | val->intval = 1; | ||
111 | else | ||
112 | val->intval = 0; | ||
113 | break; | 220 | break; |
114 | case POWER_SUPPLY_PROP_SCOPE: | 221 | case POWER_SUPPLY_PROP_SCOPE: |
115 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | 222 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; |
@@ -120,41 +227,16 @@ static int wacom_ac_get_property(struct power_supply *psy, | |||
120 | } | 227 | } |
121 | return ret; | 228 | return ret; |
122 | } | 229 | } |
123 | #endif | ||
124 | |||
125 | static void wacom_set_features(struct hid_device *hdev) | ||
126 | { | ||
127 | int ret; | ||
128 | __u8 rep_data[2]; | ||
129 | |||
130 | /*set high speed, tablet mode*/ | ||
131 | rep_data[0] = 0x03; | ||
132 | rep_data[1] = 0x20; | ||
133 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, | ||
134 | HID_FEATURE_REPORT); | ||
135 | return; | ||
136 | } | ||
137 | 230 | ||
138 | static void wacom_poke(struct hid_device *hdev, u8 speed) | 231 | static void wacom_set_features(struct hid_device *hdev, u8 speed) |
139 | { | 232 | { |
140 | struct wacom_data *wdata = hid_get_drvdata(hdev); | 233 | struct wacom_data *wdata = hid_get_drvdata(hdev); |
141 | int limit, ret; | 234 | int limit, ret; |
142 | char rep_data[2]; | 235 | __u8 rep_data[2]; |
143 | |||
144 | rep_data[0] = 0x03 ; rep_data[1] = 0x00; | ||
145 | limit = 3; | ||
146 | do { | ||
147 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, | ||
148 | HID_FEATURE_REPORT); | ||
149 | } while (ret < 0 && limit-- > 0); | ||
150 | |||
151 | if (ret >= 0) { | ||
152 | if (speed == 0) | ||
153 | rep_data[0] = 0x05; | ||
154 | else | ||
155 | rep_data[0] = 0x06; | ||
156 | 236 | ||
157 | rep_data[1] = 0x00; | 237 | switch (hdev->product) { |
238 | case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: | ||
239 | rep_data[0] = 0x03 ; rep_data[1] = 0x00; | ||
158 | limit = 3; | 240 | limit = 3; |
159 | do { | 241 | do { |
160 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, | 242 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, |
@@ -162,17 +244,47 @@ static void wacom_poke(struct hid_device *hdev, u8 speed) | |||
162 | } while (ret < 0 && limit-- > 0); | 244 | } while (ret < 0 && limit-- > 0); |
163 | 245 | ||
164 | if (ret >= 0) { | 246 | if (ret >= 0) { |
165 | wdata->high_speed = speed; | 247 | if (speed == 0) |
166 | return; | 248 | rep_data[0] = 0x05; |
249 | else | ||
250 | rep_data[0] = 0x06; | ||
251 | |||
252 | rep_data[1] = 0x00; | ||
253 | limit = 3; | ||
254 | do { | ||
255 | ret = hdev->hid_output_raw_report(hdev, | ||
256 | rep_data, 2, HID_FEATURE_REPORT); | ||
257 | } while (ret < 0 && limit-- > 0); | ||
258 | |||
259 | if (ret >= 0) { | ||
260 | wdata->high_speed = speed; | ||
261 | return; | ||
262 | } | ||
167 | } | 263 | } |
264 | |||
265 | /* | ||
266 | * Note that if the raw queries fail, it's not a hard failure | ||
267 | * and it is safe to continue | ||
268 | */ | ||
269 | hid_warn(hdev, "failed to poke device, command %d, err %d\n", | ||
270 | rep_data[0], ret); | ||
271 | break; | ||
272 | case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: | ||
273 | if (speed == 1) | ||
274 | wdata->features &= ~0x20; | ||
275 | else | ||
276 | wdata->features |= 0x20; | ||
277 | |||
278 | rep_data[0] = 0x03; | ||
279 | rep_data[1] = wdata->features; | ||
280 | |||
281 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, | ||
282 | HID_FEATURE_REPORT); | ||
283 | if (ret >= 0) | ||
284 | wdata->high_speed = speed; | ||
285 | break; | ||
168 | } | 286 | } |
169 | 287 | ||
170 | /* | ||
171 | * Note that if the raw queries fail, it's not a hard failure and it | ||
172 | * is safe to continue | ||
173 | */ | ||
174 | hid_warn(hdev, "failed to poke device, command %d, err %d\n", | ||
175 | rep_data[0], ret); | ||
176 | return; | 288 | return; |
177 | } | 289 | } |
178 | 290 | ||
@@ -196,7 +308,7 @@ static ssize_t wacom_store_speed(struct device *dev, | |||
196 | return -EINVAL; | 308 | return -EINVAL; |
197 | 309 | ||
198 | if (new_speed == 0 || new_speed == 1) { | 310 | if (new_speed == 0 || new_speed == 1) { |
199 | wacom_poke(hdev, new_speed); | 311 | wacom_set_features(hdev, new_speed); |
200 | return strnlen(buf, PAGE_SIZE); | 312 | return strnlen(buf, PAGE_SIZE); |
201 | } else | 313 | } else |
202 | return -EINVAL; | 314 | return -EINVAL; |
@@ -310,12 +422,16 @@ static int wacom_gr_parse_report(struct hid_device *hdev, | |||
310 | input_sync(input); | 422 | input_sync(input); |
311 | } | 423 | } |
312 | 424 | ||
313 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | 425 | /* Store current battery capacity and power supply state*/ |
314 | /* Store current battery capacity */ | ||
315 | rw = (data[7] >> 2 & 0x07); | 426 | rw = (data[7] >> 2 & 0x07); |
316 | if (rw != wdata->battery_capacity) | 427 | if (rw != wdata->power_raw) { |
317 | wdata->battery_capacity = rw; | 428 | wdata->power_raw = rw; |
318 | #endif | 429 | wdata->battery_capacity = batcap_gr[rw]; |
430 | if (rw == 7) | ||
431 | wdata->ps_connected = 1; | ||
432 | else | ||
433 | wdata->ps_connected = 0; | ||
434 | } | ||
319 | return 1; | 435 | return 1; |
320 | } | 436 | } |
321 | 437 | ||
@@ -369,6 +485,7 @@ static void wacom_i4_parse_pen_report(struct wacom_data *wdata, | |||
369 | { | 485 | { |
370 | __u16 x, y, pressure; | 486 | __u16 x, y, pressure; |
371 | __u8 distance; | 487 | __u8 distance; |
488 | __u8 tilt_x, tilt_y; | ||
372 | 489 | ||
373 | switch (data[1]) { | 490 | switch (data[1]) { |
374 | case 0x80: /* Out of proximity report */ | 491 | case 0x80: /* Out of proximity report */ |
@@ -405,6 +522,8 @@ static void wacom_i4_parse_pen_report(struct wacom_data *wdata, | |||
405 | pressure = (data[6] << 3) | ((data[7] & 0xC0) >> 5) | 522 | pressure = (data[6] << 3) | ((data[7] & 0xC0) >> 5) |
406 | | (data[1] & 0x01); | 523 | | (data[1] & 0x01); |
407 | distance = (data[9] >> 2) & 0x3f; | 524 | distance = (data[9] >> 2) & 0x3f; |
525 | tilt_x = ((data[7] << 1) & 0x7e) | (data[8] >> 7); | ||
526 | tilt_y = data[8] & 0x7f; | ||
408 | 527 | ||
409 | input_report_key(input, BTN_TOUCH, pressure > 1); | 528 | input_report_key(input, BTN_TOUCH, pressure > 1); |
410 | 529 | ||
@@ -415,6 +534,8 @@ static void wacom_i4_parse_pen_report(struct wacom_data *wdata, | |||
415 | input_report_abs(input, ABS_Y, y); | 534 | input_report_abs(input, ABS_Y, y); |
416 | input_report_abs(input, ABS_PRESSURE, pressure); | 535 | input_report_abs(input, ABS_PRESSURE, pressure); |
417 | input_report_abs(input, ABS_DISTANCE, distance); | 536 | input_report_abs(input, ABS_DISTANCE, distance); |
537 | input_report_abs(input, ABS_TILT_X, tilt_x); | ||
538 | input_report_abs(input, ABS_TILT_Y, tilt_y); | ||
418 | input_report_abs(input, ABS_MISC, wdata->id); | 539 | input_report_abs(input, ABS_MISC, wdata->id); |
419 | input_event(input, EV_MSC, MSC_SERIAL, wdata->serial); | 540 | input_event(input, EV_MSC, MSC_SERIAL, wdata->serial); |
420 | input_report_key(input, wdata->tool, 1); | 541 | input_report_key(input, wdata->tool, 1); |
@@ -455,6 +576,7 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
455 | struct input_dev *input; | 576 | struct input_dev *input; |
456 | unsigned char *data = (unsigned char *) raw_data; | 577 | unsigned char *data = (unsigned char *) raw_data; |
457 | int i; | 578 | int i; |
579 | __u8 power_raw; | ||
458 | 580 | ||
459 | if (!(hdev->claimed & HID_CLAIMED_INPUT)) | 581 | if (!(hdev->claimed & HID_CLAIMED_INPUT)) |
460 | return 0; | 582 | return 0; |
@@ -462,13 +584,15 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
462 | hidinput = list_entry(hdev->inputs.next, struct hid_input, list); | 584 | hidinput = list_entry(hdev->inputs.next, struct hid_input, list); |
463 | input = hidinput->input; | 585 | input = hidinput->input; |
464 | 586 | ||
465 | /* Check if this is a tablet report */ | ||
466 | if (data[0] != 0x03) | ||
467 | return 0; | ||
468 | |||
469 | switch (hdev->product) { | 587 | switch (hdev->product) { |
470 | case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: | 588 | case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: |
471 | return wacom_gr_parse_report(hdev, wdata, input, data); | 589 | if (data[0] == 0x03) { |
590 | return wacom_gr_parse_report(hdev, wdata, input, data); | ||
591 | } else { | ||
592 | hid_err(hdev, "Unknown report: %d,%d size:%d\n", | ||
593 | data[0], data[1], size); | ||
594 | return 0; | ||
595 | } | ||
472 | break; | 596 | break; |
473 | case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: | 597 | case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: |
474 | i = 1; | 598 | i = 1; |
@@ -482,6 +606,13 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
482 | wacom_i4_parse_report(hdev, wdata, input, data + i); | 606 | wacom_i4_parse_report(hdev, wdata, input, data + i); |
483 | i += 10; | 607 | i += 10; |
484 | wacom_i4_parse_report(hdev, wdata, input, data + i); | 608 | wacom_i4_parse_report(hdev, wdata, input, data + i); |
609 | power_raw = data[i+10]; | ||
610 | if (power_raw != wdata->power_raw) { | ||
611 | wdata->power_raw = power_raw; | ||
612 | wdata->battery_capacity = batcap_i4[power_raw & 0x07]; | ||
613 | wdata->ps_connected = power_raw & 0x08; | ||
614 | } | ||
615 | |||
485 | break; | 616 | break; |
486 | default: | 617 | default: |
487 | hid_err(hdev, "Unknown report: %d,%d size:%d\n", | 618 | hid_err(hdev, "Unknown report: %d,%d size:%d\n", |
@@ -546,6 +677,8 @@ static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
546 | input_set_abs_params(input, ABS_Y, 0, 25400, 4, 0); | 677 | input_set_abs_params(input, ABS_Y, 0, 25400, 4, 0); |
547 | input_set_abs_params(input, ABS_PRESSURE, 0, 2047, 0, 0); | 678 | input_set_abs_params(input, ABS_PRESSURE, 0, 2047, 0, 0); |
548 | input_set_abs_params(input, ABS_DISTANCE, 0, 63, 0, 0); | 679 | input_set_abs_params(input, ABS_DISTANCE, 0, 63, 0, 0); |
680 | input_set_abs_params(input, ABS_TILT_X, 0, 127, 0, 0); | ||
681 | input_set_abs_params(input, ABS_TILT_Y, 0, 127, 0, 0); | ||
549 | break; | 682 | break; |
550 | } | 683 | } |
551 | 684 | ||
@@ -584,19 +717,19 @@ static int wacom_probe(struct hid_device *hdev, | |||
584 | hid_warn(hdev, | 717 | hid_warn(hdev, |
585 | "can't create sysfs speed attribute err: %d\n", ret); | 718 | "can't create sysfs speed attribute err: %d\n", ret); |
586 | 719 | ||
587 | switch (hdev->product) { | 720 | wdata->features = 0; |
588 | case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: | 721 | wacom_set_features(hdev, 1); |
589 | /* Set Wacom mode 2 with high reporting speed */ | 722 | |
590 | wacom_poke(hdev, 1); | 723 | if (hdev->product == USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) { |
591 | break; | ||
592 | case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: | ||
593 | sprintf(hdev->name, "%s", "Wacom Intuos4 WL"); | 724 | sprintf(hdev->name, "%s", "Wacom Intuos4 WL"); |
594 | wdata->features = 0; | 725 | ret = wacom_initialize_leds(hdev); |
595 | wacom_set_features(hdev); | 726 | if (ret) { |
596 | break; | 727 | hid_warn(hdev, |
728 | "can't create led attribute, err: %d\n", ret); | ||
729 | goto destroy_leds; | ||
730 | } | ||
597 | } | 731 | } |
598 | 732 | ||
599 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | ||
600 | wdata->battery.properties = wacom_battery_props; | 733 | wdata->battery.properties = wacom_battery_props; |
601 | wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props); | 734 | wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props); |
602 | wdata->battery.get_property = wacom_battery_get_property; | 735 | wdata->battery.get_property = wacom_battery_get_property; |
@@ -629,16 +762,15 @@ static int wacom_probe(struct hid_device *hdev, | |||
629 | } | 762 | } |
630 | 763 | ||
631 | power_supply_powers(&wdata->ac, &hdev->dev); | 764 | power_supply_powers(&wdata->ac, &hdev->dev); |
632 | #endif | ||
633 | return 0; | 765 | return 0; |
634 | 766 | ||
635 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | ||
636 | err_ac: | 767 | err_ac: |
637 | power_supply_unregister(&wdata->battery); | 768 | power_supply_unregister(&wdata->battery); |
638 | err_battery: | 769 | err_battery: |
639 | device_remove_file(&hdev->dev, &dev_attr_speed); | 770 | device_remove_file(&hdev->dev, &dev_attr_speed); |
640 | hid_hw_stop(hdev); | 771 | hid_hw_stop(hdev); |
641 | #endif | 772 | destroy_leds: |
773 | wacom_destroy_leds(hdev); | ||
642 | err_free: | 774 | err_free: |
643 | kfree(wdata); | 775 | kfree(wdata); |
644 | return ret; | 776 | return ret; |
@@ -646,16 +778,14 @@ err_free: | |||
646 | 778 | ||
647 | static void wacom_remove(struct hid_device *hdev) | 779 | static void wacom_remove(struct hid_device *hdev) |
648 | { | 780 | { |
649 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | ||
650 | struct wacom_data *wdata = hid_get_drvdata(hdev); | 781 | struct wacom_data *wdata = hid_get_drvdata(hdev); |
651 | #endif | 782 | |
783 | wacom_destroy_leds(hdev); | ||
652 | device_remove_file(&hdev->dev, &dev_attr_speed); | 784 | device_remove_file(&hdev->dev, &dev_attr_speed); |
653 | hid_hw_stop(hdev); | 785 | hid_hw_stop(hdev); |
654 | 786 | ||
655 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | ||
656 | power_supply_unregister(&wdata->battery); | 787 | power_supply_unregister(&wdata->battery); |
657 | power_supply_unregister(&wdata->ac); | 788 | power_supply_unregister(&wdata->ac); |
658 | #endif | ||
659 | kfree(hid_get_drvdata(hdev)); | 789 | kfree(hid_get_drvdata(hdev)); |
660 | } | 790 | } |
661 | 791 | ||
@@ -693,5 +823,5 @@ static void __exit wacom_exit(void) | |||
693 | 823 | ||
694 | module_init(wacom_init); | 824 | module_init(wacom_init); |
695 | module_exit(wacom_exit); | 825 | module_exit(wacom_exit); |
826 | MODULE_DESCRIPTION("Driver for Wacom Graphire Bluetooth and Wacom Intuos4 WL"); | ||
696 | MODULE_LICENSE("GPL"); | 827 | MODULE_LICENSE("GPL"); |
697 | |||
diff --git a/drivers/hid/hid-waltop.c b/drivers/hid/hid-waltop.c index 2cfd95c4467b..745e4e9a8cf2 100644 --- a/drivers/hid/hid-waltop.c +++ b/drivers/hid/hid-waltop.c | |||
@@ -502,28 +502,146 @@ static __u8 media_tablet_14_1_inch_rdesc_fixed[] = { | |||
502 | 0xC0 /* End Collection */ | 502 | 0xC0 /* End Collection */ |
503 | }; | 503 | }; |
504 | 504 | ||
505 | struct waltop_state { | 505 | /* |
506 | u8 pressure0; | 506 | * See Sirius Battery Free Tablet description, device and HID report descriptors |
507 | u8 pressure1; | 507 | * at |
508 | * http://sf.net/apps/mediawiki/digimend/?title=Waltop_Sirius_Battery_Free_Tablet | ||
509 | */ | ||
510 | |||
511 | /* Size of the original report descriptor of Sirius Battery Free Tablet */ | ||
512 | #define SIRIUS_BATTERY_FREE_TABLET_RDESC_ORIG_SIZE 335 | ||
513 | |||
514 | /* Fixed Sirius Battery Free Tablet descriptor */ | ||
515 | static __u8 sirius_battery_free_tablet_rdesc_fixed[] = { | ||
516 | 0x05, 0x0D, /* Usage Page (Digitizer), */ | ||
517 | 0x09, 0x02, /* Usage (Pen), */ | ||
518 | 0xA1, 0x01, /* Collection (Application), */ | ||
519 | 0x85, 0x10, /* Report ID (16), */ | ||
520 | 0x09, 0x20, /* Usage (Stylus), */ | ||
521 | 0xA0, /* Collection (Physical), */ | ||
522 | 0x95, 0x01, /* Report Count (1), */ | ||
523 | 0x15, 0x01, /* Logical Minimum (1), */ | ||
524 | 0x25, 0x03, /* Logical Maximum (3), */ | ||
525 | 0x75, 0x02, /* Report Size (2), */ | ||
526 | 0x09, 0x42, /* Usage (Tip Switch), */ | ||
527 | 0x09, 0x44, /* Usage (Barrel Switch), */ | ||
528 | 0x09, 0x46, /* Usage (Tablet Pick), */ | ||
529 | 0x80, /* Input, */ | ||
530 | 0x14, /* Logical Minimum (0), */ | ||
531 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
532 | 0x75, 0x01, /* Report Size (1), */ | ||
533 | 0x09, 0x3C, /* Usage (Invert), */ | ||
534 | 0x81, 0x02, /* Input (Variable), */ | ||
535 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
536 | 0x09, 0x32, /* Usage (In Range), */ | ||
537 | 0x81, 0x02, /* Input (Variable), */ | ||
538 | 0x95, 0x03, /* Report Count (3), */ | ||
539 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
540 | 0xA4, /* Push, */ | ||
541 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
542 | 0x55, 0xFD, /* Unit Exponent (-3), */ | ||
543 | 0x65, 0x13, /* Unit (Inch), */ | ||
544 | 0x34, /* Physical Minimum (0), */ | ||
545 | 0x14, /* Logical Minimum (0), */ | ||
546 | 0x75, 0x10, /* Report Size (16), */ | ||
547 | 0x95, 0x01, /* Report Count (1), */ | ||
548 | 0x46, 0x10, 0x27, /* Physical Maximum (10000), */ | ||
549 | 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */ | ||
550 | 0x09, 0x30, /* Usage (X), */ | ||
551 | 0x81, 0x02, /* Input (Variable), */ | ||
552 | 0x46, 0x70, 0x17, /* Physical Maximum (6000), */ | ||
553 | 0x26, 0xE0, 0x2E, /* Logical Maximum (12000), */ | ||
554 | 0x09, 0x31, /* Usage (Y), */ | ||
555 | 0x81, 0x02, /* Input (Variable), */ | ||
556 | 0xB4, /* Pop, */ | ||
557 | 0x75, 0x10, /* Report Size (16), */ | ||
558 | 0x95, 0x01, /* Report Count (1), */ | ||
559 | 0x14, /* Logical Minimum (0), */ | ||
560 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
561 | 0x09, 0x30, /* Usage (Tip Pressure), */ | ||
562 | 0x81, 0x02, /* Input (Variable), */ | ||
563 | 0xA4, /* Push, */ | ||
564 | 0x55, 0xFE, /* Unit Exponent (-2), */ | ||
565 | 0x65, 0x12, /* Unit (Radians), */ | ||
566 | 0x35, 0x97, /* Physical Minimum (-105), */ | ||
567 | 0x45, 0x69, /* Physical Maximum (105), */ | ||
568 | 0x15, 0x97, /* Logical Minimum (-105), */ | ||
569 | 0x25, 0x69, /* Logical Maximum (105), */ | ||
570 | 0x75, 0x08, /* Report Size (8), */ | ||
571 | 0x95, 0x02, /* Report Count (2), */ | ||
572 | 0x09, 0x3D, /* Usage (X Tilt), */ | ||
573 | 0x09, 0x3E, /* Usage (Y Tilt), */ | ||
574 | 0x81, 0x02, /* Input (Variable), */ | ||
575 | 0xB4, /* Pop, */ | ||
576 | 0xC0, /* End Collection, */ | ||
577 | 0xC0, /* End Collection, */ | ||
578 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
579 | 0x09, 0x02, /* Usage (Mouse), */ | ||
580 | 0xA1, 0x01, /* Collection (Application), */ | ||
581 | 0x85, 0x01, /* Report ID (1), */ | ||
582 | 0x09, 0x01, /* Usage (Pointer), */ | ||
583 | 0xA0, /* Collection (Physical), */ | ||
584 | 0x75, 0x08, /* Report Size (8), */ | ||
585 | 0x95, 0x03, /* Report Count (3), */ | ||
586 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
587 | 0x09, 0x38, /* Usage (Wheel), */ | ||
588 | 0x15, 0xFF, /* Logical Minimum (-1), */ | ||
589 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
590 | 0x75, 0x08, /* Report Size (8), */ | ||
591 | 0x95, 0x01, /* Report Count (1), */ | ||
592 | 0x81, 0x06, /* Input (Variable, Relative), */ | ||
593 | 0x75, 0x08, /* Report Size (8), */ | ||
594 | 0x95, 0x03, /* Report Count (3), */ | ||
595 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
596 | 0xC0, /* End Collection, */ | ||
597 | 0xC0, /* End Collection, */ | ||
598 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
599 | 0x09, 0x06, /* Usage (Keyboard), */ | ||
600 | 0xA1, 0x01, /* Collection (Application), */ | ||
601 | 0x85, 0x0D, /* Report ID (13), */ | ||
602 | 0x05, 0x07, /* Usage Page (Keyboard), */ | ||
603 | 0x19, 0xE0, /* Usage Minimum (KB Leftcontrol), */ | ||
604 | 0x29, 0xE7, /* Usage Maximum (KB Right GUI), */ | ||
605 | 0x14, /* Logical Minimum (0), */ | ||
606 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
607 | 0x75, 0x01, /* Report Size (1), */ | ||
608 | 0x95, 0x08, /* Report Count (8), */ | ||
609 | 0x81, 0x02, /* Input (Variable), */ | ||
610 | 0x75, 0x08, /* Report Size (8), */ | ||
611 | 0x95, 0x01, /* Report Count (1), */ | ||
612 | 0x81, 0x01, /* Input (Constant), */ | ||
613 | 0x18, /* Usage Minimum (None), */ | ||
614 | 0x29, 0x65, /* Usage Maximum (KB Application), */ | ||
615 | 0x14, /* Logical Minimum (0), */ | ||
616 | 0x25, 0x65, /* Logical Maximum (101), */ | ||
617 | 0x75, 0x08, /* Report Size (8), */ | ||
618 | 0x95, 0x05, /* Report Count (5), */ | ||
619 | 0x80, /* Input, */ | ||
620 | 0xC0, /* End Collection, */ | ||
621 | 0x05, 0x0C, /* Usage Page (Consumer), */ | ||
622 | 0x09, 0x01, /* Usage (Consumer Control), */ | ||
623 | 0xA1, 0x01, /* Collection (Application), */ | ||
624 | 0x85, 0x0C, /* Report ID (12), */ | ||
625 | 0x09, 0xE9, /* Usage (Volume Inc), */ | ||
626 | 0x09, 0xEA, /* Usage (Volume Dec), */ | ||
627 | 0x14, /* Logical Minimum (0), */ | ||
628 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
629 | 0x75, 0x01, /* Report Size (1), */ | ||
630 | 0x95, 0x02, /* Report Count (2), */ | ||
631 | 0x81, 0x02, /* Input (Variable), */ | ||
632 | 0x75, 0x06, /* Report Size (6), */ | ||
633 | 0x95, 0x01, /* Report Count (1), */ | ||
634 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
635 | 0x75, 0x10, /* Report Size (16), */ | ||
636 | 0x95, 0x03, /* Report Count (3), */ | ||
637 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
638 | 0xC0 /* End Collection */ | ||
508 | }; | 639 | }; |
509 | 640 | ||
510 | static int waltop_probe(struct hid_device *hdev, | 641 | static int waltop_probe(struct hid_device *hdev, |
511 | const struct hid_device_id *id) | 642 | const struct hid_device_id *id) |
512 | { | 643 | { |
513 | int ret; | 644 | int ret; |
514 | struct waltop_state *s; | ||
515 | |||
516 | s = kzalloc(sizeof(*s), GFP_KERNEL); | ||
517 | if (s == NULL) { | ||
518 | hid_err(hdev, "can't allocate device state\n"); | ||
519 | ret = -ENOMEM; | ||
520 | goto err; | ||
521 | } | ||
522 | |||
523 | s->pressure0 = 0; | ||
524 | s->pressure1 = 0; | ||
525 | |||
526 | hid_set_drvdata(hdev, s); | ||
527 | 645 | ||
528 | ret = hid_parse(hdev); | 646 | ret = hid_parse(hdev); |
529 | if (ret) { | 647 | if (ret) { |
@@ -539,7 +657,6 @@ static int waltop_probe(struct hid_device *hdev, | |||
539 | 657 | ||
540 | return 0; | 658 | return 0; |
541 | err: | 659 | err: |
542 | kfree(s); | ||
543 | return ret; | 660 | return ret; |
544 | } | 661 | } |
545 | 662 | ||
@@ -583,6 +700,12 @@ static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
583 | *rsize = sizeof(media_tablet_14_1_inch_rdesc_fixed); | 700 | *rsize = sizeof(media_tablet_14_1_inch_rdesc_fixed); |
584 | } | 701 | } |
585 | break; | 702 | break; |
703 | case USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET: | ||
704 | if (*rsize == SIRIUS_BATTERY_FREE_TABLET_RDESC_ORIG_SIZE) { | ||
705 | rdesc = sirius_battery_free_tablet_rdesc_fixed; | ||
706 | *rsize = sizeof(sirius_battery_free_tablet_rdesc_fixed); | ||
707 | } | ||
708 | break; | ||
586 | } | 709 | } |
587 | return rdesc; | 710 | return rdesc; |
588 | } | 711 | } |
@@ -590,39 +713,72 @@ static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
590 | static int waltop_raw_event(struct hid_device *hdev, struct hid_report *report, | 713 | static int waltop_raw_event(struct hid_device *hdev, struct hid_report *report, |
591 | u8 *data, int size) | 714 | u8 *data, int size) |
592 | { | 715 | { |
593 | /* If this is a pen input report of a tablet with PID 0038 */ | 716 | /* If this is a pen input report */ |
594 | if (hdev->product == USB_DEVICE_ID_WALTOP_PID_0038 && | 717 | if (report->type == HID_INPUT_REPORT && report->id == 16 && size >= 8) { |
595 | report->type == HID_INPUT_REPORT && | ||
596 | report->id == 16 && | ||
597 | size == 8) { | ||
598 | struct waltop_state *s = hid_get_drvdata(hdev); | ||
599 | |||
600 | /* | 718 | /* |
601 | * Ignore maximum pressure reported when a barrel button is | 719 | * Ignore reported pressure when a barrel button is pressed, |
602 | * pressed. | 720 | * because it is rarely correct. |
603 | */ | 721 | */ |
604 | 722 | ||
605 | /* If a barrel button is pressed */ | 723 | /* If a barrel button is pressed */ |
606 | if ((data[1] & 0xF) > 1) { | 724 | if ((data[1] & 0xF) > 1) { |
607 | /* Use the last known pressure */ | 725 | /* Report zero pressure */ |
608 | data[6] = s->pressure0; | 726 | data[6] = 0; |
609 | data[7] = s->pressure1; | 727 | data[7] = 0; |
610 | } else { | ||
611 | /* Remember reported pressure */ | ||
612 | s->pressure0 = data[6]; | ||
613 | s->pressure1 = data[7]; | ||
614 | } | 728 | } |
615 | } | 729 | } |
616 | 730 | ||
731 | /* If this is a pen input report of Sirius Battery Free Tablet */ | ||
732 | if (hdev->product == USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET && | ||
733 | report->type == HID_INPUT_REPORT && | ||
734 | report->id == 16 && | ||
735 | size == 10) { | ||
736 | /* | ||
737 | * The tablet reports tilt as roughly sin(a)*21 (18 means 60 | ||
738 | * degrees). | ||
739 | * | ||
740 | * This array stores angles as radians * 100, corresponding to | ||
741 | * reported values up to 60 degrees, as expected by userspace. | ||
742 | */ | ||
743 | static const s8 tilt_to_radians[] = { | ||
744 | 0, 5, 10, 14, 19, 24, 29, 34, 40, 45, | ||
745 | 50, 56, 62, 68, 74, 81, 88, 96, 105 | ||
746 | }; | ||
747 | |||
748 | s8 tilt_x = (s8)data[8]; | ||
749 | s8 tilt_y = (s8)data[9]; | ||
750 | s8 sign_x = tilt_x >= 0 ? 1 : -1; | ||
751 | s8 sign_y = tilt_y >= 0 ? 1 : -1; | ||
752 | |||
753 | tilt_x *= sign_x; | ||
754 | tilt_y *= sign_y; | ||
755 | |||
756 | /* | ||
757 | * Reverse the Y Tilt direction to match the HID standard and | ||
758 | * userspace expectations. See HID Usage Tables v1.12 16.3.2 | ||
759 | * Tilt Orientation. | ||
760 | */ | ||
761 | sign_y *= -1; | ||
762 | |||
763 | /* | ||
764 | * This effectively clamps reported tilt to 60 degrees - the | ||
765 | * range expected by userspace | ||
766 | */ | ||
767 | if (tilt_x > ARRAY_SIZE(tilt_to_radians) - 1) | ||
768 | tilt_x = ARRAY_SIZE(tilt_to_radians) - 1; | ||
769 | if (tilt_y > ARRAY_SIZE(tilt_to_radians) - 1) | ||
770 | tilt_y = ARRAY_SIZE(tilt_to_radians) - 1; | ||
771 | |||
772 | data[8] = tilt_to_radians[tilt_x] * sign_x; | ||
773 | data[9] = tilt_to_radians[tilt_y] * sign_y; | ||
774 | } | ||
775 | |||
617 | return 0; | 776 | return 0; |
618 | } | 777 | } |
619 | 778 | ||
620 | static void waltop_remove(struct hid_device *hdev) | 779 | static void waltop_remove(struct hid_device *hdev) |
621 | { | 780 | { |
622 | struct waltop_state *s = hid_get_drvdata(hdev); | ||
623 | |||
624 | hid_hw_stop(hdev); | 781 | hid_hw_stop(hdev); |
625 | kfree(s); | ||
626 | } | 782 | } |
627 | 783 | ||
628 | static const struct hid_device_id waltop_devices[] = { | 784 | static const struct hid_device_id waltop_devices[] = { |
@@ -638,6 +794,8 @@ static const struct hid_device_id waltop_devices[] = { | |||
638 | USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, | 794 | USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, |
639 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, | 795 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, |
640 | USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) }, | 796 | USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) }, |
797 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, | ||
798 | USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET) }, | ||
641 | { } | 799 | { } |
642 | }; | 800 | }; |
643 | MODULE_DEVICE_TABLE(hid, waltop_devices); | 801 | MODULE_DEVICE_TABLE(hid, waltop_devices); |
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index cac3589b1ed5..84e2fbec5fbb 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c | |||
@@ -769,7 +769,7 @@ static void __ir_to_input(struct wiimote_data *wdata, const __u8 *ir, | |||
769 | 769 | ||
770 | /* | 770 | /* |
771 | * Basic IR data is encoded into 3 bytes. The first two bytes are the | 771 | * Basic IR data is encoded into 3 bytes. The first two bytes are the |
772 | * upper 8 bit of the X/Y data, the 3rd byte contains the lower 2 bits | 772 | * lower 8 bit of the X/Y data, the 3rd byte contains the upper 2 bits |
773 | * of both. | 773 | * of both. |
774 | * If data is packed, then the 3rd byte is put first and slightly | 774 | * If data is packed, then the 3rd byte is put first and slightly |
775 | * reordered. This allows to interleave packed and non-packed data to | 775 | * reordered. This allows to interleave packed and non-packed data to |
@@ -778,17 +778,11 @@ static void __ir_to_input(struct wiimote_data *wdata, const __u8 *ir, | |||
778 | */ | 778 | */ |
779 | 779 | ||
780 | if (packed) { | 780 | if (packed) { |
781 | x = ir[1] << 2; | 781 | x = ir[1] | ((ir[0] & 0x03) << 8); |
782 | y = ir[2] << 2; | 782 | y = ir[2] | ((ir[0] & 0x0c) << 6); |
783 | |||
784 | x |= ir[0] & 0x3; | ||
785 | y |= (ir[0] >> 2) & 0x3; | ||
786 | } else { | 783 | } else { |
787 | x = ir[0] << 2; | 784 | x = ir[0] | ((ir[2] & 0x30) << 4); |
788 | y = ir[1] << 2; | 785 | y = ir[1] | ((ir[2] & 0xc0) << 2); |
789 | |||
790 | x |= (ir[2] >> 4) & 0x3; | ||
791 | y |= (ir[2] >> 6) & 0x3; | ||
792 | } | 786 | } |
793 | 787 | ||
794 | input_report_abs(wdata->ir, xid, x); | 788 | input_report_abs(wdata->ir, xid, x); |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 782c63955f29..0597ee604f6e 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -88,6 +88,7 @@ static const struct hid_blacklist { | |||
88 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT }, | 88 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT }, |
89 | { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT }, | 89 | { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT }, |
90 | { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT }, | 90 | { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT }, |
91 | { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET, HID_QUIRK_MULTI_INPUT }, | ||
91 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 92 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
92 | 93 | ||
93 | { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 94 | { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |