aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/tablet/wacom.h7
-rw-r--r--drivers/input/tablet/wacom_sys.c91
-rw-r--r--drivers/input/tablet/wacom_wac.c20
-rw-r--r--drivers/input/tablet/wacom_wac.h1
4 files changed, 109 insertions, 10 deletions
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
index 0783864a7dc2..febbfd9f3a84 100644
--- a/drivers/input/tablet/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -112,6 +112,7 @@ struct wacom {
112 struct urb *irq; 112 struct urb *irq;
113 struct wacom_wac wacom_wac; 113 struct wacom_wac wacom_wac;
114 struct mutex lock; 114 struct mutex lock;
115 struct work_struct work;
115 bool open; 116 bool open;
116 char phys[32]; 117 char phys[32];
117 struct wacom_led { 118 struct wacom_led {
@@ -122,6 +123,12 @@ struct wacom {
122 } led; 123 } led;
123}; 124};
124 125
126static inline void wacom_schedule_work(struct wacom_wac *wacom_wac)
127{
128 struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
129 schedule_work(&wacom->work);
130}
131
125extern const struct usb_device_id wacom_ids[]; 132extern const struct usb_device_id wacom_ids[];
126 133
127void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); 134void 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 d8cc9ce165ff..2fc77053960f 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 */
177static 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
170static int wacom_parse_logical_collection(unsigned char *report, 183static 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 * features->x_resolution) / 100;
188 features->y_phy =
189 (features->y_max * features->y_resolution) / 100;
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]);
@@ -869,6 +874,72 @@ static int wacom_register_input(struct wacom *wacom)
869 return error; 874 return error;
870} 875}
871 876
877static void wacom_wireless_work(struct work_struct *work)
878{
879 struct wacom *wacom = container_of(work, struct wacom, work);
880 struct usb_device *usbdev = wacom->usbdev;
881 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
882
883 /*
884 * Regardless if this is a disconnect or a new tablet,
885 * remove any existing input devices.
886 */
887
888 /* Stylus interface */
889 wacom = usb_get_intfdata(usbdev->config->interface[1]);
890 if (wacom->wacom_wac.input)
891 input_unregister_device(wacom->wacom_wac.input);
892 wacom->wacom_wac.input = 0;
893
894 /* Touch interface */
895 wacom = usb_get_intfdata(usbdev->config->interface[2]);
896 if (wacom->wacom_wac.input)
897 input_unregister_device(wacom->wacom_wac.input);
898 wacom->wacom_wac.input = 0;
899
900 if (wacom_wac->pid == 0) {
901 printk(KERN_INFO "wacom: wireless tablet disconnected\n");
902 } else {
903 const struct usb_device_id *id = wacom_ids;
904
905 printk(KERN_INFO
906 "wacom: wireless tablet connected with PID %x\n",
907 wacom_wac->pid);
908
909 while (id->match_flags) {
910 if (id->idVendor == USB_VENDOR_ID_WACOM &&
911 id->idProduct == wacom_wac->pid)
912 break;
913 id++;
914 }
915
916 if (!id->match_flags) {
917 printk(KERN_INFO
918 "wacom: ignorning unknown PID.\n");
919 return;
920 }
921
922 /* Stylus interface */
923 wacom = usb_get_intfdata(usbdev->config->interface[1]);
924 wacom_wac = &wacom->wacom_wac;
925 wacom_wac->features =
926 *((struct wacom_features *)id->driver_info);
927 wacom_wac->features.device_type = BTN_TOOL_PEN;
928 wacom_register_input(wacom);
929
930 /* Touch interface */
931 wacom = usb_get_intfdata(usbdev->config->interface[2]);
932 wacom_wac = &wacom->wacom_wac;
933 wacom_wac->features =
934 *((struct wacom_features *)id->driver_info);
935 wacom_wac->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
936 wacom_wac->features.device_type = BTN_TOOL_FINGER;
937 wacom_set_phy_from_res(&wacom_wac->features);
938 wacom_wac->features.x_max = wacom_wac->features.y_max = 4096;
939 wacom_register_input(wacom);
940 }
941}
942
872static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) 943static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
873{ 944{
874 struct usb_device *dev = interface_to_usbdev(intf); 945 struct usb_device *dev = interface_to_usbdev(intf);
@@ -907,6 +978,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
907 wacom->usbdev = dev; 978 wacom->usbdev = dev;
908 wacom->intf = intf; 979 wacom->intf = intf;
909 mutex_init(&wacom->lock); 980 mutex_init(&wacom->lock);
981 INIT_WORK(&wacom->work, wacom_wireless_work);
910 usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); 982 usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
911 strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); 983 strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
912 984
@@ -977,6 +1049,7 @@ static void wacom_disconnect(struct usb_interface *intf)
977 usb_set_intfdata(intf, NULL); 1049 usb_set_intfdata(intf, NULL);
978 1050
979 usb_kill_urb(wacom->irq); 1051 usb_kill_urb(wacom->irq);
1052 cancel_work_sync(&wacom->work);
980 if (wacom->wacom_wac.input) 1053 if (wacom->wacom_wac.input)
981 input_unregister_device(wacom->wacom_wac.input); 1054 input_unregister_device(wacom->wacom_wac.input);
982 wacom_destroy_leds(wacom); 1055 wacom_destroy_leds(wacom);
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 6264e6a8d513..fce7a09fb5db 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -1046,9 +1046,27 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
1046 1046
1047static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) 1047static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
1048{ 1048{
1049 if (len != WACOM_PKGLEN_WIRELESS) 1049 unsigned char *data = wacom->data;
1050 int connected;
1051
1052 if (len != WACOM_PKGLEN_WIRELESS || data[0] != 0x80)
1050 return 0; 1053 return 0;
1051 1054
1055 connected = data[1] & 0x01;
1056 if (connected) {
1057 int pid;
1058
1059 pid = get_unaligned_be16(&data[6]);
1060 if (wacom->pid != pid) {
1061 wacom->pid = pid;
1062 wacom_schedule_work(wacom);
1063 }
1064 } else if (wacom->pid != 0) {
1065 /* disconnected while previously connected */
1066 wacom->pid = 0;
1067 wacom_schedule_work(wacom);
1068 }
1069
1052 return 0; 1070 return 0;
1053} 1071}
1054 1072
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 2c04b6248a56..cffaf6b7e6e9 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -111,6 +111,7 @@ struct wacom_wac {
111 struct wacom_features features; 111 struct wacom_features features;
112 struct wacom_shared *shared; 112 struct wacom_shared *shared;
113 struct input_dev *input; 113 struct input_dev *input;
114 int pid;
114}; 115};
115 116
116#endif 117#endif