.. | .. |
---|
11 | 11 | #include "wacom_wac.h" |
---|
12 | 12 | #include "wacom.h" |
---|
13 | 13 | #include <linux/input/mt.h> |
---|
| 14 | +#include <linux/jiffies.h> |
---|
14 | 15 | |
---|
15 | 16 | /* resolution for penabled devices */ |
---|
16 | 17 | #define WACOM_PL_RES 20 |
---|
.. | .. |
---|
41 | 42 | |
---|
42 | 43 | static void wacom_update_led(struct wacom *wacom, int button_count, int mask, |
---|
43 | 44 | int group); |
---|
| 45 | + |
---|
| 46 | +static void wacom_force_proxout(struct wacom_wac *wacom_wac) |
---|
| 47 | +{ |
---|
| 48 | + struct input_dev *input = wacom_wac->pen_input; |
---|
| 49 | + |
---|
| 50 | + wacom_wac->shared->stylus_in_proximity = 0; |
---|
| 51 | + |
---|
| 52 | + input_report_key(input, BTN_TOUCH, 0); |
---|
| 53 | + input_report_key(input, BTN_STYLUS, 0); |
---|
| 54 | + input_report_key(input, BTN_STYLUS2, 0); |
---|
| 55 | + input_report_key(input, BTN_STYLUS3, 0); |
---|
| 56 | + input_report_key(input, wacom_wac->tool[0], 0); |
---|
| 57 | + if (wacom_wac->serial[0]) { |
---|
| 58 | + input_report_abs(input, ABS_MISC, 0); |
---|
| 59 | + } |
---|
| 60 | + input_report_abs(input, ABS_PRESSURE, 0); |
---|
| 61 | + |
---|
| 62 | + wacom_wac->tool[0] = 0; |
---|
| 63 | + wacom_wac->id[0] = 0; |
---|
| 64 | + wacom_wac->serial[0] = 0; |
---|
| 65 | + |
---|
| 66 | + input_sync(input); |
---|
| 67 | +} |
---|
| 68 | + |
---|
| 69 | +void wacom_idleprox_timeout(struct timer_list *list) |
---|
| 70 | +{ |
---|
| 71 | + struct wacom *wacom = from_timer(wacom, list, idleprox_timer); |
---|
| 72 | + struct wacom_wac *wacom_wac = &wacom->wacom_wac; |
---|
| 73 | + |
---|
| 74 | + if (!wacom_wac->hid_data.sense_state) { |
---|
| 75 | + return; |
---|
| 76 | + } |
---|
| 77 | + |
---|
| 78 | + hid_warn(wacom->hdev, "%s: tool appears to be hung in-prox. forcing it out.\n", __func__); |
---|
| 79 | + wacom_force_proxout(wacom_wac); |
---|
| 80 | +} |
---|
| 81 | + |
---|
44 | 82 | /* |
---|
45 | 83 | * Percent of battery capacity for Graphire. |
---|
46 | 84 | * 8th value means AC online and show 100% capacity. |
---|
.. | .. |
---|
675 | 713 | case 0x802: /* Intuos4/5 13HD/24HD General Pen */ |
---|
676 | 714 | case 0x8e2: /* IntuosHT2 pen */ |
---|
677 | 715 | case 0x022: |
---|
| 716 | + case 0x200: /* Pro Pen 3 */ |
---|
| 717 | + case 0x04200: /* Pro Pen 3 */ |
---|
678 | 718 | case 0x10842: /* MobileStudio Pro Pro Pen slim */ |
---|
679 | 719 | case 0x14802: /* Intuos4/5 13HD/24HD Classic Pen */ |
---|
680 | 720 | case 0x16802: /* Cintiq 13HD Pro Pen */ |
---|
681 | 721 | case 0x18802: /* DTH2242 Pen */ |
---|
682 | 722 | case 0x10802: /* Intuos4/5 13HD/24HD General Pen */ |
---|
| 723 | + case 0x80842: /* Intuos Pro and Cintiq Pro 3D Pen */ |
---|
683 | 724 | tool_type = BTN_TOOL_PEN; |
---|
684 | 725 | break; |
---|
685 | 726 | |
---|
.. | .. |
---|
790 | 831 | /* Enter report */ |
---|
791 | 832 | if ((data[1] & 0xfc) == 0xc0) { |
---|
792 | 833 | /* serial number of the tool */ |
---|
793 | | - wacom->serial[idx] = ((data[3] & 0x0f) << 28) + |
---|
| 834 | + wacom->serial[idx] = ((__u64)(data[3] & 0x0f) << 28) + |
---|
794 | 835 | (data[4] << 20) + (data[5] << 12) + |
---|
795 | 836 | (data[6] << 4) + (data[7] >> 4); |
---|
796 | 837 | |
---|
.. | .. |
---|
1086 | 1127 | if (index < 0 || !remote->remotes[index].registered) |
---|
1087 | 1128 | goto out; |
---|
1088 | 1129 | |
---|
| 1130 | + remote->remotes[i].active_time = ktime_get(); |
---|
1089 | 1131 | input = remote->remotes[index].input; |
---|
1090 | 1132 | |
---|
1091 | 1133 | input_report_key(input, BTN_0, (data[9] & 0x01)); |
---|
.. | .. |
---|
1265 | 1307 | |
---|
1266 | 1308 | struct input_dev *pen_input = wacom->pen_input; |
---|
1267 | 1309 | unsigned char *data = wacom->data; |
---|
| 1310 | + int number_of_valid_frames = 0; |
---|
| 1311 | + ktime_t time_interval = 15000000; |
---|
| 1312 | + ktime_t time_packet_received = ktime_get(); |
---|
1268 | 1313 | int i; |
---|
1269 | 1314 | |
---|
1270 | 1315 | if (wacom->features.type == INTUOSP2_BT || |
---|
.. | .. |
---|
1285 | 1330 | wacom->id[0] |= (wacom->serial[0] >> 32) & 0xFFFFF; |
---|
1286 | 1331 | } |
---|
1287 | 1332 | |
---|
| 1333 | + /* number of valid frames */ |
---|
1288 | 1334 | for (i = 0; i < pen_frames; i++) { |
---|
| 1335 | + unsigned char *frame = &data[i*pen_frame_len + 1]; |
---|
| 1336 | + bool valid = frame[0] & 0x80; |
---|
| 1337 | + |
---|
| 1338 | + if (valid) |
---|
| 1339 | + number_of_valid_frames++; |
---|
| 1340 | + } |
---|
| 1341 | + |
---|
| 1342 | + if (number_of_valid_frames) { |
---|
| 1343 | + if (wacom->hid_data.time_delayed) |
---|
| 1344 | + time_interval = ktime_get() - wacom->hid_data.time_delayed; |
---|
| 1345 | + time_interval = div_u64(time_interval, number_of_valid_frames); |
---|
| 1346 | + wacom->hid_data.time_delayed = time_packet_received; |
---|
| 1347 | + } |
---|
| 1348 | + |
---|
| 1349 | + for (i = 0; i < number_of_valid_frames; i++) { |
---|
1289 | 1350 | unsigned char *frame = &data[i*pen_frame_len + 1]; |
---|
1290 | 1351 | bool valid = frame[0] & 0x80; |
---|
1291 | 1352 | bool prox = frame[0] & 0x40; |
---|
1292 | 1353 | bool range = frame[0] & 0x20; |
---|
1293 | 1354 | bool invert = frame[0] & 0x10; |
---|
| 1355 | + int frames_number_reversed = number_of_valid_frames - i - 1; |
---|
| 1356 | + ktime_t event_timestamp = time_packet_received - frames_number_reversed * time_interval; |
---|
1294 | 1357 | |
---|
1295 | 1358 | if (!valid) |
---|
1296 | 1359 | continue; |
---|
.. | .. |
---|
1303 | 1366 | wacom->tool[0] = 0; |
---|
1304 | 1367 | wacom->id[0] = 0; |
---|
1305 | 1368 | wacom->serial[0] = 0; |
---|
| 1369 | + wacom->hid_data.time_delayed = 0; |
---|
1306 | 1370 | return; |
---|
1307 | 1371 | } |
---|
1308 | 1372 | |
---|
.. | .. |
---|
1339 | 1403 | get_unaligned_le16(&frame[11])); |
---|
1340 | 1404 | } |
---|
1341 | 1405 | } |
---|
| 1406 | + |
---|
1342 | 1407 | if (wacom->tool[0]) { |
---|
1343 | 1408 | input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); |
---|
1344 | 1409 | if (wacom->features.type == INTUOSP2_BT || |
---|
.. | .. |
---|
1361 | 1426 | } |
---|
1362 | 1427 | |
---|
1363 | 1428 | wacom->shared->stylus_in_proximity = prox; |
---|
| 1429 | + |
---|
| 1430 | + /* add timestamp to unpack the frames */ |
---|
| 1431 | + input_set_timestamp(pen_input, event_timestamp); |
---|
1364 | 1432 | |
---|
1365 | 1433 | input_sync(pen_input); |
---|
1366 | 1434 | } |
---|
.. | .. |
---|
1853 | 1921 | int fmax = field->logical_maximum; |
---|
1854 | 1922 | unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid); |
---|
1855 | 1923 | int resolution_code = code; |
---|
| 1924 | + int resolution = hidinput_calc_abs_res(field, resolution_code); |
---|
1856 | 1925 | |
---|
1857 | 1926 | if (equivalent_usage == HID_DG_TWIST) { |
---|
1858 | 1927 | resolution_code = ABS_RZ; |
---|
.. | .. |
---|
1875 | 1944 | switch (type) { |
---|
1876 | 1945 | case EV_ABS: |
---|
1877 | 1946 | input_set_abs_params(input, code, fmin, fmax, fuzz, 0); |
---|
1878 | | - input_abs_set_res(input, code, |
---|
1879 | | - hidinput_calc_abs_res(field, resolution_code)); |
---|
| 1947 | + |
---|
| 1948 | + /* older tablet may miss physical usage */ |
---|
| 1949 | + if ((code == ABS_X || code == ABS_Y) && !resolution) { |
---|
| 1950 | + resolution = WACOM_INTUOS_RES; |
---|
| 1951 | + hid_warn(input, |
---|
| 1952 | + "Wacom usage (%d) missing resolution \n", |
---|
| 1953 | + code); |
---|
| 1954 | + } |
---|
| 1955 | + input_abs_set_res(input, code, resolution); |
---|
1880 | 1956 | break; |
---|
1881 | 1957 | case EV_KEY: |
---|
1882 | 1958 | input_set_capability(input, EV_KEY, code); |
---|
.. | .. |
---|
1893 | 1969 | static void wacom_wac_battery_usage_mapping(struct hid_device *hdev, |
---|
1894 | 1970 | struct hid_field *field, struct hid_usage *usage) |
---|
1895 | 1971 | { |
---|
1896 | | - struct wacom *wacom = hid_get_drvdata(hdev); |
---|
1897 | | - struct wacom_wac *wacom_wac = &wacom->wacom_wac; |
---|
1898 | | - struct wacom_features *features = &wacom_wac->features; |
---|
1899 | | - unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); |
---|
1900 | | - |
---|
1901 | | - switch (equivalent_usage) { |
---|
1902 | | - case HID_DG_BATTERYSTRENGTH: |
---|
1903 | | - case WACOM_HID_WD_BATTERY_LEVEL: |
---|
1904 | | - case WACOM_HID_WD_BATTERY_CHARGING: |
---|
1905 | | - features->quirks |= WACOM_QUIRK_BATTERY; |
---|
1906 | | - break; |
---|
1907 | | - } |
---|
| 1972 | + return; |
---|
1908 | 1973 | } |
---|
1909 | 1974 | |
---|
1910 | 1975 | static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *field, |
---|
.. | .. |
---|
1925 | 1990 | wacom_wac->hid_data.bat_connected = 1; |
---|
1926 | 1991 | wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; |
---|
1927 | 1992 | } |
---|
| 1993 | + wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY; |
---|
1928 | 1994 | break; |
---|
1929 | 1995 | case WACOM_HID_WD_BATTERY_LEVEL: |
---|
1930 | 1996 | value = value * 100 / (field->logical_maximum - field->logical_minimum); |
---|
1931 | 1997 | wacom_wac->hid_data.battery_capacity = value; |
---|
1932 | 1998 | wacom_wac->hid_data.bat_connected = 1; |
---|
1933 | 1999 | wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; |
---|
| 2000 | + wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY; |
---|
1934 | 2001 | break; |
---|
1935 | 2002 | case WACOM_HID_WD_BATTERY_CHARGING: |
---|
1936 | 2003 | wacom_wac->hid_data.bat_charging = value; |
---|
1937 | 2004 | wacom_wac->hid_data.ps_connected = value; |
---|
1938 | 2005 | wacom_wac->hid_data.bat_connected = 1; |
---|
1939 | 2006 | wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; |
---|
| 2007 | + wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY; |
---|
1940 | 2008 | break; |
---|
1941 | 2009 | } |
---|
1942 | 2010 | } |
---|
.. | .. |
---|
1952 | 2020 | { |
---|
1953 | 2021 | struct wacom *wacom = hid_get_drvdata(hdev); |
---|
1954 | 2022 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; |
---|
1955 | | - struct wacom_features *features = &wacom_wac->features; |
---|
1956 | 2023 | |
---|
1957 | | - if (features->quirks & WACOM_QUIRK_BATTERY) { |
---|
1958 | | - int status = wacom_wac->hid_data.bat_status; |
---|
1959 | | - int capacity = wacom_wac->hid_data.battery_capacity; |
---|
1960 | | - bool charging = wacom_wac->hid_data.bat_charging; |
---|
1961 | | - bool connected = wacom_wac->hid_data.bat_connected; |
---|
1962 | | - bool powered = wacom_wac->hid_data.ps_connected; |
---|
| 2024 | + int status = wacom_wac->hid_data.bat_status; |
---|
| 2025 | + int capacity = wacom_wac->hid_data.battery_capacity; |
---|
| 2026 | + bool charging = wacom_wac->hid_data.bat_charging; |
---|
| 2027 | + bool connected = wacom_wac->hid_data.bat_connected; |
---|
| 2028 | + bool powered = wacom_wac->hid_data.ps_connected; |
---|
1963 | 2029 | |
---|
1964 | | - wacom_notify_battery(wacom_wac, status, capacity, charging, |
---|
1965 | | - connected, powered); |
---|
1966 | | - } |
---|
| 2030 | + wacom_notify_battery(wacom_wac, status, capacity, charging, |
---|
| 2031 | + connected, powered); |
---|
1967 | 2032 | } |
---|
1968 | 2033 | |
---|
1969 | 2034 | static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, |
---|
.. | .. |
---|
2305 | 2370 | value = field->logical_maximum - value; |
---|
2306 | 2371 | break; |
---|
2307 | 2372 | case HID_DG_INRANGE: |
---|
| 2373 | + mod_timer(&wacom->idleprox_timer, jiffies + msecs_to_jiffies(100)); |
---|
2308 | 2374 | wacom_wac->hid_data.inrange_state = value; |
---|
2309 | 2375 | if (!(features->quirks & WACOM_QUIRK_SENSE)) |
---|
2310 | 2376 | wacom_wac->hid_data.sense_state = value; |
---|
.. | .. |
---|
4778 | 4844 | static const struct wacom_features wacom_features_0x3c8 = |
---|
4779 | 4845 | { "Wacom Intuos BT M", 21600, 13500, 4095, 63, |
---|
4780 | 4846 | INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 }; |
---|
| 4847 | +static const struct wacom_features wacom_features_0x3dd = |
---|
| 4848 | + { "Wacom Intuos Pro S", 31920, 19950, 8191, 63, |
---|
| 4849 | + INTUOSP2S_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, |
---|
| 4850 | + .touch_max = 10 }; |
---|
4781 | 4851 | |
---|
4782 | 4852 | static const struct wacom_features wacom_features_HID_ANY_ID = |
---|
4783 | 4853 | { "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID }; |
---|
| 4854 | + |
---|
| 4855 | +static const struct wacom_features wacom_features_0x94 = |
---|
| 4856 | + { "Wacom Bootloader", .type = BOOTLOADER }; |
---|
4784 | 4857 | |
---|
4785 | 4858 | #define USB_DEVICE_WACOM(prod) \ |
---|
4786 | 4859 | HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ |
---|
.. | .. |
---|
4855 | 4928 | { USB_DEVICE_WACOM(0x84) }, |
---|
4856 | 4929 | { USB_DEVICE_WACOM(0x90) }, |
---|
4857 | 4930 | { USB_DEVICE_WACOM(0x93) }, |
---|
| 4931 | + { USB_DEVICE_WACOM(0x94) }, |
---|
4858 | 4932 | { USB_DEVICE_WACOM(0x97) }, |
---|
4859 | 4933 | { USB_DEVICE_WACOM(0x9A) }, |
---|
4860 | 4934 | { USB_DEVICE_WACOM(0x9F) }, |
---|
.. | .. |
---|
4953 | 5027 | { BT_DEVICE_WACOM(0x393) }, |
---|
4954 | 5028 | { BT_DEVICE_WACOM(0x3c6) }, |
---|
4955 | 5029 | { BT_DEVICE_WACOM(0x3c8) }, |
---|
| 5030 | + { BT_DEVICE_WACOM(0x3dd) }, |
---|
4956 | 5031 | { USB_DEVICE_WACOM(0x4001) }, |
---|
4957 | 5032 | { USB_DEVICE_WACOM(0x4004) }, |
---|
4958 | 5033 | { USB_DEVICE_WACOM(0x5000) }, |
---|