diff options
Diffstat (limited to 'drivers/input/touchscreen/usbtouchscreen.c')
-rw-r--r-- | drivers/input/touchscreen/usbtouchscreen.c | 325 |
1 files changed, 303 insertions, 22 deletions
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 09a5e7341bd5..99330bbdbac7 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * - GoTop Super_Q2/GogoPen/PenPower tablets | 15 | * - GoTop Super_Q2/GogoPen/PenPower tablets |
16 | * - JASTEC USB touch controller/DigiTech DTR-02U | 16 | * - JASTEC USB touch controller/DigiTech DTR-02U |
17 | * - Zytronic capacitive touchscreen | 17 | * - Zytronic capacitive touchscreen |
18 | * - NEXIO/iNexio | ||
18 | * | 19 | * |
19 | * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch> | 20 | * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch> |
20 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) | 21 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) |
@@ -95,6 +96,7 @@ struct usbtouch_device_info { | |||
95 | 96 | ||
96 | int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); | 97 | int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); |
97 | int (*init) (struct usbtouch_usb *usbtouch); | 98 | int (*init) (struct usbtouch_usb *usbtouch); |
99 | void (*exit) (struct usbtouch_usb *usbtouch); | ||
98 | }; | 100 | }; |
99 | 101 | ||
100 | /* a usbtouch device */ | 102 | /* a usbtouch device */ |
@@ -104,11 +106,12 @@ struct usbtouch_usb { | |||
104 | unsigned char *buffer; | 106 | unsigned char *buffer; |
105 | int buf_len; | 107 | int buf_len; |
106 | struct urb *irq; | 108 | struct urb *irq; |
107 | struct usb_device *udev; | 109 | struct usb_interface *interface; |
108 | struct input_dev *input; | 110 | struct input_dev *input; |
109 | struct usbtouch_device_info *type; | 111 | struct usbtouch_device_info *type; |
110 | char name[128]; | 112 | char name[128]; |
111 | char phys[64]; | 113 | char phys[64]; |
114 | void *priv; | ||
112 | 115 | ||
113 | int x, y; | 116 | int x, y; |
114 | int touch, press; | 117 | int touch, press; |
@@ -133,6 +136,7 @@ enum { | |||
133 | DEVTYPE_E2I, | 136 | DEVTYPE_E2I, |
134 | DEVTYPE_ZYTRONIC, | 137 | DEVTYPE_ZYTRONIC, |
135 | DEVTYPE_TC5UH, | 138 | DEVTYPE_TC5UH, |
139 | DEVTYPE_NEXIO, | ||
136 | }; | 140 | }; |
137 | 141 | ||
138 | #define USB_DEVICE_HID_CLASS(vend, prod) \ | 142 | #define USB_DEVICE_HID_CLASS(vend, prod) \ |
@@ -144,7 +148,7 @@ enum { | |||
144 | .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ | 148 | .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ |
145 | .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE | 149 | .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE |
146 | 150 | ||
147 | static struct usb_device_id usbtouch_devices[] = { | 151 | static const struct usb_device_id usbtouch_devices[] = { |
148 | #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX | 152 | #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX |
149 | /* ignore the HID capable devices, handled by usbhid */ | 153 | /* ignore the HID capable devices, handled by usbhid */ |
150 | {USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE}, | 154 | {USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE}, |
@@ -222,6 +226,14 @@ static struct usb_device_id usbtouch_devices[] = { | |||
222 | {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH}, | 226 | {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH}, |
223 | #endif | 227 | #endif |
224 | 228 | ||
229 | #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO | ||
230 | /* data interface only */ | ||
231 | {USB_DEVICE_AND_INTERFACE_INFO(0x10f0, 0x2002, 0x0a, 0x00, 0x00), | ||
232 | .driver_info = DEVTYPE_NEXIO}, | ||
233 | {USB_DEVICE_AND_INTERFACE_INFO(0x1870, 0x0001, 0x0a, 0x00, 0x00), | ||
234 | .driver_info = DEVTYPE_NEXIO}, | ||
235 | #endif | ||
236 | |||
225 | {} | 237 | {} |
226 | }; | 238 | }; |
227 | 239 | ||
@@ -234,8 +246,9 @@ static struct usb_device_id usbtouch_devices[] = { | |||
234 | static int e2i_init(struct usbtouch_usb *usbtouch) | 246 | static int e2i_init(struct usbtouch_usb *usbtouch) |
235 | { | 247 | { |
236 | int ret; | 248 | int ret; |
249 | struct usb_device *udev = interface_to_usbdev(usbtouch->interface); | ||
237 | 250 | ||
238 | ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), | 251 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
239 | 0x01, 0x02, 0x0000, 0x0081, | 252 | 0x01, 0x02, 0x0000, 0x0081, |
240 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 253 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
241 | 254 | ||
@@ -344,8 +357,9 @@ static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
344 | static int mtouch_init(struct usbtouch_usb *usbtouch) | 357 | static int mtouch_init(struct usbtouch_usb *usbtouch) |
345 | { | 358 | { |
346 | int ret, i; | 359 | int ret, i; |
360 | struct usb_device *udev = interface_to_usbdev(usbtouch->interface); | ||
347 | 361 | ||
348 | ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), | 362 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
349 | MTOUCHUSB_RESET, | 363 | MTOUCHUSB_RESET, |
350 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 364 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
351 | 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); | 365 | 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); |
@@ -356,7 +370,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) | |||
356 | msleep(150); | 370 | msleep(150); |
357 | 371 | ||
358 | for (i = 0; i < 3; i++) { | 372 | for (i = 0; i < 3; i++) { |
359 | ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), | 373 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
360 | MTOUCHUSB_ASYNC_REPORT, | 374 | MTOUCHUSB_ASYNC_REPORT, |
361 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 375 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
362 | 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); | 376 | 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); |
@@ -489,7 +503,7 @@ static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
489 | 503 | ||
490 | static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) | 504 | static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) |
491 | { | 505 | { |
492 | struct usb_device *dev = usbtouch->udev; | 506 | struct usb_device *dev = interface_to_usbdev(usbtouch->interface); |
493 | int ret = -ENOMEM; | 507 | int ret = -ENOMEM; |
494 | unsigned char *buf; | 508 | unsigned char *buf; |
495 | 509 | ||
@@ -618,8 +632,8 @@ static int idealtek_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
618 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH | 632 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH |
619 | static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | 633 | static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
620 | { | 634 | { |
621 | dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1] ; | 635 | dev->x = (pkt[2] << 8) | pkt[1]; |
622 | dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3] ; | 636 | dev->y = (pkt[4] << 8) | pkt[3]; |
623 | dev->press = pkt[5] & 0xff; | 637 | dev->press = pkt[5] & 0xff; |
624 | dev->touch = pkt[0] & 0x01; | 638 | dev->touch = pkt[0] & 0x01; |
625 | 639 | ||
@@ -690,6 +704,229 @@ static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
690 | #endif | 704 | #endif |
691 | 705 | ||
692 | /***************************************************************************** | 706 | /***************************************************************************** |
707 | * NEXIO Part | ||
708 | */ | ||
709 | #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO | ||
710 | |||
711 | #define NEXIO_TIMEOUT 5000 | ||
712 | #define NEXIO_BUFSIZE 1024 | ||
713 | #define NEXIO_THRESHOLD 50 | ||
714 | |||
715 | struct nexio_priv { | ||
716 | struct urb *ack; | ||
717 | unsigned char *ack_buf; | ||
718 | }; | ||
719 | |||
720 | struct nexio_touch_packet { | ||
721 | u8 flags; /* 0xe1 = touch, 0xe1 = release */ | ||
722 | __be16 data_len; /* total bytes of touch data */ | ||
723 | __be16 x_len; /* bytes for X axis */ | ||
724 | __be16 y_len; /* bytes for Y axis */ | ||
725 | u8 data[]; | ||
726 | } __attribute__ ((packed)); | ||
727 | |||
728 | static unsigned char nexio_ack_pkt[2] = { 0xaa, 0x02 }; | ||
729 | static unsigned char nexio_init_pkt[4] = { 0x82, 0x04, 0x0a, 0x0f }; | ||
730 | |||
731 | static void nexio_ack_complete(struct urb *urb) | ||
732 | { | ||
733 | } | ||
734 | |||
735 | static int nexio_init(struct usbtouch_usb *usbtouch) | ||
736 | { | ||
737 | struct usb_device *dev = interface_to_usbdev(usbtouch->interface); | ||
738 | struct usb_host_interface *interface = usbtouch->interface->cur_altsetting; | ||
739 | struct nexio_priv *priv; | ||
740 | int ret = -ENOMEM; | ||
741 | int actual_len, i; | ||
742 | unsigned char *buf; | ||
743 | char *firmware_ver = NULL, *device_name = NULL; | ||
744 | int input_ep = 0, output_ep = 0; | ||
745 | |||
746 | /* find first input and output endpoint */ | ||
747 | for (i = 0; i < interface->desc.bNumEndpoints; i++) { | ||
748 | if (!input_ep && | ||
749 | usb_endpoint_dir_in(&interface->endpoint[i].desc)) | ||
750 | input_ep = interface->endpoint[i].desc.bEndpointAddress; | ||
751 | if (!output_ep && | ||
752 | usb_endpoint_dir_out(&interface->endpoint[i].desc)) | ||
753 | output_ep = interface->endpoint[i].desc.bEndpointAddress; | ||
754 | } | ||
755 | if (!input_ep || !output_ep) | ||
756 | return -ENXIO; | ||
757 | |||
758 | buf = kmalloc(NEXIO_BUFSIZE, GFP_KERNEL); | ||
759 | if (!buf) | ||
760 | goto out_buf; | ||
761 | |||
762 | /* two empty reads */ | ||
763 | for (i = 0; i < 2; i++) { | ||
764 | ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep), | ||
765 | buf, NEXIO_BUFSIZE, &actual_len, | ||
766 | NEXIO_TIMEOUT); | ||
767 | if (ret < 0) | ||
768 | goto out_buf; | ||
769 | } | ||
770 | |||
771 | /* send init command */ | ||
772 | memcpy(buf, nexio_init_pkt, sizeof(nexio_init_pkt)); | ||
773 | ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, output_ep), | ||
774 | buf, sizeof(nexio_init_pkt), &actual_len, | ||
775 | NEXIO_TIMEOUT); | ||
776 | if (ret < 0) | ||
777 | goto out_buf; | ||
778 | |||
779 | /* read replies */ | ||
780 | for (i = 0; i < 3; i++) { | ||
781 | memset(buf, 0, NEXIO_BUFSIZE); | ||
782 | ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep), | ||
783 | buf, NEXIO_BUFSIZE, &actual_len, | ||
784 | NEXIO_TIMEOUT); | ||
785 | if (ret < 0 || actual_len < 1 || buf[1] != actual_len) | ||
786 | continue; | ||
787 | switch (buf[0]) { | ||
788 | case 0x83: /* firmware version */ | ||
789 | if (!firmware_ver) | ||
790 | firmware_ver = kstrdup(&buf[2], GFP_KERNEL); | ||
791 | break; | ||
792 | case 0x84: /* device name */ | ||
793 | if (!device_name) | ||
794 | device_name = kstrdup(&buf[2], GFP_KERNEL); | ||
795 | break; | ||
796 | } | ||
797 | } | ||
798 | |||
799 | printk(KERN_INFO "Nexio device: %s, firmware version: %s\n", | ||
800 | device_name, firmware_ver); | ||
801 | |||
802 | kfree(firmware_ver); | ||
803 | kfree(device_name); | ||
804 | |||
805 | /* prepare ACK URB */ | ||
806 | ret = -ENOMEM; | ||
807 | |||
808 | usbtouch->priv = kmalloc(sizeof(struct nexio_priv), GFP_KERNEL); | ||
809 | if (!usbtouch->priv) | ||
810 | goto out_buf; | ||
811 | |||
812 | priv = usbtouch->priv; | ||
813 | |||
814 | priv->ack_buf = kmalloc(sizeof(nexio_ack_pkt), GFP_KERNEL); | ||
815 | if (!priv->ack_buf) | ||
816 | goto err_priv; | ||
817 | |||
818 | memcpy(priv->ack_buf, nexio_ack_pkt, sizeof(nexio_ack_pkt)); | ||
819 | |||
820 | priv->ack = usb_alloc_urb(0, GFP_KERNEL); | ||
821 | if (!priv->ack) { | ||
822 | dbg("%s - usb_alloc_urb failed: usbtouch->ack", __func__); | ||
823 | goto err_ack_buf; | ||
824 | } | ||
825 | |||
826 | usb_fill_bulk_urb(priv->ack, dev, usb_sndbulkpipe(dev, output_ep), | ||
827 | priv->ack_buf, sizeof(nexio_ack_pkt), | ||
828 | nexio_ack_complete, usbtouch); | ||
829 | ret = 0; | ||
830 | goto out_buf; | ||
831 | |||
832 | err_ack_buf: | ||
833 | kfree(priv->ack_buf); | ||
834 | err_priv: | ||
835 | kfree(priv); | ||
836 | out_buf: | ||
837 | kfree(buf); | ||
838 | return ret; | ||
839 | } | ||
840 | |||
841 | static void nexio_exit(struct usbtouch_usb *usbtouch) | ||
842 | { | ||
843 | struct nexio_priv *priv = usbtouch->priv; | ||
844 | |||
845 | usb_kill_urb(priv->ack); | ||
846 | usb_free_urb(priv->ack); | ||
847 | kfree(priv->ack_buf); | ||
848 | kfree(priv); | ||
849 | } | ||
850 | |||
851 | static int nexio_read_data(struct usbtouch_usb *usbtouch, unsigned char *pkt) | ||
852 | { | ||
853 | int x, y, begin_x, begin_y, end_x, end_y, w, h, ret; | ||
854 | struct nexio_touch_packet *packet = (void *) pkt; | ||
855 | struct nexio_priv *priv = usbtouch->priv; | ||
856 | |||
857 | /* got touch data? */ | ||
858 | if ((pkt[0] & 0xe0) != 0xe0) | ||
859 | return 0; | ||
860 | |||
861 | /* send ACK */ | ||
862 | ret = usb_submit_urb(priv->ack, GFP_ATOMIC); | ||
863 | |||
864 | if (!usbtouch->type->max_xc) { | ||
865 | usbtouch->type->max_xc = 2 * be16_to_cpu(packet->x_len); | ||
866 | input_set_abs_params(usbtouch->input, ABS_X, 0, | ||
867 | 2 * be16_to_cpu(packet->x_len), 0, 0); | ||
868 | usbtouch->type->max_yc = 2 * be16_to_cpu(packet->y_len); | ||
869 | input_set_abs_params(usbtouch->input, ABS_Y, 0, | ||
870 | 2 * be16_to_cpu(packet->y_len), 0, 0); | ||
871 | } | ||
872 | /* | ||
873 | * The device reports state of IR sensors on X and Y axes. | ||
874 | * Each byte represents "darkness" percentage (0-100) of one element. | ||
875 | * 17" touchscreen reports only 64 x 52 bytes so the resolution is low. | ||
876 | * This also means that there's a limited multi-touch capability but | ||
877 | * it's disabled (and untested) here as there's no X driver for that. | ||
878 | */ | ||
879 | begin_x = end_x = begin_y = end_y = -1; | ||
880 | for (x = 0; x < be16_to_cpu(packet->x_len); x++) { | ||
881 | if (begin_x == -1 && packet->data[x] > NEXIO_THRESHOLD) { | ||
882 | begin_x = x; | ||
883 | continue; | ||
884 | } | ||
885 | if (end_x == -1 && begin_x != -1 && packet->data[x] < NEXIO_THRESHOLD) { | ||
886 | end_x = x - 1; | ||
887 | for (y = be16_to_cpu(packet->x_len); | ||
888 | y < be16_to_cpu(packet->data_len); y++) { | ||
889 | if (begin_y == -1 && packet->data[y] > NEXIO_THRESHOLD) { | ||
890 | begin_y = y - be16_to_cpu(packet->x_len); | ||
891 | continue; | ||
892 | } | ||
893 | if (end_y == -1 && | ||
894 | begin_y != -1 && packet->data[y] < NEXIO_THRESHOLD) { | ||
895 | end_y = y - 1 - be16_to_cpu(packet->x_len); | ||
896 | w = end_x - begin_x; | ||
897 | h = end_y - begin_y; | ||
898 | #if 0 | ||
899 | /* multi-touch */ | ||
900 | input_report_abs(usbtouch->input, | ||
901 | ABS_MT_TOUCH_MAJOR, max(w,h)); | ||
902 | input_report_abs(usbtouch->input, | ||
903 | ABS_MT_TOUCH_MINOR, min(x,h)); | ||
904 | input_report_abs(usbtouch->input, | ||
905 | ABS_MT_POSITION_X, 2*begin_x+w); | ||
906 | input_report_abs(usbtouch->input, | ||
907 | ABS_MT_POSITION_Y, 2*begin_y+h); | ||
908 | input_report_abs(usbtouch->input, | ||
909 | ABS_MT_ORIENTATION, w > h); | ||
910 | input_mt_sync(usbtouch->input); | ||
911 | #endif | ||
912 | /* single touch */ | ||
913 | usbtouch->x = 2 * begin_x + w; | ||
914 | usbtouch->y = 2 * begin_y + h; | ||
915 | usbtouch->touch = packet->flags & 0x01; | ||
916 | begin_y = end_y = -1; | ||
917 | return 1; | ||
918 | } | ||
919 | } | ||
920 | begin_x = end_x = -1; | ||
921 | } | ||
922 | |||
923 | } | ||
924 | return 0; | ||
925 | } | ||
926 | #endif | ||
927 | |||
928 | |||
929 | /***************************************************************************** | ||
693 | * the different device descriptors | 930 | * the different device descriptors |
694 | */ | 931 | */ |
695 | #ifdef MULTI_PACKET | 932 | #ifdef MULTI_PACKET |
@@ -809,9 +1046,9 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { | |||
809 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH | 1046 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH |
810 | [DEVTYPE_GENERAL_TOUCH] = { | 1047 | [DEVTYPE_GENERAL_TOUCH] = { |
811 | .min_xc = 0x0, | 1048 | .min_xc = 0x0, |
812 | .max_xc = 0x0500, | 1049 | .max_xc = 0x7fff, |
813 | .min_yc = 0x0, | 1050 | .min_yc = 0x0, |
814 | .max_yc = 0x0500, | 1051 | .max_yc = 0x7fff, |
815 | .rept_size = 7, | 1052 | .rept_size = 7, |
816 | .read_data = general_touch_read_data, | 1053 | .read_data = general_touch_read_data, |
817 | }, | 1054 | }, |
@@ -873,6 +1110,16 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { | |||
873 | .read_data = tc5uh_read_data, | 1110 | .read_data = tc5uh_read_data, |
874 | }, | 1111 | }, |
875 | #endif | 1112 | #endif |
1113 | |||
1114 | #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO | ||
1115 | [DEVTYPE_NEXIO] = { | ||
1116 | .rept_size = 128, | ||
1117 | .irq_always = true, | ||
1118 | .read_data = nexio_read_data, | ||
1119 | .init = nexio_init, | ||
1120 | .exit = nexio_exit, | ||
1121 | }, | ||
1122 | #endif | ||
876 | }; | 1123 | }; |
877 | 1124 | ||
878 | 1125 | ||
@@ -998,6 +1245,7 @@ static void usbtouch_irq(struct urb *urb) | |||
998 | case -ECONNRESET: | 1245 | case -ECONNRESET: |
999 | case -ENOENT: | 1246 | case -ENOENT: |
1000 | case -ESHUTDOWN: | 1247 | case -ESHUTDOWN: |
1248 | case -EPIPE: | ||
1001 | /* this urb is terminated, clean up */ | 1249 | /* this urb is terminated, clean up */ |
1002 | dbg("%s - urb shutting down with status: %d", | 1250 | dbg("%s - urb shutting down with status: %d", |
1003 | __func__, urb->status); | 1251 | __func__, urb->status); |
@@ -1021,7 +1269,7 @@ static int usbtouch_open(struct input_dev *input) | |||
1021 | { | 1269 | { |
1022 | struct usbtouch_usb *usbtouch = input_get_drvdata(input); | 1270 | struct usbtouch_usb *usbtouch = input_get_drvdata(input); |
1023 | 1271 | ||
1024 | usbtouch->irq->dev = usbtouch->udev; | 1272 | usbtouch->irq->dev = interface_to_usbdev(usbtouch->interface); |
1025 | 1273 | ||
1026 | if (!usbtouch->type->irq_always) { | 1274 | if (!usbtouch->type->irq_always) { |
1027 | if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) | 1275 | if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) |
@@ -1048,13 +1296,23 @@ static void usbtouch_free_buffers(struct usb_device *udev, | |||
1048 | kfree(usbtouch->buffer); | 1296 | kfree(usbtouch->buffer); |
1049 | } | 1297 | } |
1050 | 1298 | ||
1299 | static struct usb_endpoint_descriptor * | ||
1300 | usbtouch_get_input_endpoint(struct usb_host_interface *interface) | ||
1301 | { | ||
1302 | int i; | ||
1303 | |||
1304 | for (i = 0; i < interface->desc.bNumEndpoints; i++) | ||
1305 | if (usb_endpoint_dir_in(&interface->endpoint[i].desc)) | ||
1306 | return &interface->endpoint[i].desc; | ||
1307 | |||
1308 | return NULL; | ||
1309 | } | ||
1051 | 1310 | ||
1052 | static int usbtouch_probe(struct usb_interface *intf, | 1311 | static int usbtouch_probe(struct usb_interface *intf, |
1053 | const struct usb_device_id *id) | 1312 | const struct usb_device_id *id) |
1054 | { | 1313 | { |
1055 | struct usbtouch_usb *usbtouch; | 1314 | struct usbtouch_usb *usbtouch; |
1056 | struct input_dev *input_dev; | 1315 | struct input_dev *input_dev; |
1057 | struct usb_host_interface *interface; | ||
1058 | struct usb_endpoint_descriptor *endpoint; | 1316 | struct usb_endpoint_descriptor *endpoint; |
1059 | struct usb_device *udev = interface_to_usbdev(intf); | 1317 | struct usb_device *udev = interface_to_usbdev(intf); |
1060 | struct usbtouch_device_info *type; | 1318 | struct usbtouch_device_info *type; |
@@ -1064,8 +1322,9 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
1064 | if (id->driver_info == DEVTYPE_IGNORE) | 1322 | if (id->driver_info == DEVTYPE_IGNORE) |
1065 | return -ENODEV; | 1323 | return -ENODEV; |
1066 | 1324 | ||
1067 | interface = intf->cur_altsetting; | 1325 | endpoint = usbtouch_get_input_endpoint(intf->cur_altsetting); |
1068 | endpoint = &interface->endpoint[0].desc; | 1326 | if (!endpoint) |
1327 | return -ENXIO; | ||
1069 | 1328 | ||
1070 | usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); | 1329 | usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); |
1071 | input_dev = input_allocate_device(); | 1330 | input_dev = input_allocate_device(); |
@@ -1094,7 +1353,7 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
1094 | goto out_free_buffers; | 1353 | goto out_free_buffers; |
1095 | } | 1354 | } |
1096 | 1355 | ||
1097 | usbtouch->udev = udev; | 1356 | usbtouch->interface = intf; |
1098 | usbtouch->input = input_dev; | 1357 | usbtouch->input = input_dev; |
1099 | 1358 | ||
1100 | if (udev->manufacturer) | 1359 | if (udev->manufacturer) |
@@ -1133,12 +1392,18 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
1133 | input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, | 1392 | input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, |
1134 | type->max_press, 0, 0); | 1393 | type->max_press, 0, 0); |
1135 | 1394 | ||
1136 | usb_fill_int_urb(usbtouch->irq, usbtouch->udev, | 1395 | if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT) |
1137 | usb_rcvintpipe(usbtouch->udev, endpoint->bEndpointAddress), | 1396 | usb_fill_int_urb(usbtouch->irq, udev, |
1397 | usb_rcvintpipe(udev, endpoint->bEndpointAddress), | ||
1138 | usbtouch->data, type->rept_size, | 1398 | usbtouch->data, type->rept_size, |
1139 | usbtouch_irq, usbtouch, endpoint->bInterval); | 1399 | usbtouch_irq, usbtouch, endpoint->bInterval); |
1400 | else | ||
1401 | usb_fill_bulk_urb(usbtouch->irq, udev, | ||
1402 | usb_rcvbulkpipe(udev, endpoint->bEndpointAddress), | ||
1403 | usbtouch->data, type->rept_size, | ||
1404 | usbtouch_irq, usbtouch); | ||
1140 | 1405 | ||
1141 | usbtouch->irq->dev = usbtouch->udev; | 1406 | usbtouch->irq->dev = udev; |
1142 | usbtouch->irq->transfer_dma = usbtouch->data_dma; | 1407 | usbtouch->irq->transfer_dma = usbtouch->data_dma; |
1143 | usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1408 | usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1144 | 1409 | ||
@@ -1147,23 +1412,37 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
1147 | err = type->init(usbtouch); | 1412 | err = type->init(usbtouch); |
1148 | if (err) { | 1413 | if (err) { |
1149 | dbg("%s - type->init() failed, err: %d", __func__, err); | 1414 | dbg("%s - type->init() failed, err: %d", __func__, err); |
1150 | goto out_free_buffers; | 1415 | goto out_free_urb; |
1151 | } | 1416 | } |
1152 | } | 1417 | } |
1153 | 1418 | ||
1154 | err = input_register_device(usbtouch->input); | 1419 | err = input_register_device(usbtouch->input); |
1155 | if (err) { | 1420 | if (err) { |
1156 | dbg("%s - input_register_device failed, err: %d", __func__, err); | 1421 | dbg("%s - input_register_device failed, err: %d", __func__, err); |
1157 | goto out_free_buffers; | 1422 | goto out_do_exit; |
1158 | } | 1423 | } |
1159 | 1424 | ||
1160 | usb_set_intfdata(intf, usbtouch); | 1425 | usb_set_intfdata(intf, usbtouch); |
1161 | 1426 | ||
1162 | if (usbtouch->type->irq_always) | 1427 | if (usbtouch->type->irq_always) { |
1163 | usb_submit_urb(usbtouch->irq, GFP_KERNEL); | 1428 | err = usb_submit_urb(usbtouch->irq, GFP_KERNEL); |
1429 | if (err) { | ||
1430 | err("%s - usb_submit_urb failed with result: %d", | ||
1431 | __func__, err); | ||
1432 | goto out_unregister_input; | ||
1433 | } | ||
1434 | } | ||
1164 | 1435 | ||
1165 | return 0; | 1436 | return 0; |
1166 | 1437 | ||
1438 | out_unregister_input: | ||
1439 | input_unregister_device(input_dev); | ||
1440 | input_dev = NULL; | ||
1441 | out_do_exit: | ||
1442 | if (type->exit) | ||
1443 | type->exit(usbtouch); | ||
1444 | out_free_urb: | ||
1445 | usb_free_urb(usbtouch->irq); | ||
1167 | out_free_buffers: | 1446 | out_free_buffers: |
1168 | usbtouch_free_buffers(udev, usbtouch); | 1447 | usbtouch_free_buffers(udev, usbtouch); |
1169 | out_free: | 1448 | out_free: |
@@ -1186,6 +1465,8 @@ static void usbtouch_disconnect(struct usb_interface *intf) | |||
1186 | /* this will stop IO via close */ | 1465 | /* this will stop IO via close */ |
1187 | input_unregister_device(usbtouch->input); | 1466 | input_unregister_device(usbtouch->input); |
1188 | usb_free_urb(usbtouch->irq); | 1467 | usb_free_urb(usbtouch->irq); |
1468 | if (usbtouch->type->exit) | ||
1469 | usbtouch->type->exit(usbtouch); | ||
1189 | usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); | 1470 | usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); |
1190 | kfree(usbtouch); | 1471 | kfree(usbtouch); |
1191 | } | 1472 | } |