aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/wacom_wac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/wacom_wac.c')
-rw-r--r--drivers/hid/wacom_wac.c312
1 files changed, 312 insertions, 0 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index aa6a08eb7ad6..586b2405b0d4 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1248,6 +1248,296 @@ 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
1375static void wacom_wac_finger_usage_mapping(struct hid_device *hdev,
1376 struct hid_field *field, struct hid_usage *usage)
1377{
1378 struct wacom *wacom = hid_get_drvdata(hdev);
1379 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1380 struct input_dev *input = wacom_wac->input;
1381 unsigned touch_max = wacom_wac->features.touch_max;
1382
1383 switch (usage->hid) {
1384 case HID_GD_X:
1385 if (touch_max == 1)
1386 wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4);
1387 else
1388 wacom_map_usage(wacom, usage, field, EV_ABS,
1389 ABS_MT_POSITION_X, 4);
1390 break;
1391 case HID_GD_Y:
1392 if (touch_max == 1)
1393 wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4);
1394 else
1395 wacom_map_usage(wacom, usage, field, EV_ABS,
1396 ABS_MT_POSITION_Y, 4);
1397 break;
1398 case HID_DG_CONTACTID:
1399 input_mt_init_slots(input, wacom_wac->features.touch_max,
1400 INPUT_MT_DIRECT);
1401 break;
1402 case HID_DG_INRANGE:
1403 break;
1404 case HID_DG_INVERT:
1405 break;
1406 case HID_DG_TIPSWITCH:
1407 wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0);
1408 break;
1409 }
1410}
1411
1412static int wacom_wac_finger_event(struct hid_device *hdev,
1413 struct hid_field *field, struct hid_usage *usage, __s32 value)
1414{
1415 struct wacom *wacom = hid_get_drvdata(hdev);
1416 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1417
1418 switch (usage->hid) {
1419 case HID_GD_X:
1420 wacom_wac->hid_data.x = value;
1421 break;
1422 case HID_GD_Y:
1423 wacom_wac->hid_data.y = value;
1424 break;
1425 case HID_DG_CONTACTID:
1426 wacom_wac->hid_data.id = value;
1427 break;
1428 case HID_DG_TIPSWITCH:
1429 wacom_wac->hid_data.tipswitch = value;
1430 break;
1431 }
1432
1433
1434 return 0;
1435}
1436
1437static void wacom_wac_finger_mt_report(struct wacom_wac *wacom_wac,
1438 struct input_dev *input, bool touch)
1439{
1440 int slot;
1441 struct hid_data *hid_data = &wacom_wac->hid_data;
1442
1443 slot = input_mt_get_slot_by_key(input, hid_data->id);
1444
1445 input_mt_slot(input, slot);
1446 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
1447 if (touch) {
1448 input_report_abs(input, ABS_MT_POSITION_X, hid_data->x);
1449 input_report_abs(input, ABS_MT_POSITION_Y, hid_data->y);
1450 }
1451 input_mt_sync_frame(input);
1452}
1453
1454static void wacom_wac_finger_single_touch_report(struct wacom_wac *wacom_wac,
1455 struct input_dev *input, bool touch)
1456{
1457 struct hid_data *hid_data = &wacom_wac->hid_data;
1458
1459 if (touch) {
1460 input_report_abs(input, ABS_X, hid_data->x);
1461 input_report_abs(input, ABS_Y, hid_data->y);
1462 }
1463 input_report_key(input, BTN_TOUCH, touch);
1464}
1465
1466static void wacom_wac_finger_report(struct hid_device *hdev,
1467 struct hid_report *report)
1468{
1469 struct wacom *wacom = hid_get_drvdata(hdev);
1470 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1471 struct input_dev *input = wacom_wac->input;
1472 bool touch = wacom_wac->hid_data.tipswitch &&
1473 !wacom_wac->shared->stylus_in_proximity;
1474 unsigned touch_max = wacom_wac->features.touch_max;
1475
1476 if (touch_max > 1)
1477 wacom_wac_finger_mt_report(wacom_wac, input, touch);
1478 else
1479 wacom_wac_finger_single_touch_report(wacom_wac, input, touch);
1480 input_sync(input);
1481
1482 /* keep touch state for pen event */
1483 wacom_wac->shared->touch_down = touch;
1484}
1485
1486#define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \
1487 ((f)->physical == HID_DG_STYLUS))
1488#define WACOM_FINGER_FIELD(f) (((f)->logical == HID_DG_FINGER) || \
1489 ((f)->physical == HID_DG_FINGER))
1490
1491void wacom_wac_usage_mapping(struct hid_device *hdev,
1492 struct hid_field *field, struct hid_usage *usage)
1493{
1494 struct wacom *wacom = hid_get_drvdata(hdev);
1495 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1496 struct input_dev *input = wacom_wac->input;
1497
1498 /* currently, only direct devices have proper hid report descriptors */
1499 __set_bit(INPUT_PROP_DIRECT, input->propbit);
1500
1501 if (WACOM_PEN_FIELD(field))
1502 return wacom_wac_pen_usage_mapping(hdev, field, usage);
1503
1504 if (WACOM_FINGER_FIELD(field))
1505 return wacom_wac_finger_usage_mapping(hdev, field, usage);
1506}
1507
1508int wacom_wac_event(struct hid_device *hdev, struct hid_field *field,
1509 struct hid_usage *usage, __s32 value)
1510{
1511 struct wacom *wacom = hid_get_drvdata(hdev);
1512
1513 if (wacom->wacom_wac.features.type != HID_GENERIC)
1514 return 0;
1515
1516 if (WACOM_PEN_FIELD(field))
1517 return wacom_wac_pen_event(hdev, field, usage, value);
1518
1519 if (WACOM_FINGER_FIELD(field))
1520 return wacom_wac_finger_event(hdev, field, usage, value);
1521
1522 return 0;
1523}
1524
1525void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
1526{
1527 struct wacom *wacom = hid_get_drvdata(hdev);
1528 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1529 struct hid_field *field = report->field[0];
1530
1531 if (wacom_wac->features.type != HID_GENERIC)
1532 return;
1533
1534 if (WACOM_PEN_FIELD(field))
1535 return wacom_wac_pen_report(hdev, report);
1536
1537 if (WACOM_FINGER_FIELD(field))
1538 return wacom_wac_finger_report(hdev, report);
1539}
1540
1251static int wacom_bpt_touch(struct wacom_wac *wacom) 1541static int wacom_bpt_touch(struct wacom_wac *wacom)
1252{ 1542{
1253 struct wacom_features *features = &wacom->features; 1543 struct wacom_features *features = &wacom->features;
@@ -1746,6 +2036,10 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
1746 2036
1747 input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 2037 input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
1748 2038
2039 if (features->type == HID_GENERIC)
2040 /* setup has already been done */
2041 return 0;
2042
1749 __set_bit(BTN_TOUCH, input_dev->keybit); 2043 __set_bit(BTN_TOUCH, input_dev->keybit);
1750 __set_bit(ABS_MISC, input_dev->absbit); 2044 __set_bit(ABS_MISC, input_dev->absbit);
1751 2045
@@ -1990,6 +2284,9 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
1990 input_set_abs_params(input_dev, ABS_X, 0, 1, 0, 0); 2284 input_set_abs_params(input_dev, ABS_X, 0, 1, 0, 0);
1991 input_set_abs_params(input_dev, ABS_Y, 0, 1, 0, 0); 2285 input_set_abs_params(input_dev, ABS_Y, 0, 1, 0, 0);
1992 2286
2287 /* kept for making udev and libwacom accepting the pad */
2288 __set_bit(BTN_STYLUS, input_dev->keybit);
2289
1993 switch (features->type) { 2290 switch (features->type) {
1994 case GRAPHIRE_BT: 2291 case GRAPHIRE_BT:
1995 __set_bit(BTN_0, input_dev->keybit); 2292 __set_bit(BTN_0, input_dev->keybit);
@@ -2573,6 +2870,17 @@ static const struct wacom_features wacom_features_0x309 =
2573 { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */ 2870 { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */
2574 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10, 2871 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10,
2575 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; 2872 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
2873static const struct wacom_features wacom_features_0x30A =
2874 { "Wacom ISDv5 30A", 59352, 33648, 2047, 63,
2875 CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200,
2876 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30C };
2877static const struct wacom_features wacom_features_0x30C =
2878 { "Wacom ISDv5 30C", .type = WACOM_24HDT, /* Touch */
2879 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10,
2880 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
2881
2882static const struct wacom_features wacom_features_HID_ANY_ID =
2883 { "Wacom HID", .type = HID_GENERIC };
2576 2884
2577#define USB_DEVICE_WACOM(prod) \ 2885#define USB_DEVICE_WACOM(prod) \
2578 HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ 2886 HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
@@ -2708,6 +3016,8 @@ const struct hid_device_id wacom_ids[] = {
2708 { USB_DEVICE_WACOM(0x304) }, 3016 { USB_DEVICE_WACOM(0x304) },
2709 { USB_DEVICE_WACOM(0x307) }, 3017 { USB_DEVICE_WACOM(0x307) },
2710 { USB_DEVICE_WACOM(0x309) }, 3018 { USB_DEVICE_WACOM(0x309) },
3019 { USB_DEVICE_WACOM(0x30A) },
3020 { USB_DEVICE_WACOM(0x30C) },
2711 { USB_DEVICE_WACOM(0x30E) }, 3021 { USB_DEVICE_WACOM(0x30E) },
2712 { USB_DEVICE_WACOM(0x314) }, 3022 { USB_DEVICE_WACOM(0x314) },
2713 { USB_DEVICE_WACOM(0x315) }, 3023 { USB_DEVICE_WACOM(0x315) },
@@ -2716,6 +3026,8 @@ const struct hid_device_id wacom_ids[] = {
2716 { USB_DEVICE_WACOM(0x4004) }, 3026 { USB_DEVICE_WACOM(0x4004) },
2717 { USB_DEVICE_WACOM(0x5000) }, 3027 { USB_DEVICE_WACOM(0x5000) },
2718 { USB_DEVICE_WACOM(0x5002) }, 3028 { USB_DEVICE_WACOM(0x5002) },
3029
3030 { USB_DEVICE_WACOM(HID_ANY_ID) },
2719 { } 3031 { }
2720}; 3032};
2721MODULE_DEVICE_TABLE(hid, wacom_ids); 3033MODULE_DEVICE_TABLE(hid, wacom_ids);