diff options
Diffstat (limited to 'drivers/hid/wacom_wac.c')
-rw-r--r-- | drivers/hid/wacom_wac.c | 312 |
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 | ||
1251 | static 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 | |||
1279 | static 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 | |||
1317 | static 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 | |||
1347 | static 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 | static 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 | |||
1412 | static 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 | |||
1437 | static 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 | |||
1454 | static 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 | |||
1466 | static 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 | |||
1491 | void 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 | |||
1508 | int 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 | |||
1525 | void 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 | |||
1251 | static int wacom_bpt_touch(struct wacom_wac *wacom) | 1541 | static 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 }; |
2873 | static 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 }; | ||
2877 | static 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 | |||
2882 | static 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 | }; |
2721 | MODULE_DEVICE_TABLE(hid, wacom_ids); | 3033 | MODULE_DEVICE_TABLE(hid, wacom_ids); |