diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-03-27 03:27:10 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-03-27 03:27:10 -0400 |
commit | 993808253ca256b8ca7f8ff90d9935d7c99cd32d (patch) | |
tree | ff51c2b3f7625ae8d89b45962cc3dbc59a5152f8 /drivers/input/tablet | |
parent | 10ce3cc919f50c2043b41ca968b43c26a3672600 (diff) | |
parent | 131c713fd96e251fcb18f4d2d05f263aa41bb11f (diff) |
Merge branch 'next' into for-linus
Conflicts:
drivers/input/tablet/wacom_sys.c
Diffstat (limited to 'drivers/input/tablet')
-rw-r--r-- | drivers/input/tablet/Kconfig | 1 | ||||
-rw-r--r-- | drivers/input/tablet/wacom.h | 9 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_sys.c | 229 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.c | 49 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.h | 6 |
5 files changed, 262 insertions, 32 deletions
diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig index e53f4081a586..bed7cbf84cfd 100644 --- a/drivers/input/tablet/Kconfig +++ b/drivers/input/tablet/Kconfig | |||
@@ -76,6 +76,7 @@ config TABLET_USB_KBTAB | |||
76 | config TABLET_USB_WACOM | 76 | config TABLET_USB_WACOM |
77 | tristate "Wacom Intuos/Graphire tablet support (USB)" | 77 | tristate "Wacom Intuos/Graphire tablet support (USB)" |
78 | depends on USB_ARCH_HAS_HCD | 78 | depends on USB_ARCH_HAS_HCD |
79 | select POWER_SUPPLY | ||
79 | select USB | 80 | select USB |
80 | select NEW_LEDS | 81 | select NEW_LEDS |
81 | select LEDS_CLASS | 82 | select LEDS_CLASS |
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 0783864a7dc2..b4842d0e61dd 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -88,6 +88,7 @@ | |||
88 | #include <linux/mod_devicetable.h> | 88 | #include <linux/mod_devicetable.h> |
89 | #include <linux/init.h> | 89 | #include <linux/init.h> |
90 | #include <linux/usb/input.h> | 90 | #include <linux/usb/input.h> |
91 | #include <linux/power_supply.h> | ||
91 | #include <asm/unaligned.h> | 92 | #include <asm/unaligned.h> |
92 | 93 | ||
93 | /* | 94 | /* |
@@ -112,6 +113,7 @@ struct wacom { | |||
112 | struct urb *irq; | 113 | struct urb *irq; |
113 | struct wacom_wac wacom_wac; | 114 | struct wacom_wac wacom_wac; |
114 | struct mutex lock; | 115 | struct mutex lock; |
116 | struct work_struct work; | ||
115 | bool open; | 117 | bool open; |
116 | char phys[32]; | 118 | char phys[32]; |
117 | struct wacom_led { | 119 | struct wacom_led { |
@@ -120,8 +122,15 @@ struct wacom { | |||
120 | u8 hlv; /* status led brightness button pressed (1..127) */ | 122 | u8 hlv; /* status led brightness button pressed (1..127) */ |
121 | u8 img_lum; /* OLED matrix display brightness */ | 123 | u8 img_lum; /* OLED matrix display brightness */ |
122 | } led; | 124 | } led; |
125 | struct power_supply battery; | ||
123 | }; | 126 | }; |
124 | 127 | ||
128 | static inline void wacom_schedule_work(struct wacom_wac *wacom_wac) | ||
129 | { | ||
130 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
131 | schedule_work(&wacom->work); | ||
132 | } | ||
133 | |||
125 | extern const struct usb_device_id wacom_ids[]; | 134 | extern const struct usb_device_id wacom_ids[]; |
126 | 135 | ||
127 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); | 136 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index ca28066dc81e..19ba58640dc2 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -167,6 +167,19 @@ static void wacom_close(struct input_dev *dev) | |||
167 | usb_autopm_put_interface(wacom->intf); | 167 | usb_autopm_put_interface(wacom->intf); |
168 | } | 168 | } |
169 | 169 | ||
170 | /* | ||
171 | * Static values for max X/Y and resolution of Pen interface is stored in | ||
172 | * features. This mean physical size of active area can be computed. | ||
173 | * This is useful to do when Pen and Touch have same active area of tablet. | ||
174 | * This means for Touch device, we only need to find max X/Y value and we | ||
175 | * have enough information to compute resolution of touch. | ||
176 | */ | ||
177 | static void wacom_set_phy_from_res(struct wacom_features *features) | ||
178 | { | ||
179 | features->x_phy = (features->x_max * 100) / features->x_resolution; | ||
180 | features->y_phy = (features->y_max * 100) / features->y_resolution; | ||
181 | } | ||
182 | |||
170 | static int wacom_parse_logical_collection(unsigned char *report, | 183 | static int wacom_parse_logical_collection(unsigned char *report, |
171 | struct wacom_features *features) | 184 | struct wacom_features *features) |
172 | { | 185 | { |
@@ -178,15 +191,7 @@ static int wacom_parse_logical_collection(unsigned char *report, | |||
178 | features->pktlen = WACOM_PKGLEN_BBTOUCH3; | 191 | features->pktlen = WACOM_PKGLEN_BBTOUCH3; |
179 | features->device_type = BTN_TOOL_FINGER; | 192 | features->device_type = BTN_TOOL_FINGER; |
180 | 193 | ||
181 | /* | 194 | wacom_set_phy_from_res(features); |
182 | * Stylus and Touch have same active area | ||
183 | * so compute physical size based on stylus | ||
184 | * data before its overwritten. | ||
185 | */ | ||
186 | features->x_phy = | ||
187 | (features->x_max * 100) / features->x_resolution; | ||
188 | features->y_phy = | ||
189 | (features->y_max * 100) / features->y_resolution; | ||
190 | 195 | ||
191 | features->x_max = features->y_max = | 196 | features->x_max = features->y_max = |
192 | get_unaligned_le16(&report[10]); | 197 | get_unaligned_le16(&report[10]); |
@@ -422,6 +427,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat | |||
422 | report_id, rep_data, 4, 1); | 427 | report_id, rep_data, 4, 1); |
423 | } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES); | 428 | } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES); |
424 | } else if (features->type != TABLETPC && | 429 | } else if (features->type != TABLETPC && |
430 | features->type != WIRELESS && | ||
425 | features->device_type == BTN_TOOL_PEN) { | 431 | features->device_type == BTN_TOOL_PEN) { |
426 | do { | 432 | do { |
427 | rep_data[0] = 2; | 433 | rep_data[0] = 2; |
@@ -454,6 +460,21 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | |||
454 | features->pressure_fuzz = 0; | 460 | features->pressure_fuzz = 0; |
455 | features->distance_fuzz = 0; | 461 | features->distance_fuzz = 0; |
456 | 462 | ||
463 | /* | ||
464 | * The wireless device HID is basic and layout conflicts with | ||
465 | * other tablets (monitor and touch interface can look like pen). | ||
466 | * Skip the query for this type and modify defaults based on | ||
467 | * interface number. | ||
468 | */ | ||
469 | if (features->type == WIRELESS) { | ||
470 | if (intf->cur_altsetting->desc.bInterfaceNumber == 0) { | ||
471 | features->device_type = 0; | ||
472 | } else if (intf->cur_altsetting->desc.bInterfaceNumber == 2) { | ||
473 | features->device_type = BTN_TOOL_DOUBLETAP; | ||
474 | features->pktlen = WACOM_PKGLEN_BBTOUCH3; | ||
475 | } | ||
476 | } | ||
477 | |||
457 | /* only Tablet PCs and Bamboo P&T need to retrieve the info */ | 478 | /* only Tablet PCs and Bamboo P&T need to retrieve the info */ |
458 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) && | 479 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) && |
459 | (features->type != BAMBOO_PT)) | 480 | (features->type != BAMBOO_PT)) |
@@ -822,6 +843,152 @@ static void wacom_destroy_leds(struct wacom *wacom) | |||
822 | } | 843 | } |
823 | } | 844 | } |
824 | 845 | ||
846 | static enum power_supply_property wacom_battery_props[] = { | ||
847 | POWER_SUPPLY_PROP_CAPACITY | ||
848 | }; | ||
849 | |||
850 | static int wacom_battery_get_property(struct power_supply *psy, | ||
851 | enum power_supply_property psp, | ||
852 | union power_supply_propval *val) | ||
853 | { | ||
854 | struct wacom *wacom = container_of(psy, struct wacom, battery); | ||
855 | int ret = 0; | ||
856 | |||
857 | switch (psp) { | ||
858 | case POWER_SUPPLY_PROP_CAPACITY: | ||
859 | val->intval = | ||
860 | wacom->wacom_wac.battery_capacity * 100 / 31; | ||
861 | break; | ||
862 | default: | ||
863 | ret = -EINVAL; | ||
864 | break; | ||
865 | } | ||
866 | |||
867 | return ret; | ||
868 | } | ||
869 | |||
870 | static int wacom_initialize_battery(struct wacom *wacom) | ||
871 | { | ||
872 | int error = 0; | ||
873 | |||
874 | if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR) { | ||
875 | wacom->battery.properties = wacom_battery_props; | ||
876 | wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props); | ||
877 | wacom->battery.get_property = wacom_battery_get_property; | ||
878 | wacom->battery.name = "wacom_battery"; | ||
879 | wacom->battery.type = POWER_SUPPLY_TYPE_BATTERY; | ||
880 | wacom->battery.use_for_apm = 0; | ||
881 | |||
882 | error = power_supply_register(&wacom->usbdev->dev, | ||
883 | &wacom->battery); | ||
884 | } | ||
885 | |||
886 | return error; | ||
887 | } | ||
888 | |||
889 | static void wacom_destroy_battery(struct wacom *wacom) | ||
890 | { | ||
891 | if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR) | ||
892 | power_supply_unregister(&wacom->battery); | ||
893 | } | ||
894 | |||
895 | static int wacom_register_input(struct wacom *wacom) | ||
896 | { | ||
897 | struct input_dev *input_dev; | ||
898 | struct usb_interface *intf = wacom->intf; | ||
899 | struct usb_device *dev = interface_to_usbdev(intf); | ||
900 | struct wacom_wac *wacom_wac = &(wacom->wacom_wac); | ||
901 | int error; | ||
902 | |||
903 | input_dev = input_allocate_device(); | ||
904 | if (!input_dev) | ||
905 | return -ENOMEM; | ||
906 | |||
907 | input_dev->name = wacom_wac->name; | ||
908 | input_dev->dev.parent = &intf->dev; | ||
909 | input_dev->open = wacom_open; | ||
910 | input_dev->close = wacom_close; | ||
911 | usb_to_input_id(dev, &input_dev->id); | ||
912 | input_set_drvdata(input_dev, wacom); | ||
913 | |||
914 | wacom_wac->input = input_dev; | ||
915 | wacom_setup_input_capabilities(input_dev, wacom_wac); | ||
916 | |||
917 | error = input_register_device(input_dev); | ||
918 | if (error) { | ||
919 | input_free_device(input_dev); | ||
920 | wacom_wac->input = NULL; | ||
921 | } | ||
922 | |||
923 | return error; | ||
924 | } | ||
925 | |||
926 | static void wacom_wireless_work(struct work_struct *work) | ||
927 | { | ||
928 | struct wacom *wacom = container_of(work, struct wacom, work); | ||
929 | struct usb_device *usbdev = wacom->usbdev; | ||
930 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
931 | |||
932 | /* | ||
933 | * Regardless if this is a disconnect or a new tablet, | ||
934 | * remove any existing input devices. | ||
935 | */ | ||
936 | |||
937 | /* Stylus interface */ | ||
938 | wacom = usb_get_intfdata(usbdev->config->interface[1]); | ||
939 | if (wacom->wacom_wac.input) | ||
940 | input_unregister_device(wacom->wacom_wac.input); | ||
941 | wacom->wacom_wac.input = 0; | ||
942 | |||
943 | /* Touch interface */ | ||
944 | wacom = usb_get_intfdata(usbdev->config->interface[2]); | ||
945 | if (wacom->wacom_wac.input) | ||
946 | input_unregister_device(wacom->wacom_wac.input); | ||
947 | wacom->wacom_wac.input = 0; | ||
948 | |||
949 | if (wacom_wac->pid == 0) { | ||
950 | printk(KERN_INFO "wacom: wireless tablet disconnected\n"); | ||
951 | } else { | ||
952 | const struct usb_device_id *id = wacom_ids; | ||
953 | |||
954 | printk(KERN_INFO | ||
955 | "wacom: wireless tablet connected with PID %x\n", | ||
956 | wacom_wac->pid); | ||
957 | |||
958 | while (id->match_flags) { | ||
959 | if (id->idVendor == USB_VENDOR_ID_WACOM && | ||
960 | id->idProduct == wacom_wac->pid) | ||
961 | break; | ||
962 | id++; | ||
963 | } | ||
964 | |||
965 | if (!id->match_flags) { | ||
966 | printk(KERN_INFO | ||
967 | "wacom: ignorning unknown PID.\n"); | ||
968 | return; | ||
969 | } | ||
970 | |||
971 | /* Stylus interface */ | ||
972 | wacom = usb_get_intfdata(usbdev->config->interface[1]); | ||
973 | wacom_wac = &wacom->wacom_wac; | ||
974 | wacom_wac->features = | ||
975 | *((struct wacom_features *)id->driver_info); | ||
976 | wacom_wac->features.device_type = BTN_TOOL_PEN; | ||
977 | wacom_register_input(wacom); | ||
978 | |||
979 | /* Touch interface */ | ||
980 | wacom = usb_get_intfdata(usbdev->config->interface[2]); | ||
981 | wacom_wac = &wacom->wacom_wac; | ||
982 | wacom_wac->features = | ||
983 | *((struct wacom_features *)id->driver_info); | ||
984 | wacom_wac->features.pktlen = WACOM_PKGLEN_BBTOUCH3; | ||
985 | wacom_wac->features.device_type = BTN_TOOL_FINGER; | ||
986 | wacom_set_phy_from_res(&wacom_wac->features); | ||
987 | wacom_wac->features.x_max = wacom_wac->features.y_max = 4096; | ||
988 | wacom_register_input(wacom); | ||
989 | } | ||
990 | } | ||
991 | |||
825 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) | 992 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) |
826 | { | 993 | { |
827 | struct usb_device *dev = interface_to_usbdev(intf); | 994 | struct usb_device *dev = interface_to_usbdev(intf); |
@@ -829,18 +996,12 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
829 | struct wacom *wacom; | 996 | struct wacom *wacom; |
830 | struct wacom_wac *wacom_wac; | 997 | struct wacom_wac *wacom_wac; |
831 | struct wacom_features *features; | 998 | struct wacom_features *features; |
832 | struct input_dev *input_dev; | ||
833 | int error; | 999 | int error; |
834 | 1000 | ||
835 | if (!id->driver_info) | 1001 | if (!id->driver_info) |
836 | return -EINVAL; | 1002 | return -EINVAL; |
837 | 1003 | ||
838 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | 1004 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); |
839 | input_dev = input_allocate_device(); | ||
840 | if (!wacom || !input_dev) { | ||
841 | error = -ENOMEM; | ||
842 | goto fail1; | ||
843 | } | ||
844 | 1005 | ||
845 | wacom_wac = &wacom->wacom_wac; | 1006 | wacom_wac = &wacom->wacom_wac; |
846 | wacom_wac->features = *((struct wacom_features *)id->driver_info); | 1007 | wacom_wac->features = *((struct wacom_features *)id->driver_info); |
@@ -866,11 +1027,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
866 | wacom->usbdev = dev; | 1027 | wacom->usbdev = dev; |
867 | wacom->intf = intf; | 1028 | wacom->intf = intf; |
868 | mutex_init(&wacom->lock); | 1029 | mutex_init(&wacom->lock); |
1030 | INIT_WORK(&wacom->work, wacom_wireless_work); | ||
869 | usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); | 1031 | usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); |
870 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); | 1032 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); |
871 | 1033 | ||
872 | wacom_wac->input = input_dev; | ||
873 | |||
874 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | 1034 | endpoint = &intf->cur_altsetting->endpoint[0].desc; |
875 | 1035 | ||
876 | /* Retrieve the physical and logical size for OEM devices */ | 1036 | /* Retrieve the physical and logical size for OEM devices */ |
@@ -894,15 +1054,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
894 | goto fail3; | 1054 | goto fail3; |
895 | } | 1055 | } |
896 | 1056 | ||
897 | input_dev->name = wacom_wac->name; | ||
898 | input_dev->dev.parent = &intf->dev; | ||
899 | input_dev->open = wacom_open; | ||
900 | input_dev->close = wacom_close; | ||
901 | usb_to_input_id(dev, &input_dev->id); | ||
902 | input_set_drvdata(input_dev, wacom); | ||
903 | |||
904 | wacom_setup_input_capabilities(input_dev, wacom_wac); | ||
905 | |||
906 | usb_fill_int_urb(wacom->irq, dev, | 1057 | usb_fill_int_urb(wacom->irq, dev, |
907 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | 1058 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), |
908 | wacom_wac->data, features->pktlen, | 1059 | wacom_wac->data, features->pktlen, |
@@ -914,22 +1065,34 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
914 | if (error) | 1065 | if (error) |
915 | goto fail4; | 1066 | goto fail4; |
916 | 1067 | ||
917 | error = input_register_device(input_dev); | 1068 | error = wacom_initialize_battery(wacom); |
918 | if (error) | 1069 | if (error) |
919 | goto fail5; | 1070 | goto fail5; |
920 | 1071 | ||
1072 | if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) { | ||
1073 | error = wacom_register_input(wacom); | ||
1074 | if (error) | ||
1075 | goto fail6; | ||
1076 | } | ||
1077 | |||
921 | /* Note that if query fails it is not a hard failure */ | 1078 | /* Note that if query fails it is not a hard failure */ |
922 | wacom_query_tablet_data(intf, features); | 1079 | wacom_query_tablet_data(intf, features); |
923 | 1080 | ||
924 | usb_set_intfdata(intf, wacom); | 1081 | usb_set_intfdata(intf, wacom); |
1082 | |||
1083 | if (features->quirks & WACOM_QUIRK_MONITOR) { | ||
1084 | if (usb_submit_urb(wacom->irq, GFP_KERNEL)) | ||
1085 | goto fail5; | ||
1086 | } | ||
1087 | |||
925 | return 0; | 1088 | return 0; |
926 | 1089 | ||
1090 | fail6: wacom_destroy_battery(wacom); | ||
927 | fail5: wacom_destroy_leds(wacom); | 1091 | fail5: wacom_destroy_leds(wacom); |
928 | fail4: wacom_remove_shared_data(wacom_wac); | 1092 | fail4: wacom_remove_shared_data(wacom_wac); |
929 | fail3: usb_free_urb(wacom->irq); | 1093 | fail3: usb_free_urb(wacom->irq); |
930 | fail2: usb_free_coherent(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma); | 1094 | fail2: usb_free_coherent(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma); |
931 | fail1: input_free_device(input_dev); | 1095 | fail1: kfree(wacom); |
932 | kfree(wacom); | ||
933 | return error; | 1096 | return error; |
934 | } | 1097 | } |
935 | 1098 | ||
@@ -940,7 +1103,10 @@ static void wacom_disconnect(struct usb_interface *intf) | |||
940 | usb_set_intfdata(intf, NULL); | 1103 | usb_set_intfdata(intf, NULL); |
941 | 1104 | ||
942 | usb_kill_urb(wacom->irq); | 1105 | usb_kill_urb(wacom->irq); |
943 | input_unregister_device(wacom->wacom_wac.input); | 1106 | cancel_work_sync(&wacom->work); |
1107 | if (wacom->wacom_wac.input) | ||
1108 | input_unregister_device(wacom->wacom_wac.input); | ||
1109 | wacom_destroy_battery(wacom); | ||
944 | wacom_destroy_leds(wacom); | 1110 | wacom_destroy_leds(wacom); |
945 | usb_free_urb(wacom->irq); | 1111 | usb_free_urb(wacom->irq); |
946 | usb_free_coherent(interface_to_usbdev(intf), WACOM_PKGLEN_MAX, | 1112 | usb_free_coherent(interface_to_usbdev(intf), WACOM_PKGLEN_MAX, |
@@ -972,7 +1138,8 @@ static int wacom_resume(struct usb_interface *intf) | |||
972 | wacom_query_tablet_data(intf, features); | 1138 | wacom_query_tablet_data(intf, features); |
973 | wacom_led_control(wacom); | 1139 | wacom_led_control(wacom); |
974 | 1140 | ||
975 | if (wacom->open && usb_submit_urb(wacom->irq, GFP_NOIO) < 0) | 1141 | if ((wacom->open || features->quirks & WACOM_QUIRK_MONITOR) |
1142 | && usb_submit_urb(wacom->irq, GFP_NOIO) < 0) | ||
976 | rv = -EIO; | 1143 | rv = -EIO; |
977 | 1144 | ||
978 | mutex_unlock(&wacom->lock); | 1145 | mutex_unlock(&wacom->lock); |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 89a96427faa0..cecd35c8f0b3 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -1044,6 +1044,35 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len) | |||
1044 | return 0; | 1044 | return 0; |
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) | ||
1048 | { | ||
1049 | unsigned char *data = wacom->data; | ||
1050 | int connected; | ||
1051 | |||
1052 | if (len != WACOM_PKGLEN_WIRELESS || data[0] != 0x80) | ||
1053 | return 0; | ||
1054 | |||
1055 | connected = data[1] & 0x01; | ||
1056 | if (connected) { | ||
1057 | int pid, battery; | ||
1058 | |||
1059 | pid = get_unaligned_be16(&data[6]); | ||
1060 | battery = data[5] & 0x3f; | ||
1061 | if (wacom->pid != pid) { | ||
1062 | wacom->pid = pid; | ||
1063 | wacom_schedule_work(wacom); | ||
1064 | } | ||
1065 | wacom->battery_capacity = battery; | ||
1066 | } else if (wacom->pid != 0) { | ||
1067 | /* disconnected while previously connected */ | ||
1068 | wacom->pid = 0; | ||
1069 | wacom_schedule_work(wacom); | ||
1070 | wacom->battery_capacity = 0; | ||
1071 | } | ||
1072 | |||
1073 | return 0; | ||
1074 | } | ||
1075 | |||
1047 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | 1076 | void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) |
1048 | { | 1077 | { |
1049 | bool sync; | 1078 | bool sync; |
@@ -1094,6 +1123,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
1094 | sync = wacom_bpt_irq(wacom_wac, len); | 1123 | sync = wacom_bpt_irq(wacom_wac, len); |
1095 | break; | 1124 | break; |
1096 | 1125 | ||
1126 | case WIRELESS: | ||
1127 | sync = wacom_wireless_irq(wacom_wac, len); | ||
1128 | break; | ||
1129 | |||
1097 | default: | 1130 | default: |
1098 | sync = false; | 1131 | sync = false; |
1099 | break; | 1132 | break; |
@@ -1155,7 +1188,7 @@ void wacom_setup_device_quirks(struct wacom_features *features) | |||
1155 | 1188 | ||
1156 | /* these device have multiple inputs */ | 1189 | /* these device have multiple inputs */ |
1157 | if (features->type == TABLETPC || features->type == TABLETPC2FG || | 1190 | if (features->type == TABLETPC || features->type == TABLETPC2FG || |
1158 | features->type == BAMBOO_PT) | 1191 | features->type == BAMBOO_PT || features->type == WIRELESS) |
1159 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; | 1192 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; |
1160 | 1193 | ||
1161 | /* quirk for bamboo touch with 2 low res touches */ | 1194 | /* quirk for bamboo touch with 2 low res touches */ |
@@ -1167,6 +1200,16 @@ void wacom_setup_device_quirks(struct wacom_features *features) | |||
1167 | features->y_fuzz <<= 5; | 1200 | features->y_fuzz <<= 5; |
1168 | features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES; | 1201 | features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES; |
1169 | } | 1202 | } |
1203 | |||
1204 | if (features->type == WIRELESS) { | ||
1205 | |||
1206 | /* monitor never has input and pen/touch have delayed create */ | ||
1207 | features->quirks |= WACOM_QUIRK_NO_INPUT; | ||
1208 | |||
1209 | /* must be monitor interface if no device_type set */ | ||
1210 | if (!features->device_type) | ||
1211 | features->quirks |= WACOM_QUIRK_MONITOR; | ||
1212 | } | ||
1170 | } | 1213 | } |
1171 | 1214 | ||
1172 | static unsigned int wacom_calculate_touch_res(unsigned int logical_max, | 1215 | static unsigned int wacom_calculate_touch_res(unsigned int logical_max, |
@@ -1640,6 +1683,9 @@ static const struct wacom_features wacom_features_0xEC = | |||
1640 | static const struct wacom_features wacom_features_0x47 = | 1683 | static const struct wacom_features wacom_features_0x47 = |
1641 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, | 1684 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, |
1642 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1685 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
1686 | static const struct wacom_features wacom_features_0x84 = | ||
1687 | { "Wacom Wireless Receiver", WACOM_PKGLEN_WIRELESS, 0, 0, 0, | ||
1688 | 0, WIRELESS, 0, 0 }; | ||
1643 | static const struct wacom_features wacom_features_0xD0 = | 1689 | static const struct wacom_features wacom_features_0xD0 = |
1644 | { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | 1690 | { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, |
1645 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1691 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
@@ -1766,6 +1812,7 @@ const struct usb_device_id wacom_ids[] = { | |||
1766 | { USB_DEVICE_DETAILED(0xCE, USB_CLASS_HID, | 1812 | { USB_DEVICE_DETAILED(0xCE, USB_CLASS_HID, |
1767 | USB_INTERFACE_SUBCLASS_BOOT, | 1813 | USB_INTERFACE_SUBCLASS_BOOT, |
1768 | USB_INTERFACE_PROTOCOL_MOUSE) }, | 1814 | USB_INTERFACE_PROTOCOL_MOUSE) }, |
1815 | { USB_DEVICE_WACOM(0x84) }, | ||
1769 | { USB_DEVICE_WACOM(0xD0) }, | 1816 | { USB_DEVICE_WACOM(0xD0) }, |
1770 | { USB_DEVICE_WACOM(0xD1) }, | 1817 | { USB_DEVICE_WACOM(0xD1) }, |
1771 | { USB_DEVICE_WACOM(0xD2) }, | 1818 | { USB_DEVICE_WACOM(0xD2) }, |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 4f0ba21b0196..ba5a334e54d6 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define WACOM_PKGLEN_BBTOUCH 20 | 24 | #define WACOM_PKGLEN_BBTOUCH 20 |
25 | #define WACOM_PKGLEN_BBTOUCH3 64 | 25 | #define WACOM_PKGLEN_BBTOUCH3 64 |
26 | #define WACOM_PKGLEN_BBPEN 10 | 26 | #define WACOM_PKGLEN_BBPEN 10 |
27 | #define WACOM_PKGLEN_WIRELESS 32 | ||
27 | 28 | ||
28 | /* device IDs */ | 29 | /* device IDs */ |
29 | #define STYLUS_DEVICE_ID 0x02 | 30 | #define STYLUS_DEVICE_ID 0x02 |
@@ -45,6 +46,8 @@ | |||
45 | /* device quirks */ | 46 | /* device quirks */ |
46 | #define WACOM_QUIRK_MULTI_INPUT 0x0001 | 47 | #define WACOM_QUIRK_MULTI_INPUT 0x0001 |
47 | #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 | 48 | #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 |
49 | #define WACOM_QUIRK_NO_INPUT 0x0004 | ||
50 | #define WACOM_QUIRK_MONITOR 0x0008 | ||
48 | 51 | ||
49 | enum { | 52 | enum { |
50 | PENPARTNER = 0, | 53 | PENPARTNER = 0, |
@@ -54,6 +57,7 @@ enum { | |||
54 | PL, | 57 | PL, |
55 | DTU, | 58 | DTU, |
56 | BAMBOO_PT, | 59 | BAMBOO_PT, |
60 | WIRELESS, | ||
57 | INTUOS, | 61 | INTUOS, |
58 | INTUOS3S, | 62 | INTUOS3S, |
59 | INTUOS3, | 63 | INTUOS3, |
@@ -107,6 +111,8 @@ struct wacom_wac { | |||
107 | struct wacom_features features; | 111 | struct wacom_features features; |
108 | struct wacom_shared *shared; | 112 | struct wacom_shared *shared; |
109 | struct input_dev *input; | 113 | struct input_dev *input; |
114 | int pid; | ||
115 | int battery_capacity; | ||
110 | }; | 116 | }; |
111 | 117 | ||
112 | #endif | 118 | #endif |