diff options
Diffstat (limited to 'drivers/usb/input/yealink.c')
-rw-r--r-- | drivers/usb/input/yealink.c | 66 |
1 files changed, 35 insertions, 31 deletions
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c index 58a176ef96a5..f526aebea502 100644 --- a/drivers/usb/input/yealink.c +++ b/drivers/usb/input/yealink.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/module.h> | 54 | #include <linux/module.h> |
55 | #include <linux/rwsem.h> | 55 | #include <linux/rwsem.h> |
56 | #include <linux/usb.h> | 56 | #include <linux/usb.h> |
57 | #include <linux/usb_input.h> | ||
57 | 58 | ||
58 | #include "map_to_7segment.h" | 59 | #include "map_to_7segment.h" |
59 | #include "yealink.h" | 60 | #include "yealink.h" |
@@ -101,12 +102,12 @@ static const struct lcd_segment_map { | |||
101 | }; | 102 | }; |
102 | 103 | ||
103 | struct yealink_dev { | 104 | struct yealink_dev { |
104 | struct input_dev idev; /* input device */ | 105 | struct input_dev *idev; /* input device */ |
105 | struct usb_device *udev; /* usb device */ | 106 | struct usb_device *udev; /* usb device */ |
106 | 107 | ||
107 | /* irq input channel */ | 108 | /* irq input channel */ |
108 | struct yld_ctl_packet *irq_data; | 109 | struct yld_ctl_packet *irq_data; |
109 | dma_addr_t irq_dma; | 110 | dma_addr_t irq_dma; |
110 | struct urb *urb_irq; | 111 | struct urb *urb_irq; |
111 | 112 | ||
112 | /* control output channel */ | 113 | /* control output channel */ |
@@ -237,7 +238,7 @@ static int map_p1k_to_key(int scancode) | |||
237 | */ | 238 | */ |
238 | static void report_key(struct yealink_dev *yld, int key, struct pt_regs *regs) | 239 | static void report_key(struct yealink_dev *yld, int key, struct pt_regs *regs) |
239 | { | 240 | { |
240 | struct input_dev *idev = &yld->idev; | 241 | struct input_dev *idev = yld->idev; |
241 | 242 | ||
242 | input_regs(idev, regs); | 243 | input_regs(idev, regs); |
243 | if (yld->key_code >= 0) { | 244 | if (yld->key_code >= 0) { |
@@ -809,8 +810,12 @@ static int usb_cleanup(struct yealink_dev *yld, int err) | |||
809 | } | 810 | } |
810 | if (yld->urb_ctl) | 811 | if (yld->urb_ctl) |
811 | usb_free_urb(yld->urb_ctl); | 812 | usb_free_urb(yld->urb_ctl); |
812 | if (yld->idev.dev) | 813 | if (yld->idev) { |
813 | input_unregister_device(&yld->idev); | 814 | if (err) |
815 | input_free_device(yld->idev); | ||
816 | else | ||
817 | input_unregister_device(yld->idev); | ||
818 | } | ||
814 | if (yld->ctl_req) | 819 | if (yld->ctl_req) |
815 | usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)), | 820 | usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)), |
816 | yld->ctl_req, yld->ctl_req_dma); | 821 | yld->ctl_req, yld->ctl_req_dma); |
@@ -857,7 +862,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
857 | struct usb_host_interface *interface; | 862 | struct usb_host_interface *interface; |
858 | struct usb_endpoint_descriptor *endpoint; | 863 | struct usb_endpoint_descriptor *endpoint; |
859 | struct yealink_dev *yld; | 864 | struct yealink_dev *yld; |
860 | char path[64]; | 865 | struct input_dev *input_dev; |
861 | int ret, pipe, i; | 866 | int ret, pipe, i; |
862 | 867 | ||
863 | i = usb_match(udev); | 868 | i = usb_match(udev); |
@@ -866,17 +871,21 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
866 | 871 | ||
867 | interface = intf->cur_altsetting; | 872 | interface = intf->cur_altsetting; |
868 | endpoint = &interface->endpoint[0].desc; | 873 | endpoint = &interface->endpoint[0].desc; |
869 | if (!(endpoint->bEndpointAddress & 0x80)) | 874 | if (!(endpoint->bEndpointAddress & USB_DIR_IN)) |
870 | return -EIO; | 875 | return -EIO; |
871 | if ((endpoint->bmAttributes & 3) != 3) | 876 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) |
872 | return -EIO; | 877 | return -EIO; |
873 | 878 | ||
874 | if ((yld = kmalloc(sizeof(struct yealink_dev), GFP_KERNEL)) == NULL) | 879 | yld = kzalloc(sizeof(struct yealink_dev), GFP_KERNEL); |
880 | if (!yld) | ||
875 | return -ENOMEM; | 881 | return -ENOMEM; |
876 | 882 | ||
877 | memset(yld, 0, sizeof(*yld)); | ||
878 | yld->udev = udev; | 883 | yld->udev = udev; |
879 | 884 | ||
885 | yld->idev = input_dev = input_allocate_device(); | ||
886 | if (!input_dev) | ||
887 | return usb_cleanup(yld, -ENOMEM); | ||
888 | |||
880 | /* allocate usb buffers */ | 889 | /* allocate usb buffers */ |
881 | yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN, | 890 | yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN, |
882 | SLAB_ATOMIC, &yld->irq_dma); | 891 | SLAB_ATOMIC, &yld->irq_dma); |
@@ -935,42 +944,37 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
935 | yld->urb_ctl->dev = udev; | 944 | yld->urb_ctl->dev = udev; |
936 | 945 | ||
937 | /* find out the physical bus location */ | 946 | /* find out the physical bus location */ |
938 | if (usb_make_path(udev, path, sizeof(path)) > 0) | 947 | usb_make_path(udev, yld->phys, sizeof(yld->phys)); |
939 | snprintf(yld->phys, sizeof(yld->phys)-1, "%s/input0", path); | 948 | strlcat(yld->phys, "/input0", sizeof(yld->phys)); |
940 | 949 | ||
941 | /* register settings for the input device */ | 950 | /* register settings for the input device */ |
942 | init_input_dev(&yld->idev); | 951 | input_dev->name = yld_device[i].name; |
943 | yld->idev.private = yld; | 952 | input_dev->phys = yld->phys; |
944 | yld->idev.id.bustype = BUS_USB; | 953 | usb_to_input_id(udev, &input_dev->id); |
945 | yld->idev.id.vendor = le16_to_cpu(udev->descriptor.idVendor); | 954 | input_dev->cdev.dev = &intf->dev; |
946 | yld->idev.id.product = le16_to_cpu(udev->descriptor.idProduct); | 955 | |
947 | yld->idev.id.version = le16_to_cpu(udev->descriptor.bcdDevice); | 956 | input_dev->private = yld; |
948 | yld->idev.dev = &intf->dev; | 957 | input_dev->open = input_open; |
949 | yld->idev.name = yld_device[i].name; | 958 | input_dev->close = input_close; |
950 | yld->idev.phys = yld->phys; | 959 | /* input_dev->event = input_ev; TODO */ |
951 | /* yld->idev.event = input_ev; TODO */ | ||
952 | yld->idev.open = input_open; | ||
953 | yld->idev.close = input_close; | ||
954 | 960 | ||
955 | /* register available key events */ | 961 | /* register available key events */ |
956 | yld->idev.evbit[0] = BIT(EV_KEY); | 962 | input_dev->evbit[0] = BIT(EV_KEY); |
957 | for (i = 0; i < 256; i++) { | 963 | for (i = 0; i < 256; i++) { |
958 | int k = map_p1k_to_key(i); | 964 | int k = map_p1k_to_key(i); |
959 | if (k >= 0) { | 965 | if (k >= 0) { |
960 | set_bit(k & 0xff, yld->idev.keybit); | 966 | set_bit(k & 0xff, input_dev->keybit); |
961 | if (k >> 8) | 967 | if (k >> 8) |
962 | set_bit(k >> 8, yld->idev.keybit); | 968 | set_bit(k >> 8, input_dev->keybit); |
963 | } | 969 | } |
964 | } | 970 | } |
965 | 971 | ||
966 | printk(KERN_INFO "input: %s on %s\n", yld->idev.name, path); | 972 | input_register_device(yld->idev); |
967 | |||
968 | input_register_device(&yld->idev); | ||
969 | 973 | ||
970 | usb_set_intfdata(intf, yld); | 974 | usb_set_intfdata(intf, yld); |
971 | 975 | ||
972 | /* clear visible elements */ | 976 | /* clear visible elements */ |
973 | for (i=0; i<ARRAY_SIZE(lcdMap); i++) | 977 | for (i = 0; i < ARRAY_SIZE(lcdMap); i++) |
974 | setChar(yld, i, ' '); | 978 | setChar(yld, i, ' '); |
975 | 979 | ||
976 | /* display driver version on LCD line 3 */ | 980 | /* display driver version on LCD line 3 */ |