diff options
-rw-r--r-- | drivers/hid/wacom.h | 8 | ||||
-rw-r--r-- | drivers/hid/wacom_sys.c | 75 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.c | 259 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.h | 8 |
4 files changed, 287 insertions, 63 deletions
diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index 7db432809e9e..ad7318db1dfe 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h | |||
@@ -129,13 +129,6 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac) | |||
129 | schedule_work(&wacom->work); | 129 | schedule_work(&wacom->work); |
130 | } | 130 | } |
131 | 131 | ||
132 | static inline void wacom_notify_battery(struct wacom_wac *wacom_wac) | ||
133 | { | ||
134 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
135 | |||
136 | power_supply_changed(&wacom->battery); | ||
137 | } | ||
138 | |||
139 | extern const struct hid_device_id wacom_ids[]; | 132 | extern const struct hid_device_id wacom_ids[]; |
140 | 133 | ||
141 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); | 134 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); |
@@ -149,4 +142,5 @@ void wacom_wac_usage_mapping(struct hid_device *hdev, | |||
149 | int wacom_wac_event(struct hid_device *hdev, struct hid_field *field, | 142 | int wacom_wac_event(struct hid_device *hdev, struct hid_field *field, |
150 | struct hid_usage *usage, __s32 value); | 143 | struct hid_usage *usage, __s32 value); |
151 | void wacom_wac_report(struct hid_device *hdev, struct hid_report *report); | 144 | void wacom_wac_report(struct hid_device *hdev, struct hid_report *report); |
145 | void wacom_battery_work(struct work_struct *work); | ||
152 | #endif | 146 | #endif |
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index f0568a7e6de9..353fe476be26 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
@@ -406,6 +406,9 @@ static int wacom_query_tablet_data(struct hid_device *hdev, | |||
406 | else if (features->type == WACOM_27QHDT) { | 406 | else if (features->type == WACOM_27QHDT) { |
407 | return wacom_set_device_mode(hdev, 131, 3, 2); | 407 | return wacom_set_device_mode(hdev, 131, 3, 2); |
408 | } | 408 | } |
409 | else if (features->type == BAMBOO_PAD) { | ||
410 | return wacom_set_device_mode(hdev, 2, 2, 2); | ||
411 | } | ||
409 | } else if (features->device_type == BTN_TOOL_PEN) { | 412 | } else if (features->device_type == BTN_TOOL_PEN) { |
410 | if (features->type <= BAMBOO_PT && features->type != WIRELESS) { | 413 | if (features->type <= BAMBOO_PT && features->type != WIRELESS) { |
411 | return wacom_set_device_mode(hdev, 2, 2, 2); | 414 | return wacom_set_device_mode(hdev, 2, 2, 2); |
@@ -524,6 +527,11 @@ static int wacom_add_shared_data(struct hid_device *hdev) | |||
524 | 527 | ||
525 | wacom_wac->shared = &data->shared; | 528 | wacom_wac->shared = &data->shared; |
526 | 529 | ||
530 | if (wacom_wac->features.device_type == BTN_TOOL_FINGER) | ||
531 | wacom_wac->shared->touch = hdev; | ||
532 | else if (wacom_wac->features.device_type == BTN_TOOL_PEN) | ||
533 | wacom_wac->shared->pen = hdev; | ||
534 | |||
527 | out: | 535 | out: |
528 | mutex_unlock(&wacom_udev_list_lock); | 536 | mutex_unlock(&wacom_udev_list_lock); |
529 | return retval; | 537 | return retval; |
@@ -541,14 +549,22 @@ static void wacom_release_shared_data(struct kref *kref) | |||
541 | kfree(data); | 549 | kfree(data); |
542 | } | 550 | } |
543 | 551 | ||
544 | static void wacom_remove_shared_data(struct wacom_wac *wacom) | 552 | static void wacom_remove_shared_data(struct wacom *wacom) |
545 | { | 553 | { |
546 | struct wacom_hdev_data *data; | 554 | struct wacom_hdev_data *data; |
555 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
556 | |||
557 | if (wacom_wac->shared) { | ||
558 | data = container_of(wacom_wac->shared, struct wacom_hdev_data, | ||
559 | shared); | ||
560 | |||
561 | if (wacom_wac->shared->touch == wacom->hdev) | ||
562 | wacom_wac->shared->touch = NULL; | ||
563 | else if (wacom_wac->shared->pen == wacom->hdev) | ||
564 | wacom_wac->shared->pen = NULL; | ||
547 | 565 | ||
548 | if (wacom->shared) { | ||
549 | data = container_of(wacom->shared, struct wacom_hdev_data, shared); | ||
550 | kref_put(&data->kref, wacom_release_shared_data); | 566 | kref_put(&data->kref, wacom_release_shared_data); |
551 | wacom->shared = NULL; | 567 | wacom_wac->shared = NULL; |
552 | } | 568 | } |
553 | } | 569 | } |
554 | 570 | ||
@@ -929,6 +945,7 @@ static void wacom_destroy_leds(struct wacom *wacom) | |||
929 | } | 945 | } |
930 | 946 | ||
931 | static enum power_supply_property wacom_battery_props[] = { | 947 | static enum power_supply_property wacom_battery_props[] = { |
948 | POWER_SUPPLY_PROP_PRESENT, | ||
932 | POWER_SUPPLY_PROP_STATUS, | 949 | POWER_SUPPLY_PROP_STATUS, |
933 | POWER_SUPPLY_PROP_SCOPE, | 950 | POWER_SUPPLY_PROP_SCOPE, |
934 | POWER_SUPPLY_PROP_CAPACITY | 951 | POWER_SUPPLY_PROP_CAPACITY |
@@ -948,6 +965,9 @@ static int wacom_battery_get_property(struct power_supply *psy, | |||
948 | int ret = 0; | 965 | int ret = 0; |
949 | 966 | ||
950 | switch (psp) { | 967 | switch (psp) { |
968 | case POWER_SUPPLY_PROP_PRESENT: | ||
969 | val->intval = wacom->wacom_wac.bat_connected; | ||
970 | break; | ||
951 | case POWER_SUPPLY_PROP_SCOPE: | 971 | case POWER_SUPPLY_PROP_SCOPE: |
952 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | 972 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; |
953 | break; | 973 | break; |
@@ -961,6 +981,8 @@ static int wacom_battery_get_property(struct power_supply *psy, | |||
961 | else if (wacom->wacom_wac.battery_capacity == 100 && | 981 | else if (wacom->wacom_wac.battery_capacity == 100 && |
962 | wacom->wacom_wac.ps_connected) | 982 | wacom->wacom_wac.ps_connected) |
963 | val->intval = POWER_SUPPLY_STATUS_FULL; | 983 | val->intval = POWER_SUPPLY_STATUS_FULL; |
984 | else if (wacom->wacom_wac.ps_connected) | ||
985 | val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; | ||
964 | else | 986 | else |
965 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | 987 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; |
966 | break; | 988 | break; |
@@ -1041,8 +1063,7 @@ static int wacom_initialize_battery(struct wacom *wacom) | |||
1041 | 1063 | ||
1042 | static void wacom_destroy_battery(struct wacom *wacom) | 1064 | static void wacom_destroy_battery(struct wacom *wacom) |
1043 | { | 1065 | { |
1044 | if ((wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) && | 1066 | if (wacom->battery.dev) { |
1045 | wacom->battery.dev) { | ||
1046 | power_supply_unregister(&wacom->battery); | 1067 | power_supply_unregister(&wacom->battery); |
1047 | wacom->battery.dev = NULL; | 1068 | wacom->battery.dev = NULL; |
1048 | power_supply_unregister(&wacom->ac); | 1069 | power_supply_unregister(&wacom->ac); |
@@ -1313,6 +1334,20 @@ fail: | |||
1313 | return; | 1334 | return; |
1314 | } | 1335 | } |
1315 | 1336 | ||
1337 | void wacom_battery_work(struct work_struct *work) | ||
1338 | { | ||
1339 | struct wacom *wacom = container_of(work, struct wacom, work); | ||
1340 | |||
1341 | if ((wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) && | ||
1342 | !wacom->battery.dev) { | ||
1343 | wacom_initialize_battery(wacom); | ||
1344 | } | ||
1345 | else if (!(wacom->wacom_wac.features.quirks & WACOM_QUIRK_BATTERY) && | ||
1346 | wacom->battery.dev) { | ||
1347 | wacom_destroy_battery(wacom); | ||
1348 | } | ||
1349 | } | ||
1350 | |||
1316 | /* | 1351 | /* |
1317 | * Not all devices report physical dimensions from HID. | 1352 | * Not all devices report physical dimensions from HID. |
1318 | * Compute the default from hardcoded logical dimension | 1353 | * Compute the default from hardcoded logical dimension |
@@ -1373,6 +1408,9 @@ static int wacom_probe(struct hid_device *hdev, | |||
1373 | 1408 | ||
1374 | hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; | 1409 | hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; |
1375 | 1410 | ||
1411 | /* hid-core sets this quirk for the boot interface */ | ||
1412 | hdev->quirks &= ~HID_QUIRK_NOGET; | ||
1413 | |||
1376 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | 1414 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); |
1377 | if (!wacom) | 1415 | if (!wacom) |
1378 | return -ENOMEM; | 1416 | return -ENOMEM; |
@@ -1412,6 +1450,21 @@ static int wacom_probe(struct hid_device *hdev, | |||
1412 | goto fail_allocate_inputs; | 1450 | goto fail_allocate_inputs; |
1413 | } | 1451 | } |
1414 | 1452 | ||
1453 | /* | ||
1454 | * Bamboo Pad has a generic hid handling for the Pen, and we switch it | ||
1455 | * into debug mode for the touch part. | ||
1456 | * We ignore the other interfaces. | ||
1457 | */ | ||
1458 | if (features->type == BAMBOO_PAD) { | ||
1459 | if (features->pktlen == WACOM_PKGLEN_PENABLED) { | ||
1460 | features->type = HID_GENERIC; | ||
1461 | } else if ((features->pktlen != WACOM_PKGLEN_BPAD_TOUCH) && | ||
1462 | (features->pktlen != WACOM_PKGLEN_BPAD_TOUCH_USB)) { | ||
1463 | error = -ENODEV; | ||
1464 | goto fail_shared_data; | ||
1465 | } | ||
1466 | } | ||
1467 | |||
1415 | /* set the default size in case we do not get them from hid */ | 1468 | /* set the default size in case we do not get them from hid */ |
1416 | wacom_set_default_phy(features); | 1469 | wacom_set_default_phy(features); |
1417 | 1470 | ||
@@ -1446,6 +1499,12 @@ static int wacom_probe(struct hid_device *hdev, | |||
1446 | features->y_max = 4096; | 1499 | features->y_max = 4096; |
1447 | } | 1500 | } |
1448 | 1501 | ||
1502 | /* | ||
1503 | * Same thing for Bamboo PAD | ||
1504 | */ | ||
1505 | if (features->type == BAMBOO_PAD) | ||
1506 | features->device_type = BTN_TOOL_FINGER; | ||
1507 | |||
1449 | if (hdev->bus == BUS_BLUETOOTH) | 1508 | if (hdev->bus == BUS_BLUETOOTH) |
1450 | features->quirks |= WACOM_QUIRK_BATTERY; | 1509 | features->quirks |= WACOM_QUIRK_BATTERY; |
1451 | 1510 | ||
@@ -1527,7 +1586,7 @@ fail_register_inputs: | |||
1527 | wacom_clean_inputs(wacom); | 1586 | wacom_clean_inputs(wacom); |
1528 | wacom_destroy_battery(wacom); | 1587 | wacom_destroy_battery(wacom); |
1529 | fail_battery: | 1588 | fail_battery: |
1530 | wacom_remove_shared_data(wacom_wac); | 1589 | wacom_remove_shared_data(wacom); |
1531 | fail_shared_data: | 1590 | fail_shared_data: |
1532 | wacom_clean_inputs(wacom); | 1591 | wacom_clean_inputs(wacom); |
1533 | fail_allocate_inputs: | 1592 | fail_allocate_inputs: |
@@ -1550,7 +1609,7 @@ static void wacom_remove(struct hid_device *hdev) | |||
1550 | if (hdev->bus == BUS_BLUETOOTH) | 1609 | if (hdev->bus == BUS_BLUETOOTH) |
1551 | device_remove_file(&hdev->dev, &dev_attr_speed); | 1610 | device_remove_file(&hdev->dev, &dev_attr_speed); |
1552 | wacom_destroy_battery(wacom); | 1611 | wacom_destroy_battery(wacom); |
1553 | wacom_remove_shared_data(&wacom->wacom_wac); | 1612 | wacom_remove_shared_data(wacom); |
1554 | 1613 | ||
1555 | hid_set_drvdata(hdev, NULL); | 1614 | hid_set_drvdata(hdev, NULL); |
1556 | kfree(wacom); | 1615 | kfree(wacom); |
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index bbe32d66e500..fa0578ecd7a1 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
@@ -45,6 +45,27 @@ static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 }; | |||
45 | */ | 45 | */ |
46 | static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; | 46 | static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; |
47 | 47 | ||
48 | static void wacom_notify_battery(struct wacom_wac *wacom_wac, | ||
49 | int bat_capacity, bool bat_charging, bool bat_connected, | ||
50 | bool ps_connected) | ||
51 | { | ||
52 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
53 | bool changed = wacom_wac->battery_capacity != bat_capacity || | ||
54 | wacom_wac->bat_charging != bat_charging || | ||
55 | wacom_wac->bat_connected != bat_connected || | ||
56 | wacom_wac->ps_connected != ps_connected; | ||
57 | |||
58 | if (changed) { | ||
59 | wacom_wac->battery_capacity = bat_capacity; | ||
60 | wacom_wac->bat_charging = bat_charging; | ||
61 | wacom_wac->bat_connected = bat_connected; | ||
62 | wacom_wac->ps_connected = ps_connected; | ||
63 | |||
64 | if (wacom->battery.dev) | ||
65 | power_supply_changed(&wacom->battery); | ||
66 | } | ||
67 | } | ||
68 | |||
48 | static int wacom_penpartner_irq(struct wacom_wac *wacom) | 69 | static int wacom_penpartner_irq(struct wacom_wac *wacom) |
49 | { | 70 | { |
50 | unsigned char *data = wacom->data; | 71 | unsigned char *data = wacom->data; |
@@ -419,17 +440,26 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) | |||
419 | rw = (data[7] >> 2 & 0x07); | 440 | rw = (data[7] >> 2 & 0x07); |
420 | battery_capacity = batcap_gr[rw]; | 441 | battery_capacity = batcap_gr[rw]; |
421 | ps_connected = rw == 7; | 442 | ps_connected = rw == 7; |
422 | if ((wacom->battery_capacity != battery_capacity) || | 443 | wacom_notify_battery(wacom, battery_capacity, ps_connected, |
423 | (wacom->ps_connected != ps_connected)) { | 444 | 1, ps_connected); |
424 | wacom->battery_capacity = battery_capacity; | ||
425 | wacom->ps_connected = ps_connected; | ||
426 | wacom_notify_battery(wacom); | ||
427 | } | ||
428 | } | 445 | } |
429 | exit: | 446 | exit: |
430 | return retval; | 447 | return retval; |
431 | } | 448 | } |
432 | 449 | ||
450 | static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac) | ||
451 | { | ||
452 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
453 | struct hid_report *r; | ||
454 | struct hid_report_enum *re; | ||
455 | |||
456 | re = &(wacom->hdev->report_enum[HID_FEATURE_REPORT]); | ||
457 | r = re->report_id_hash[WACOM_REPORT_INTUOSREAD]; | ||
458 | if (r) { | ||
459 | hid_hw_request(wacom->hdev, r, HID_REQ_GET_REPORT); | ||
460 | } | ||
461 | } | ||
462 | |||
433 | static int wacom_intuos_inout(struct wacom_wac *wacom) | 463 | static int wacom_intuos_inout(struct wacom_wac *wacom) |
434 | { | 464 | { |
435 | struct wacom_features *features = &wacom->features; | 465 | struct wacom_features *features = &wacom->features; |
@@ -610,8 +640,11 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
610 | } | 640 | } |
611 | 641 | ||
612 | /* don't report other events if we don't know the ID */ | 642 | /* don't report other events if we don't know the ID */ |
613 | if (!wacom->id[idx]) | 643 | if (!wacom->id[idx]) { |
644 | /* but reschedule a read of the current tool */ | ||
645 | wacom_intuos_schedule_prox_event(wacom); | ||
614 | return 1; | 646 | return 1; |
647 | } | ||
615 | 648 | ||
616 | return 0; | 649 | return 0; |
617 | } | 650 | } |
@@ -1023,15 +1056,9 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len) | |||
1023 | bat_charging = (power_raw & 0x08) ? 1 : 0; | 1056 | bat_charging = (power_raw & 0x08) ? 1 : 0; |
1024 | ps_connected = (power_raw & 0x10) ? 1 : 0; | 1057 | ps_connected = (power_raw & 0x10) ? 1 : 0; |
1025 | battery_capacity = batcap_i4[power_raw & 0x07]; | 1058 | battery_capacity = batcap_i4[power_raw & 0x07]; |
1026 | if ((wacom->battery_capacity != battery_capacity) || | 1059 | wacom_notify_battery(wacom, battery_capacity, bat_charging, |
1027 | (wacom->bat_charging != bat_charging) || | 1060 | battery_capacity || bat_charging, |
1028 | (wacom->ps_connected != ps_connected)) { | 1061 | ps_connected); |
1029 | wacom->battery_capacity = battery_capacity; | ||
1030 | wacom->bat_charging = bat_charging; | ||
1031 | wacom->ps_connected = ps_connected; | ||
1032 | wacom_notify_battery(wacom); | ||
1033 | } | ||
1034 | |||
1035 | break; | 1062 | break; |
1036 | default: | 1063 | default: |
1037 | dev_dbg(wacom->input->dev.parent, | 1064 | dev_dbg(wacom->input->dev.parent, |
@@ -1104,7 +1131,7 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) | |||
1104 | contact_with_no_pen_down_count++; | 1131 | contact_with_no_pen_down_count++; |
1105 | } | 1132 | } |
1106 | } | 1133 | } |
1107 | input_mt_report_pointer_emulation(input, true); | 1134 | input_mt_sync_frame(input); |
1108 | 1135 | ||
1109 | wacom->num_contacts_left -= contacts_to_send; | 1136 | wacom->num_contacts_left -= contacts_to_send; |
1110 | if (wacom->num_contacts_left <= 0) { | 1137 | if (wacom->num_contacts_left <= 0) { |
@@ -1159,7 +1186,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom) | |||
1159 | contact_with_no_pen_down_count++; | 1186 | contact_with_no_pen_down_count++; |
1160 | } | 1187 | } |
1161 | } | 1188 | } |
1162 | input_mt_report_pointer_emulation(input, true); | 1189 | input_mt_sync_frame(input); |
1163 | 1190 | ||
1164 | wacom->num_contacts_left -= contacts_to_send; | 1191 | wacom->num_contacts_left -= contacts_to_send; |
1165 | if (wacom->num_contacts_left <= 0) { | 1192 | if (wacom->num_contacts_left <= 0) { |
@@ -1191,7 +1218,7 @@ static int wacom_tpc_mt_touch(struct wacom_wac *wacom) | |||
1191 | contact_with_no_pen_down_count++; | 1218 | contact_with_no_pen_down_count++; |
1192 | } | 1219 | } |
1193 | } | 1220 | } |
1194 | input_mt_report_pointer_emulation(input, true); | 1221 | input_mt_sync_frame(input); |
1195 | 1222 | ||
1196 | /* keep touch state for pen event */ | 1223 | /* keep touch state for pen event */ |
1197 | wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); | 1224 | wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); |
@@ -1651,7 +1678,7 @@ static int wacom_bpt_touch(struct wacom_wac *wacom) | |||
1651 | } | 1678 | } |
1652 | } | 1679 | } |
1653 | 1680 | ||
1654 | input_mt_report_pointer_emulation(input, true); | 1681 | input_mt_sync_frame(input); |
1655 | 1682 | ||
1656 | input_report_key(pad_input, BTN_LEFT, (data[1] & 0x08) != 0); | 1683 | input_report_key(pad_input, BTN_LEFT, (data[1] & 0x08) != 0); |
1657 | input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0); | 1684 | input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0); |
@@ -1747,7 +1774,7 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom) | |||
1747 | wacom_bpt3_button_msg(wacom, data + offset); | 1774 | wacom_bpt3_button_msg(wacom, data + offset); |
1748 | 1775 | ||
1749 | } | 1776 | } |
1750 | input_mt_report_pointer_emulation(input, true); | 1777 | input_mt_sync_frame(input); |
1751 | wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); | 1778 | wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); |
1752 | 1779 | ||
1753 | return 1; | 1780 | return 1; |
@@ -1760,20 +1787,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) | |||
1760 | unsigned char *data = wacom->data; | 1787 | unsigned char *data = wacom->data; |
1761 | int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; | 1788 | int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; |
1762 | 1789 | ||
1763 | if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_USB) | 1790 | if (data[0] != WACOM_REPORT_PENABLED) |
1764 | return 0; | 1791 | return 0; |
1765 | 1792 | ||
1766 | if (data[0] == WACOM_REPORT_USB) { | ||
1767 | if (features->type == INTUOSHT && | ||
1768 | wacom->shared->touch_input && | ||
1769 | features->touch_max) { | ||
1770 | input_report_switch(wacom->shared->touch_input, | ||
1771 | SW_MUTE_DEVICE, data[8] & 0x40); | ||
1772 | input_sync(wacom->shared->touch_input); | ||
1773 | } | ||
1774 | return 0; | ||
1775 | } | ||
1776 | |||
1777 | if (wacom->shared->touch_down) | 1793 | if (wacom->shared->touch_down) |
1778 | return 0; | 1794 | return 0; |
1779 | 1795 | ||
@@ -1849,6 +1865,91 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len) | |||
1849 | return 0; | 1865 | return 0; |
1850 | } | 1866 | } |
1851 | 1867 | ||
1868 | static void wacom_bamboo_pad_pen_event(struct wacom_wac *wacom, | ||
1869 | unsigned char *data) | ||
1870 | { | ||
1871 | unsigned char prefix; | ||
1872 | |||
1873 | /* | ||
1874 | * We need to reroute the event from the debug interface to the | ||
1875 | * pen interface. | ||
1876 | * We need to add the report ID to the actual pen report, so we | ||
1877 | * temporary overwrite the first byte to prevent having to kzalloc/kfree | ||
1878 | * and memcpy the report. | ||
1879 | */ | ||
1880 | prefix = data[0]; | ||
1881 | data[0] = WACOM_REPORT_BPAD_PEN; | ||
1882 | |||
1883 | /* | ||
1884 | * actually reroute the event. | ||
1885 | * No need to check if wacom->shared->pen is valid, hid_input_report() | ||
1886 | * will check for us. | ||
1887 | */ | ||
1888 | hid_input_report(wacom->shared->pen, HID_INPUT_REPORT, data, | ||
1889 | WACOM_PKGLEN_PENABLED, 1); | ||
1890 | |||
1891 | data[0] = prefix; | ||
1892 | } | ||
1893 | |||
1894 | static int wacom_bamboo_pad_touch_event(struct wacom_wac *wacom, | ||
1895 | unsigned char *data) | ||
1896 | { | ||
1897 | struct input_dev *input = wacom->input; | ||
1898 | unsigned char *finger_data, prefix; | ||
1899 | unsigned id; | ||
1900 | int x, y; | ||
1901 | bool valid; | ||
1902 | |||
1903 | prefix = data[0]; | ||
1904 | |||
1905 | for (id = 0; id < wacom->features.touch_max; id++) { | ||
1906 | valid = !!(prefix & BIT(id)) && | ||
1907 | !wacom->shared->stylus_in_proximity; | ||
1908 | |||
1909 | input_mt_slot(input, id); | ||
1910 | input_mt_report_slot_state(input, MT_TOOL_FINGER, valid); | ||
1911 | |||
1912 | if (!valid) | ||
1913 | continue; | ||
1914 | |||
1915 | finger_data = data + 1 + id * 3; | ||
1916 | x = finger_data[0] | ((finger_data[1] & 0x0f) << 8); | ||
1917 | y = (finger_data[2] << 4) | (finger_data[1] >> 4); | ||
1918 | |||
1919 | input_report_abs(input, ABS_MT_POSITION_X, x); | ||
1920 | input_report_abs(input, ABS_MT_POSITION_Y, y); | ||
1921 | } | ||
1922 | |||
1923 | input_mt_sync_frame(input); | ||
1924 | |||
1925 | input_report_key(input, BTN_LEFT, prefix & 0x40); | ||
1926 | input_report_key(input, BTN_RIGHT, prefix & 0x80); | ||
1927 | |||
1928 | /* keep touch state for pen event */ | ||
1929 | wacom->shared->touch_down = !!prefix && | ||
1930 | !wacom->shared->stylus_in_proximity; | ||
1931 | |||
1932 | return 1; | ||
1933 | } | ||
1934 | |||
1935 | static int wacom_bamboo_pad_irq(struct wacom_wac *wacom, size_t len) | ||
1936 | { | ||
1937 | unsigned char *data = wacom->data; | ||
1938 | |||
1939 | if (!((len == WACOM_PKGLEN_BPAD_TOUCH) || | ||
1940 | (len == WACOM_PKGLEN_BPAD_TOUCH_USB)) || | ||
1941 | (data[0] != WACOM_REPORT_BPAD_TOUCH)) | ||
1942 | return 0; | ||
1943 | |||
1944 | if (data[1] & 0x01) | ||
1945 | wacom_bamboo_pad_pen_event(wacom, &data[1]); | ||
1946 | |||
1947 | if (data[1] & 0x02) | ||
1948 | return wacom_bamboo_pad_touch_event(wacom, &data[9]); | ||
1949 | |||
1950 | return 0; | ||
1951 | } | ||
1952 | |||
1852 | static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) | 1953 | static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) |
1853 | { | 1954 | { |
1854 | unsigned char *data = wacom->data; | 1955 | unsigned char *data = wacom->data; |
@@ -1859,7 +1960,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) | |||
1859 | 1960 | ||
1860 | connected = data[1] & 0x01; | 1961 | connected = data[1] & 0x01; |
1861 | if (connected) { | 1962 | if (connected) { |
1862 | int pid, battery, ps_connected; | 1963 | int pid, battery, charging; |
1863 | 1964 | ||
1864 | if ((wacom->shared->type == INTUOSHT) && | 1965 | if ((wacom->shared->type == INTUOSHT) && |
1865 | wacom->shared->touch_input && | 1966 | wacom->shared->touch_input && |
@@ -1871,30 +1972,63 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) | |||
1871 | 1972 | ||
1872 | pid = get_unaligned_be16(&data[6]); | 1973 | pid = get_unaligned_be16(&data[6]); |
1873 | battery = (data[5] & 0x3f) * 100 / 31; | 1974 | battery = (data[5] & 0x3f) * 100 / 31; |
1874 | ps_connected = !!(data[5] & 0x80); | 1975 | charging = !!(data[5] & 0x80); |
1875 | if (wacom->pid != pid) { | 1976 | if (wacom->pid != pid) { |
1876 | wacom->pid = pid; | 1977 | wacom->pid = pid; |
1877 | wacom_schedule_work(wacom); | 1978 | wacom_schedule_work(wacom); |
1878 | } | 1979 | } |
1879 | 1980 | ||
1880 | if (wacom->shared->type && | 1981 | if (wacom->shared->type) |
1881 | (battery != wacom->battery_capacity || | 1982 | wacom_notify_battery(wacom, battery, charging, 1, 0); |
1882 | ps_connected != wacom->ps_connected)) { | 1983 | |
1883 | wacom->battery_capacity = battery; | ||
1884 | wacom->ps_connected = ps_connected; | ||
1885 | wacom->bat_charging = ps_connected && | ||
1886 | wacom->battery_capacity < 100; | ||
1887 | wacom_notify_battery(wacom); | ||
1888 | } | ||
1889 | } else if (wacom->pid != 0) { | 1984 | } else if (wacom->pid != 0) { |
1890 | /* disconnected while previously connected */ | 1985 | /* disconnected while previously connected */ |
1891 | wacom->pid = 0; | 1986 | wacom->pid = 0; |
1892 | wacom_schedule_work(wacom); | 1987 | wacom_schedule_work(wacom); |
1893 | wacom->battery_capacity = 0; | 1988 | wacom_notify_battery(wacom, 0, 0, 0, 0); |
1894 | wacom->bat_charging = 0; | 1989 | } |
1895 | wacom->ps_connected = 0; | 1990 | |
1991 | return 0; | ||
1992 | } | ||
1993 | |||
1994 | static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) | ||
1995 | { | ||
1996 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
1997 | struct wacom_features *features = &wacom_wac->features; | ||
1998 | unsigned char *data = wacom_wac->data; | ||
1999 | |||
2000 | if (data[0] != WACOM_REPORT_USB) | ||
2001 | return 0; | ||
2002 | |||
2003 | if (features->type == INTUOSHT && | ||
2004 | wacom_wac->shared->touch_input && | ||
2005 | features->touch_max) { | ||
2006 | input_report_switch(wacom_wac->shared->touch_input, | ||
2007 | SW_MUTE_DEVICE, data[8] & 0x40); | ||
2008 | input_sync(wacom_wac->shared->touch_input); | ||
1896 | } | 2009 | } |
1897 | 2010 | ||
2011 | if (data[9] & 0x02) { /* wireless module is attached */ | ||
2012 | int battery = (data[8] & 0x3f) * 100 / 31; | ||
2013 | bool charging = !!(data[8] & 0x80); | ||
2014 | |||
2015 | wacom_notify_battery(wacom_wac, battery, charging, | ||
2016 | battery || charging, 1); | ||
2017 | |||
2018 | if (!wacom->battery.dev && | ||
2019 | !(features->quirks & WACOM_QUIRK_BATTERY)) { | ||
2020 | features->quirks |= WACOM_QUIRK_BATTERY; | ||
2021 | INIT_WORK(&wacom->work, wacom_battery_work); | ||
2022 | wacom_schedule_work(wacom_wac); | ||
2023 | } | ||
2024 | } | ||
2025 | else if ((features->quirks & WACOM_QUIRK_BATTERY) && | ||
2026 | wacom->battery.dev) { | ||
2027 | features->quirks &= ~WACOM_QUIRK_BATTERY; | ||
2028 | INIT_WORK(&wacom->work, wacom_battery_work); | ||
2029 | wacom_schedule_work(wacom_wac); | ||
2030 | wacom_notify_battery(wacom_wac, 0, 0, 0, 0); | ||
2031 | } | ||
1898 | return 0; | 2032 | return 0; |
1899 | } | 2033 | } |
1900 | 2034 | ||
@@ -1967,6 +2101,8 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
1967 | case INTUOSPL: | 2101 | case INTUOSPL: |
1968 | if (len == WACOM_PKGLEN_BBTOUCH3) | 2102 | if (len == WACOM_PKGLEN_BBTOUCH3) |
1969 | sync = wacom_bpt3_touch(wacom_wac); | 2103 | sync = wacom_bpt3_touch(wacom_wac); |
2104 | else if (wacom_wac->data[0] == WACOM_REPORT_USB) | ||
2105 | sync = wacom_status_irq(wacom_wac, len); | ||
1970 | else | 2106 | else |
1971 | sync = wacom_intuos_irq(wacom_wac); | 2107 | sync = wacom_intuos_irq(wacom_wac); |
1972 | break; | 2108 | break; |
@@ -1982,7 +2118,14 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
1982 | 2118 | ||
1983 | case BAMBOO_PT: | 2119 | case BAMBOO_PT: |
1984 | case INTUOSHT: | 2120 | case INTUOSHT: |
1985 | sync = wacom_bpt_irq(wacom_wac, len); | 2121 | if (wacom_wac->data[0] == WACOM_REPORT_USB) |
2122 | sync = wacom_status_irq(wacom_wac, len); | ||
2123 | else | ||
2124 | sync = wacom_bpt_irq(wacom_wac, len); | ||
2125 | break; | ||
2126 | |||
2127 | case BAMBOO_PAD: | ||
2128 | sync = wacom_bamboo_pad_irq(wacom_wac, len); | ||
1986 | break; | 2129 | break; |
1987 | 2130 | ||
1988 | case WIRELESS: | 2131 | case WIRELESS: |
@@ -2323,6 +2466,13 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, | |||
2323 | 0, 0); | 2466 | 0, 0); |
2324 | } | 2467 | } |
2325 | break; | 2468 | break; |
2469 | case BAMBOO_PAD: | ||
2470 | __clear_bit(ABS_MISC, input_dev->absbit); | ||
2471 | input_mt_init_slots(input_dev, features->touch_max, | ||
2472 | INPUT_MT_POINTER); | ||
2473 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
2474 | __set_bit(BTN_RIGHT, input_dev->keybit); | ||
2475 | break; | ||
2326 | } | 2476 | } |
2327 | return 0; | 2477 | return 0; |
2328 | } | 2478 | } |
@@ -2976,6 +3126,12 @@ static const struct wacom_features wacom_features_0x30C = | |||
2976 | { "Wacom ISDv5 30C", .type = WACOM_24HDT, /* Touch */ | 3126 | { "Wacom ISDv5 30C", .type = WACOM_24HDT, /* Touch */ |
2977 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10, | 3127 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10, |
2978 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; | 3128 | .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; |
3129 | static const struct wacom_features wacom_features_0x318 = | ||
3130 | { "Wacom USB Bamboo PAD", 4095, 4095, /* Touch */ | ||
3131 | .type = BAMBOO_PAD, 35, 48, .touch_max = 4 }; | ||
3132 | static const struct wacom_features wacom_features_0x319 = | ||
3133 | { "Wacom Wireless Bamboo PAD", 4095, 4095, /* Touch */ | ||
3134 | .type = BAMBOO_PAD, 35, 48, .touch_max = 4 }; | ||
2979 | static const struct wacom_features wacom_features_0x323 = | 3135 | static const struct wacom_features wacom_features_0x323 = |
2980 | { "Wacom Intuos P M", 21600, 13500, 1023, 31, | 3136 | { "Wacom Intuos P M", 21600, 13500, 1023, 31, |
2981 | INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, | 3137 | INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
@@ -2992,6 +3148,10 @@ static const struct wacom_features wacom_features_HID_ANY_ID = | |||
2992 | HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ | 3148 | HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ |
2993 | .driver_data = (kernel_ulong_t)&wacom_features_##prod | 3149 | .driver_data = (kernel_ulong_t)&wacom_features_##prod |
2994 | 3150 | ||
3151 | #define I2C_DEVICE_WACOM(prod) \ | ||
3152 | HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ | ||
3153 | .driver_data = (kernel_ulong_t)&wacom_features_##prod | ||
3154 | |||
2995 | #define USB_DEVICE_LENOVO(prod) \ | 3155 | #define USB_DEVICE_LENOVO(prod) \ |
2996 | HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \ | 3156 | HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \ |
2997 | .driver_data = (kernel_ulong_t)&wacom_features_##prod | 3157 | .driver_data = (kernel_ulong_t)&wacom_features_##prod |
@@ -3124,6 +3284,8 @@ const struct hid_device_id wacom_ids[] = { | |||
3124 | { USB_DEVICE_WACOM(0x314) }, | 3284 | { USB_DEVICE_WACOM(0x314) }, |
3125 | { USB_DEVICE_WACOM(0x315) }, | 3285 | { USB_DEVICE_WACOM(0x315) }, |
3126 | { USB_DEVICE_WACOM(0x317) }, | 3286 | { USB_DEVICE_WACOM(0x317) }, |
3287 | { USB_DEVICE_WACOM(0x318) }, | ||
3288 | { USB_DEVICE_WACOM(0x319) }, | ||
3127 | { USB_DEVICE_WACOM(0x323) }, | 3289 | { USB_DEVICE_WACOM(0x323) }, |
3128 | { USB_DEVICE_WACOM(0x32A) }, | 3290 | { USB_DEVICE_WACOM(0x32A) }, |
3129 | { USB_DEVICE_WACOM(0x32B) }, | 3291 | { USB_DEVICE_WACOM(0x32B) }, |
@@ -3136,6 +3298,7 @@ const struct hid_device_id wacom_ids[] = { | |||
3136 | { USB_DEVICE_LENOVO(0x6004) }, | 3298 | { USB_DEVICE_LENOVO(0x6004) }, |
3137 | 3299 | ||
3138 | { USB_DEVICE_WACOM(HID_ANY_ID) }, | 3300 | { USB_DEVICE_WACOM(HID_ANY_ID) }, |
3301 | { I2C_DEVICE_WACOM(HID_ANY_ID) }, | ||
3139 | { } | 3302 | { } |
3140 | }; | 3303 | }; |
3141 | MODULE_DEVICE_TABLE(hid, wacom_ids); | 3304 | MODULE_DEVICE_TABLE(hid, wacom_ids); |
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 021ee1c1980a..1c7d8931f1fa 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h | |||
@@ -33,6 +33,8 @@ | |||
33 | #define WACOM_PKGLEN_MTTPC 40 | 33 | #define WACOM_PKGLEN_MTTPC 40 |
34 | #define WACOM_PKGLEN_DTUS 68 | 34 | #define WACOM_PKGLEN_DTUS 68 |
35 | #define WACOM_PKGLEN_PENABLED 8 | 35 | #define WACOM_PKGLEN_PENABLED 8 |
36 | #define WACOM_PKGLEN_BPAD_TOUCH 32 | ||
37 | #define WACOM_PKGLEN_BPAD_TOUCH_USB 64 | ||
36 | 38 | ||
37 | /* wacom data size per MT contact */ | 39 | /* wacom data size per MT contact */ |
38 | #define WACOM_BYTES_PER_MT_PACKET 11 | 40 | #define WACOM_BYTES_PER_MT_PACKET 11 |
@@ -67,6 +69,8 @@ | |||
67 | #define WACOM_REPORT_24HDT 1 | 69 | #define WACOM_REPORT_24HDT 1 |
68 | #define WACOM_REPORT_WL 128 | 70 | #define WACOM_REPORT_WL 128 |
69 | #define WACOM_REPORT_USB 192 | 71 | #define WACOM_REPORT_USB 192 |
72 | #define WACOM_REPORT_BPAD_PEN 3 | ||
73 | #define WACOM_REPORT_BPAD_TOUCH 16 | ||
70 | 74 | ||
71 | /* device quirks */ | 75 | /* device quirks */ |
72 | #define WACOM_QUIRK_MULTI_INPUT 0x0001 | 76 | #define WACOM_QUIRK_MULTI_INPUT 0x0001 |
@@ -122,6 +126,7 @@ enum { | |||
122 | BAMBOO_PT, | 126 | BAMBOO_PT, |
123 | WACOM_24HDT, | 127 | WACOM_24HDT, |
124 | WACOM_27QHDT, | 128 | WACOM_27QHDT, |
129 | BAMBOO_PAD, | ||
125 | TABLETPC, /* add new TPC below */ | 130 | TABLETPC, /* add new TPC below */ |
126 | TABLETPCE, | 131 | TABLETPCE, |
127 | TABLETPC2FG, | 132 | TABLETPC2FG, |
@@ -169,6 +174,8 @@ struct wacom_shared { | |||
169 | unsigned touch_max; | 174 | unsigned touch_max; |
170 | int type; | 175 | int type; |
171 | struct input_dev *touch_input; | 176 | struct input_dev *touch_input; |
177 | struct hid_device *pen; | ||
178 | struct hid_device *touch; | ||
172 | }; | 179 | }; |
173 | 180 | ||
174 | struct hid_data { | 181 | struct hid_data { |
@@ -205,6 +212,7 @@ struct wacom_wac { | |||
205 | int battery_capacity; | 212 | int battery_capacity; |
206 | int num_contacts_left; | 213 | int num_contacts_left; |
207 | int bat_charging; | 214 | int bat_charging; |
215 | int bat_connected; | ||
208 | int ps_connected; | 216 | int ps_connected; |
209 | u8 bt_features; | 217 | u8 bt_features; |
210 | u8 bt_high_speed; | 218 | u8 bt_high_speed; |