aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig16
-rw-r--r--drivers/hid/hid-apple.c3
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-ids.h1
-rw-r--r--drivers/hid/hid-input.c25
-rw-r--r--drivers/hid/hid-logitech-dj.c5
-rw-r--r--drivers/hid/hid-wacom.c302
-rw-r--r--drivers/hid/hid-waltop.c230
-rw-r--r--drivers/hid/hid-wiimote-core.c16
-rw-r--r--drivers/hid/usbhid/hid-quirks.c1
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
34config HID_BATTERY_STRENGTH 34config 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
39config HIDRAW 43config HIDRAW
40 bool "/dev/hidraw raw HID device support" 44 bool "/dev/hidraw raw HID device support"
@@ -613,16 +617,10 @@ config THRUSTMASTER_FF
613config HID_WACOM 617config 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
619config 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
627config HID_WIIMOTE 625config 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
36struct wacom_data { 37struct 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 */
53static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 }; 56static 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*/
58static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 };
54 59
55static enum power_supply_property wacom_battery_props[] = { 60static 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
72static 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
102static 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
122static 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
162err:
163 return ret;
164}
165
166static 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
67static int wacom_battery_get_property(struct power_supply *psy, 183static 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
125static 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
138static void wacom_poke(struct hid_device *hdev, u8 speed) 231static 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
636err_ac: 767err_ac:
637 power_supply_unregister(&wdata->battery); 768 power_supply_unregister(&wdata->battery);
638err_battery: 769err_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 772destroy_leds:
773 wacom_destroy_leds(hdev);
642err_free: 774err_free:
643 kfree(wdata); 775 kfree(wdata);
644 return ret; 776 return ret;
@@ -646,16 +778,14 @@ err_free:
646 778
647static void wacom_remove(struct hid_device *hdev) 779static 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
694module_init(wacom_init); 824module_init(wacom_init);
695module_exit(wacom_exit); 825module_exit(wacom_exit);
826MODULE_DESCRIPTION("Driver for Wacom Graphire Bluetooth and Wacom Intuos4 WL");
696MODULE_LICENSE("GPL"); 827MODULE_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
505struct 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 */
515static __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
510static int waltop_probe(struct hid_device *hdev, 641static 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;
541err: 659err:
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,
590static int waltop_raw_event(struct hid_device *hdev, struct hid_report *report, 713static 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
620static void waltop_remove(struct hid_device *hdev) 779static 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
628static const struct hid_device_id waltop_devices[] = { 784static 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};
643MODULE_DEVICE_TABLE(hid, waltop_devices); 801MODULE_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 },