aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2014-09-23 12:08:08 -0400
committerJiri Kosina <jkosina@suse.cz>2014-10-01 03:11:23 -0400
commit7704ac937345d4b502062952657027234aa86a37 (patch)
treef74ae80b7e96d23da461256dde4ec1a57a7968af /drivers
parent494078b0bb578c4cf1e00275dd3224d793013488 (diff)
HID: wacom: implement generic HID handling for pen generic devices
ISDv4 and v5 are plain HID devices. We can directly implement a generic HID parsing/handling and remove the need to manually add those PID in the list of supported devices. This patch implements the pen support only. The finger part will come in a later patch. To be properly notified of an .event() and a .report(), we need to force hid-core to go through the HID parsing. By default, wacom.ko binds only hidraw, so the hid parsing is not done by hid-core. When a true HID device is there, we add the flag HID_CLAIMED_DRIVER to hid->claimed which will force hid-core to parse the incoming reports. (Note that this can be easily backported by directly setting the .claimed flag to HID_CLAIMED_DRIVER even if hid-core does not support HID_CONNECT_DRIVER) Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Acked-by: Jason Gerecke <killertofu@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/hid-core.c3
-rw-r--r--drivers/hid/wacom.h6
-rw-r--r--drivers/hid/wacom_sys.c12
-rw-r--r--drivers/hid/wacom_wac.c179
-rw-r--r--drivers/hid/wacom_wac.h8
5 files changed, 206 insertions, 2 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 12b6e67d9de0..583344dba3c6 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1591,6 +1591,9 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
1591 if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev)) 1591 if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev))
1592 hdev->claimed |= HID_CLAIMED_HIDRAW; 1592 hdev->claimed |= HID_CLAIMED_HIDRAW;
1593 1593
1594 if (connect_mask & HID_CONNECT_DRIVER)
1595 hdev->claimed |= HID_CLAIMED_DRIVER;
1596
1594 /* Drivers with the ->raw_event callback set are not required to connect 1597 /* Drivers with the ->raw_event callback set are not required to connect
1595 * to any other listener. */ 1598 * to any other listener. */
1596 if (!hdev->claimed && !hdev->driver->raw_event) { 1599 if (!hdev->claimed && !hdev->driver->raw_event) {
diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h
index 64bc1b296d91..0cc53440543a 100644
--- a/drivers/hid/wacom.h
+++ b/drivers/hid/wacom.h
@@ -89,6 +89,7 @@
89#include <linux/slab.h> 89#include <linux/slab.h>
90#include <linux/module.h> 90#include <linux/module.h>
91#include <linux/mod_devicetable.h> 91#include <linux/mod_devicetable.h>
92#include <linux/hid.h>
92#include <linux/usb/input.h> 93#include <linux/usb/input.h>
93#include <linux/power_supply.h> 94#include <linux/power_supply.h>
94#include <asm/unaligned.h> 95#include <asm/unaligned.h>
@@ -143,4 +144,9 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
143 struct wacom_wac *wacom_wac); 144 struct wacom_wac *wacom_wac);
144int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, 145int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
145 struct wacom_wac *wacom_wac); 146 struct wacom_wac *wacom_wac);
147void wacom_wac_usage_mapping(struct hid_device *hdev,
148 struct hid_field *field, struct hid_usage *usage);
149int wacom_wac_event(struct hid_device *hdev, struct hid_field *field,
150 struct hid_usage *usage, __s32 value);
151void wacom_wac_report(struct hid_device *hdev, struct hid_report *report);
146#endif 152#endif
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 21ac2baa21be..dd288b2fbfe8 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -13,7 +13,6 @@
13 13
14#include "wacom_wac.h" 14#include "wacom_wac.h"
15#include "wacom.h" 15#include "wacom.h"
16#include <linux/hid.h>
17 16
18#define WAC_MSG_RETRIES 5 17#define WAC_MSG_RETRIES 5
19 18
@@ -215,6 +214,9 @@ static void wacom_usage_mapping(struct hid_device *hdev,
215 features->pressure_max = field->logical_maximum; 214 features->pressure_max = field->logical_maximum;
216 break; 215 break;
217 } 216 }
217
218 if (features->type == HID_GENERIC)
219 wacom_wac_usage_mapping(hdev, field, usage);
218} 220}
219 221
220static void wacom_parse_hid(struct hid_device *hdev, 222static void wacom_parse_hid(struct hid_device *hdev,
@@ -1318,6 +1320,7 @@ static int wacom_probe(struct hid_device *hdev,
1318 struct wacom_wac *wacom_wac; 1320 struct wacom_wac *wacom_wac;
1319 struct wacom_features *features; 1321 struct wacom_features *features;
1320 int error; 1322 int error;
1323 unsigned int connect_mask = HID_CONNECT_HIDRAW;
1321 1324
1322 if (!id->driver_data) 1325 if (!id->driver_data)
1323 return -EINVAL; 1326 return -EINVAL;
@@ -1451,8 +1454,11 @@ static int wacom_probe(struct hid_device *hdev,
1451 /* Note that if query fails it is not a hard failure */ 1454 /* Note that if query fails it is not a hard failure */
1452 wacom_query_tablet_data(hdev, features); 1455 wacom_query_tablet_data(hdev, features);
1453 1456
1457 if (features->type == HID_GENERIC)
1458 connect_mask |= HID_CONNECT_DRIVER;
1459
1454 /* Regular HID work starts now */ 1460 /* Regular HID work starts now */
1455 error = hid_hw_start(hdev, HID_CONNECT_HIDRAW); 1461 error = hid_hw_start(hdev, connect_mask);
1456 if (error) { 1462 if (error) {
1457 hid_err(hdev, "hw start failed\n"); 1463 hid_err(hdev, "hw start failed\n");
1458 goto fail_hw_start; 1464 goto fail_hw_start;
@@ -1532,6 +1538,8 @@ static struct hid_driver wacom_driver = {
1532 .id_table = wacom_ids, 1538 .id_table = wacom_ids,
1533 .probe = wacom_probe, 1539 .probe = wacom_probe,
1534 .remove = wacom_remove, 1540 .remove = wacom_remove,
1541 .event = wacom_wac_event,
1542 .report = wacom_wac_report,
1535#ifdef CONFIG_PM 1543#ifdef CONFIG_PM
1536 .resume = wacom_resume, 1544 .resume = wacom_resume,
1537 .reset_resume = wacom_reset_resume, 1545 .reset_resume = wacom_reset_resume,
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index b8180e40534d..e77d46d85a11 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1248,6 +1248,176 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
1248 return 0; 1248 return 0;
1249} 1249}
1250 1250
1251static void wacom_map_usage(struct wacom *wacom, struct hid_usage *usage,
1252 struct hid_field *field, __u8 type, __u16 code, int fuzz)
1253{
1254 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1255 struct input_dev *input = wacom_wac->input;
1256 int fmin = field->logical_minimum;
1257 int fmax = field->logical_maximum;
1258
1259 usage->type = type;
1260 usage->code = code;
1261
1262 set_bit(type, input->evbit);
1263
1264 switch (type) {
1265 case EV_ABS:
1266 input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
1267 input_abs_set_res(input, code,
1268 hidinput_calc_abs_res(field, code));
1269 break;
1270 case EV_KEY:
1271 input_set_capability(input, EV_KEY, code);
1272 break;
1273 case EV_MSC:
1274 input_set_capability(input, EV_MSC, code);
1275 break;
1276 }
1277}
1278
1279static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
1280 struct hid_field *field, struct hid_usage *usage)
1281{
1282 struct wacom *wacom = hid_get_drvdata(hdev);
1283
1284 switch (usage->hid) {
1285 case HID_GD_X:
1286 wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4);
1287 break;
1288 case HID_GD_Y:
1289 wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4);
1290 break;
1291 case HID_DG_TIPPRESSURE:
1292 wacom_map_usage(wacom, usage, field, EV_ABS, ABS_PRESSURE, 0);
1293 break;
1294 case HID_DG_INRANGE:
1295 wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOOL_PEN, 0);
1296 break;
1297 case HID_DG_INVERT:
1298 wacom_map_usage(wacom, usage, field, EV_KEY,
1299 BTN_TOOL_RUBBER, 0);
1300 break;
1301 case HID_DG_ERASER:
1302 case HID_DG_TIPSWITCH:
1303 wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0);
1304 break;
1305 case HID_DG_BARRELSWITCH:
1306 wacom_map_usage(wacom, usage, field, EV_KEY, BTN_STYLUS, 0);
1307 break;
1308 case HID_DG_BARRELSWITCH2:
1309 wacom_map_usage(wacom, usage, field, EV_KEY, BTN_STYLUS2, 0);
1310 break;
1311 case HID_DG_TOOLSERIALNUMBER:
1312 wacom_map_usage(wacom, usage, field, EV_MSC, MSC_SERIAL, 0);
1313 break;
1314 }
1315}
1316
1317static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field,
1318 struct hid_usage *usage, __s32 value)
1319{
1320 struct wacom *wacom = hid_get_drvdata(hdev);
1321 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1322 struct input_dev *input = wacom_wac->input;
1323
1324 /* checking which Tool / tip switch to send */
1325 switch (usage->hid) {
1326 case HID_DG_INRANGE:
1327 wacom_wac->hid_data.inrange_state = value;
1328 return 0;
1329 case HID_DG_INVERT:
1330 wacom_wac->hid_data.invert_state = value;
1331 return 0;
1332 case HID_DG_ERASER:
1333 case HID_DG_TIPSWITCH:
1334 wacom_wac->hid_data.tipswitch |= value;
1335 return 0;
1336 }
1337
1338 /* send pen events only when touch is up or forced out */
1339 if (!usage->type || wacom_wac->shared->touch_down)
1340 return 0;
1341
1342 input_event(input, usage->type, usage->code, value);
1343
1344 return 0;
1345}
1346
1347static void wacom_wac_pen_report(struct hid_device *hdev,
1348 struct hid_report *report)
1349{
1350 struct wacom *wacom = hid_get_drvdata(hdev);
1351 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1352 struct input_dev *input = wacom_wac->input;
1353 bool prox = wacom_wac->hid_data.inrange_state;
1354
1355 if (!wacom_wac->shared->stylus_in_proximity) /* first in prox */
1356 /* Going into proximity select tool */
1357 wacom_wac->tool[0] = wacom_wac->hid_data.invert_state ?
1358 BTN_TOOL_RUBBER : BTN_TOOL_PEN;
1359
1360 /* keep pen state for touch events */
1361 wacom_wac->shared->stylus_in_proximity = prox;
1362
1363 /* send pen events only when touch is up or forced out */
1364 if (!wacom_wac->shared->touch_down) {
1365 input_report_key(input, BTN_TOUCH,
1366 wacom_wac->hid_data.tipswitch);
1367 input_report_key(input, wacom_wac->tool[0], prox);
1368
1369 wacom_wac->hid_data.tipswitch = false;
1370
1371 input_sync(input);
1372 }
1373}
1374
1375#define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \
1376 ((f)->physical == HID_DG_STYLUS))
1377#define WACOM_FINGER_FIELD(f) (((f)->logical == HID_DG_FINGER) || \
1378 ((f)->physical == HID_DG_FINGER))
1379
1380void wacom_wac_usage_mapping(struct hid_device *hdev,
1381 struct hid_field *field, struct hid_usage *usage)
1382{
1383 struct wacom *wacom = hid_get_drvdata(hdev);
1384 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1385 struct input_dev *input = wacom_wac->input;
1386
1387 /* currently, only direct devices have proper hid report descriptors */
1388 __set_bit(INPUT_PROP_DIRECT, input->propbit);
1389
1390 if (WACOM_PEN_FIELD(field))
1391 return wacom_wac_pen_usage_mapping(hdev, field, usage);
1392}
1393
1394int wacom_wac_event(struct hid_device *hdev, struct hid_field *field,
1395 struct hid_usage *usage, __s32 value)
1396{
1397 struct wacom *wacom = hid_get_drvdata(hdev);
1398
1399 if (wacom->wacom_wac.features.type != HID_GENERIC)
1400 return 0;
1401
1402 if (WACOM_PEN_FIELD(field))
1403 return wacom_wac_pen_event(hdev, field, usage, value);
1404
1405 return 0;
1406}
1407
1408void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
1409{
1410 struct wacom *wacom = hid_get_drvdata(hdev);
1411 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1412 struct hid_field *field = report->field[0];
1413
1414 if (wacom_wac->features.type != HID_GENERIC)
1415 return;
1416
1417 if (WACOM_PEN_FIELD(field))
1418 return wacom_wac_pen_report(hdev, report);
1419}
1420
1251static int wacom_bpt_touch(struct wacom_wac *wacom) 1421static int wacom_bpt_touch(struct wacom_wac *wacom)
1252{ 1422{
1253 struct wacom_features *features = &wacom->features; 1423 struct wacom_features *features = &wacom->features;
@@ -1746,6 +1916,10 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
1746 1916
1747 input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 1917 input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
1748 1918
1919 if (features->type == HID_GENERIC)
1920 /* setup has already been done */
1921 return 0;
1922
1749 __set_bit(BTN_TOUCH, input_dev->keybit); 1923 __set_bit(BTN_TOUCH, input_dev->keybit);
1750 __set_bit(ABS_MISC, input_dev->absbit); 1924 __set_bit(ABS_MISC, input_dev->absbit);
1751 1925
@@ -2585,6 +2759,9 @@ static const struct wacom_features wacom_features_0x30C =
2585 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10, 2759 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10,
2586 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; 2760 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
2587 2761
2762static const struct wacom_features wacom_features_HID_ANY_ID =
2763 { "Wacom HID", .type = HID_GENERIC };
2764
2588#define USB_DEVICE_WACOM(prod) \ 2765#define USB_DEVICE_WACOM(prod) \
2589 HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ 2766 HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
2590 .driver_data = (kernel_ulong_t)&wacom_features_##prod 2767 .driver_data = (kernel_ulong_t)&wacom_features_##prod
@@ -2729,6 +2906,8 @@ const struct hid_device_id wacom_ids[] = {
2729 { USB_DEVICE_WACOM(0x4004) }, 2906 { USB_DEVICE_WACOM(0x4004) },
2730 { USB_DEVICE_WACOM(0x5000) }, 2907 { USB_DEVICE_WACOM(0x5000) },
2731 { USB_DEVICE_WACOM(0x5002) }, 2908 { USB_DEVICE_WACOM(0x5002) },
2909
2910 { USB_DEVICE_WACOM(HID_ANY_ID) },
2732 { } 2911 { }
2733}; 2912};
2734MODULE_DEVICE_TABLE(hid, wacom_ids); 2913MODULE_DEVICE_TABLE(hid, wacom_ids);
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index 72f9ca8e5cd4..f472eac292d5 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -113,6 +113,7 @@ enum {
113 MTSCREEN, 113 MTSCREEN,
114 MTTPC, 114 MTTPC,
115 MTTPC_B, 115 MTTPC_B,
116 HID_GENERIC,
116 MAX_TYPE 117 MAX_TYPE
117}; 118};
118 119
@@ -154,6 +155,12 @@ struct wacom_shared {
154 struct input_dev *touch_input; 155 struct input_dev *touch_input;
155}; 156};
156 157
158struct hid_data {
159 bool inrange_state;
160 bool invert_state;
161 bool tipswitch;
162};
163
157struct wacom_wac { 164struct wacom_wac {
158 char name[WACOM_NAME_MAX]; 165 char name[WACOM_NAME_MAX];
159 char pad_name[WACOM_NAME_MAX]; 166 char pad_name[WACOM_NAME_MAX];
@@ -175,6 +182,7 @@ struct wacom_wac {
175 int ps_connected; 182 int ps_connected;
176 u8 bt_features; 183 u8 bt_features;
177 u8 bt_high_speed; 184 u8 bt_high_speed;
185 struct hid_data hid_data;
178}; 186};
179 187
180#endif 188#endif