diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2014-08-06 16:55:56 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-08-06 18:14:34 -0400 |
commit | 81af7e61a774e687ed4a7f37992ef75da57c5ddf (patch) | |
tree | 6cb88940d854b69455876f0185105a91f130fac3 /drivers/hid | |
parent | 387142bb8fcb263771e1fa6b1a96e6a7ca36e820 (diff) |
Input: wacom - handle Intuos 4 BT in wacom.ko
A good point of this change is that now, the Intuos4 bluetooth can handle
the different tools (artpen, airbrush, mice), and we get a common interface
between USB and BT for accessing the LEDs/OLEDs.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Reviewed-by: Ping Cheng <pingc@wacom.com>
Tested-by: Przemo Firszt <przemo@firszt.eu>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hid-core.c | 1 | ||||
-rw-r--r-- | drivers/hid/hid-wacom.c | 1 | ||||
-rw-r--r-- | drivers/hid/wacom_sys.c | 16 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.c | 75 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.h | 1 |
5 files changed, 92 insertions, 2 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index cbabd8786e71..b3181ea8f860 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1942,7 +1942,6 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1942 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) }, | 1942 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) }, |
1943 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) }, | 1943 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) }, |
1944 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) }, | 1944 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) }, |
1945 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) }, | ||
1946 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, | 1945 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, |
1947 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) }, | 1946 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) }, |
1948 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_Q_PAD) }, | 1947 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_Q_PAD) }, |
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index 967c457a2785..db2d07da4b4e 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c | |||
@@ -952,7 +952,6 @@ static void wacom_remove(struct hid_device *hdev) | |||
952 | } | 952 | } |
953 | 953 | ||
954 | static const struct hid_device_id wacom_devices[] = { | 954 | static const struct hid_device_id wacom_devices[] = { |
955 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) }, | ||
956 | 955 | ||
957 | { } | 956 | { } |
958 | }; | 957 | }; |
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index c21e58ba0693..f5c9c56c0975 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
@@ -296,6 +296,20 @@ static int wacom_bt_query_tablet_data(struct hid_device *hdev, u8 speed, | |||
296 | hid_warn(hdev, "failed to poke device, command %d, err %d\n", | 296 | hid_warn(hdev, "failed to poke device, command %d, err %d\n", |
297 | rep_data[0], ret); | 297 | rep_data[0], ret); |
298 | break; | 298 | break; |
299 | case INTUOS4WL: | ||
300 | if (speed == 1) | ||
301 | wacom->wacom_wac.bt_features &= ~0x20; | ||
302 | else | ||
303 | wacom->wacom_wac.bt_features |= 0x20; | ||
304 | |||
305 | rep_data[0] = 0x03; | ||
306 | rep_data[1] = wacom->wacom_wac.bt_features; | ||
307 | |||
308 | ret = wacom_set_report(hdev, HID_FEATURE_REPORT, | ||
309 | rep_data[0], rep_data, 2, 1); | ||
310 | if (ret >= 0) | ||
311 | wacom->wacom_wac.bt_high_speed = speed; | ||
312 | break; | ||
299 | } | 313 | } |
300 | 314 | ||
301 | return 0; | 315 | return 0; |
@@ -720,6 +734,7 @@ static int wacom_initialize_leds(struct wacom *wacom) | |||
720 | switch (wacom->wacom_wac.features.type) { | 734 | switch (wacom->wacom_wac.features.type) { |
721 | case INTUOS4S: | 735 | case INTUOS4S: |
722 | case INTUOS4: | 736 | case INTUOS4: |
737 | case INTUOS4WL: | ||
723 | case INTUOS4L: | 738 | case INTUOS4L: |
724 | wacom->led.select[0] = 0; | 739 | wacom->led.select[0] = 0; |
725 | wacom->led.select[1] = 0; | 740 | wacom->led.select[1] = 0; |
@@ -786,6 +801,7 @@ static void wacom_destroy_leds(struct wacom *wacom) | |||
786 | switch (wacom->wacom_wac.features.type) { | 801 | switch (wacom->wacom_wac.features.type) { |
787 | case INTUOS4S: | 802 | case INTUOS4S: |
788 | case INTUOS4: | 803 | case INTUOS4: |
804 | case INTUOS4WL: | ||
789 | case INTUOS4L: | 805 | case INTUOS4L: |
790 | sysfs_remove_group(&wacom->hdev->dev.kobj, | 806 | sysfs_remove_group(&wacom->hdev->dev.kobj, |
791 | &intuos4_led_attr_group); | 807 | &intuos4_led_attr_group); |
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index fa16a5bf3df3..d4a2d533a444 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
@@ -37,6 +37,11 @@ | |||
37 | */ | 37 | */ |
38 | static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 }; | 38 | static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 }; |
39 | 39 | ||
40 | /* | ||
41 | * Percent of battery capacity for Intuos4 WL, AC has a separate bit. | ||
42 | */ | ||
43 | static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; | ||
44 | |||
40 | static int wacom_penpartner_irq(struct wacom_wac *wacom) | 45 | static int wacom_penpartner_irq(struct wacom_wac *wacom) |
41 | { | 46 | { |
42 | unsigned char *data = wacom->data; | 47 | unsigned char *data = wacom->data; |
@@ -953,6 +958,58 @@ static int int_dist(int x1, int y1, int x2, int y2) | |||
953 | return int_sqrt(x*x + y*y); | 958 | return int_sqrt(x*x + y*y); |
954 | } | 959 | } |
955 | 960 | ||
961 | static void wacom_intuos_bt_process_data(struct wacom_wac *wacom, | ||
962 | unsigned char *data) | ||
963 | { | ||
964 | memcpy(wacom->data, data, 10); | ||
965 | wacom_intuos_irq(wacom); | ||
966 | |||
967 | input_sync(wacom->input); | ||
968 | if (wacom->pad_input) | ||
969 | input_sync(wacom->pad_input); | ||
970 | } | ||
971 | |||
972 | static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len) | ||
973 | { | ||
974 | unsigned char data[WACOM_PKGLEN_MAX]; | ||
975 | int i = 1; | ||
976 | unsigned power_raw, battery_capacity, bat_charging, ps_connected; | ||
977 | |||
978 | memcpy(data, wacom->data, len); | ||
979 | |||
980 | switch (data[0]) { | ||
981 | case 0x04: | ||
982 | wacom_intuos_bt_process_data(wacom, data + i); | ||
983 | i += 10; | ||
984 | /* fall through */ | ||
985 | case 0x03: | ||
986 | wacom_intuos_bt_process_data(wacom, data + i); | ||
987 | i += 10; | ||
988 | wacom_intuos_bt_process_data(wacom, data + i); | ||
989 | i += 10; | ||
990 | power_raw = data[i]; | ||
991 | bat_charging = (power_raw & 0x08) ? 1 : 0; | ||
992 | ps_connected = (power_raw & 0x10) ? 1 : 0; | ||
993 | battery_capacity = batcap_i4[power_raw & 0x07]; | ||
994 | if ((wacom->battery_capacity != battery_capacity) || | ||
995 | (wacom->bat_charging != bat_charging) || | ||
996 | (wacom->ps_connected != ps_connected)) { | ||
997 | wacom->battery_capacity = battery_capacity; | ||
998 | wacom->bat_charging = bat_charging; | ||
999 | wacom->ps_connected = ps_connected; | ||
1000 | wacom_notify_battery(wacom); | ||
1001 | } | ||
1002 | |||
1003 | break; | ||
1004 | default: | ||
1005 | dev_dbg(wacom->input->dev.parent, | ||
1006 | "Unknown report: %d,%d size:%zu\n", | ||
1007 | data[0], data[1], len); | ||
1008 | return 0; | ||
1009 | } | ||
1010 | return 0; | ||
1011 | } | ||
1012 | |||
956 | static int wacom_24hdt_irq(struct wacom_wac *wacom) | 1013 | static int wacom_24hdt_irq(struct wacom_wac *wacom) |
957 | { | 1014 | { |
958 | struct input_dev *input = wacom->input; | 1015 | struct input_dev *input = wacom->input; |
@@ -1512,6 +1569,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
1512 | sync = wacom_intuos_irq(wacom_wac); | 1569 | sync = wacom_intuos_irq(wacom_wac); |
1513 | break; | 1570 | break; |
1514 | 1571 | ||
1572 | case INTUOS4WL: | ||
1573 | sync = wacom_intuos_bt_irq(wacom_wac, len); | ||
1574 | break; | ||
1575 | |||
1515 | case WACOM_24HDT: | 1576 | case WACOM_24HDT: |
1516 | sync = wacom_24hdt_irq(wacom_wac); | 1577 | sync = wacom_24hdt_irq(wacom_wac); |
1517 | break; | 1578 | break; |
@@ -1803,6 +1864,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1803 | break; | 1864 | break; |
1804 | 1865 | ||
1805 | case INTUOS4: | 1866 | case INTUOS4: |
1867 | case INTUOS4WL: | ||
1806 | case INTUOS4L: | 1868 | case INTUOS4L: |
1807 | case INTUOS4S: | 1869 | case INTUOS4S: |
1808 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 1870 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
@@ -2065,6 +2127,15 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
2065 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); | 2127 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); |
2066 | break; | 2128 | break; |
2067 | 2129 | ||
2130 | case INTUOS4WL: | ||
2131 | /* | ||
2132 | * For Bluetooth devices, the udev rule does not work correctly | ||
2133 | * for pads unless we add a stylus capability, which forces | ||
2134 | * ID_INPUT_TABLET to be set. | ||
2135 | */ | ||
2136 | __set_bit(BTN_STYLUS, input_dev->keybit); | ||
2137 | /* fall through */ | ||
2138 | |||
2068 | case INTUOS4: | 2139 | case INTUOS4: |
2069 | case INTUOS4L: | 2140 | case INTUOS4L: |
2070 | __set_bit(BTN_7, input_dev->keybit); | 2141 | __set_bit(BTN_7, input_dev->keybit); |
@@ -2279,6 +2350,9 @@ static const struct wacom_features wacom_features_0xBB = | |||
2279 | static const struct wacom_features wacom_features_0xBC = | 2350 | static const struct wacom_features wacom_features_0xBC = |
2280 | { "Wacom Intuos4 WL", 40640, 25400, 2047, 63, | 2351 | { "Wacom Intuos4 WL", 40640, 25400, 2047, 63, |
2281 | INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 2352 | INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
2353 | static const struct wacom_features wacom_features_0xBD = | ||
2354 | { "Wacom Intuos4 WL", 40640, 25400, 2047, 63, | ||
2355 | INTUOS4WL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
2282 | static const struct wacom_features wacom_features_0x26 = | 2356 | static const struct wacom_features wacom_features_0x26 = |
2283 | { "Wacom Intuos5 touch S", 31496, 19685, 2047, 63, | 2357 | { "Wacom Intuos5 touch S", 31496, 19685, 2047, 63, |
2284 | INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16 }; | 2358 | INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16 }; |
@@ -2598,6 +2672,7 @@ const struct hid_device_id wacom_ids[] = { | |||
2598 | { USB_DEVICE_WACOM(0xBA) }, | 2672 | { USB_DEVICE_WACOM(0xBA) }, |
2599 | { USB_DEVICE_WACOM(0xBB) }, | 2673 | { USB_DEVICE_WACOM(0xBB) }, |
2600 | { USB_DEVICE_WACOM(0xBC) }, | 2674 | { USB_DEVICE_WACOM(0xBC) }, |
2675 | { BT_DEVICE_WACOM(0xBD) }, | ||
2601 | { USB_DEVICE_WACOM(0xC0) }, | 2676 | { USB_DEVICE_WACOM(0xC0) }, |
2602 | { USB_DEVICE_WACOM(0xC2) }, | 2677 | { USB_DEVICE_WACOM(0xC2) }, |
2603 | { USB_DEVICE_WACOM(0xC4) }, | 2678 | { USB_DEVICE_WACOM(0xC4) }, |
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 4f0178b9a789..339ab5d81a2d 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h | |||
@@ -86,6 +86,7 @@ enum { | |||
86 | INTUOS3L, | 86 | INTUOS3L, |
87 | INTUOS4S, | 87 | INTUOS4S, |
88 | INTUOS4, | 88 | INTUOS4, |
89 | INTUOS4WL, | ||
89 | INTUOS4L, | 90 | INTUOS4L, |
90 | INTUOS5S, | 91 | INTUOS5S, |
91 | INTUOS5, | 92 | INTUOS5, |