aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/tablet/wacom_sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/tablet/wacom_sys.c')
-rw-r--r--drivers/input/tablet/wacom_sys.c91
1 files changed, 82 insertions, 9 deletions
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);