aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Young <sean@mess.org>2006-05-02 07:44:43 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-21 18:04:10 -0400
commit69165c29bb4db9bafead7c6574c73ce245965f3a (patch)
tree64e39463bb48cb1a40393640222e4ef69a2b308b
parenta01c4ef1cc9622fcce5c10ddb8e9e7f76206959e (diff)
[PATCH] USB Phidget InterfaceKit: make inputs pollable and new device support
Make inputs pollable using sysfs_notify and add support for the Phidget InterfaceKit 0/16/16. Various cleanups. Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Daniel Saakes <daniel@saakes.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/misc/phidgetkit.c303
1 files changed, 218 insertions, 85 deletions
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c
index 997db5d8e35b..13aeea2026cc 100644
--- a/drivers/usb/misc/phidgetkit.c
+++ b/drivers/usb/misc/phidgetkit.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * USB PhidgetInterfaceKit driver 1.0 2 * USB PhidgetInterfaceKit driver 1.0
3 * 3 *
4 * Copyright (C) 2004 Sean Young <sean@mess.org> 4 * Copyright (C) 2004, 2006 Sean Young <sean@mess.org>
5 * Copyright (C) 2005 Daniel Saakes <daniel@saakes.net>
5 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> 6 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
@@ -25,6 +26,7 @@
25 26
26#define USB_VENDOR_ID_GLAB 0x06c2 27#define USB_VENDOR_ID_GLAB 0x06c2
27#define USB_DEVICE_ID_INTERFACEKIT004 0x0040 28#define USB_DEVICE_ID_INTERFACEKIT004 0x0040
29#define USB_DEVICE_ID_INTERFACEKIT01616 0x0044
28#define USB_DEVICE_ID_INTERFACEKIT888 0x0045 30#define USB_DEVICE_ID_INTERFACEKIT888 0x0045
29#define USB_DEVICE_ID_INTERFACEKIT047 0x0051 31#define USB_DEVICE_ID_INTERFACEKIT047 0x0051
30#define USB_DEVICE_ID_INTERFACEKIT088 0x0053 32#define USB_DEVICE_ID_INTERFACEKIT088 0x0053
@@ -32,7 +34,9 @@
32#define USB_VENDOR_ID_WISEGROUP 0x0925 34#define USB_VENDOR_ID_WISEGROUP 0x0925
33#define USB_DEVICE_ID_INTERFACEKIT884 0x8201 35#define USB_DEVICE_ID_INTERFACEKIT884 0x8201
34 36
35#define MAX_INTERFACES 8 37#define MAX_INTERFACES 16
38
39#define URB_INT_SIZE 8
36 40
37struct driver_interfacekit { 41struct driver_interfacekit {
38 int sensors; 42 int sensors;
@@ -52,19 +56,24 @@ ifkit(8, 8, 8, 0);
52ifkit(0, 4, 7, 1); 56ifkit(0, 4, 7, 1);
53ifkit(8, 8, 4, 0); 57ifkit(8, 8, 4, 0);
54ifkit(0, 8, 8, 1); 58ifkit(0, 8, 8, 1);
59ifkit(0, 16, 16, 0);
55 60
56struct phidget_interfacekit { 61struct interfacekit {
57 struct usb_device *udev; 62 struct usb_device *udev;
58 struct usb_interface *intf; 63 struct usb_interface *intf;
59 struct driver_interfacekit *ifkit; 64 struct driver_interfacekit *ifkit;
60 int outputs[MAX_INTERFACES]; 65 unsigned long outputs;
61 int inputs[MAX_INTERFACES]; 66 u8 inputs[MAX_INTERFACES];
62 int sensors[MAX_INTERFACES]; 67 u16 sensors[MAX_INTERFACES];
63 u8 lcd_files_on; 68 u8 lcd_files_on;
64 69
65 struct urb *irq; 70 struct urb *irq;
66 unsigned char *data; 71 unsigned char *data;
67 dma_addr_t data_dma; 72 dma_addr_t data_dma;
73
74 struct work_struct do_notify;
75 unsigned long input_events;
76 unsigned long sensor_events;
68}; 77};
69 78
70static struct usb_device_id id_table[] = { 79static struct usb_device_id id_table[] = {
@@ -76,33 +85,33 @@ static struct usb_device_id id_table[] = {
76 .driver_info = (kernel_ulong_t)&ph_047}, 85 .driver_info = (kernel_ulong_t)&ph_047},
77 {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT088), 86 {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT088),
78 .driver_info = (kernel_ulong_t)&ph_088}, 87 .driver_info = (kernel_ulong_t)&ph_088},
88 {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT01616),
89 .driver_info = (kernel_ulong_t)&ph_01616},
79 {USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_INTERFACEKIT884), 90 {USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_INTERFACEKIT884),
80 .driver_info = (kernel_ulong_t)&ph_884}, 91 .driver_info = (kernel_ulong_t)&ph_884},
81 {} 92 {}
82}; 93};
83MODULE_DEVICE_TABLE(usb, id_table); 94MODULE_DEVICE_TABLE(usb, id_table);
84 95
85static int change_outputs(struct phidget_interfacekit *kit, int output_num, int enable) 96static int change_outputs(struct interfacekit *kit, int output_num, int enable)
86{ 97{
87 unsigned char *buffer; 98 u8 *buffer;
88 int retval; 99 int retval;
89 int n; 100
101 if (enable)
102 set_bit(output_num, &kit->outputs);
103 else
104 clear_bit(output_num, &kit->outputs);
90 105
91 buffer = kzalloc(4, GFP_KERNEL); 106 buffer = kzalloc(4, GFP_KERNEL);
92 if (!buffer) { 107 if (!buffer) {
93 dev_err(&kit->udev->dev, "%s - out of memory\n", 108 dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__);
94 __FUNCTION__);
95 return -ENOMEM; 109 return -ENOMEM;
96 } 110 }
111 buffer[0] = (u8)kit->outputs;
112 buffer[1] = (u8)(kit->outputs >> 8);
97 113
98 kit->outputs[output_num] = enable; 114 dev_dbg(&kit->udev->dev, "sending data: 0x%04x\n", (u16)kit->outputs);
99 for (n=0; n<8; n++) {
100 if (kit->outputs[n]) {
101 buffer[0] |= 1 << n;
102 }
103 }
104
105 dev_dbg(&kit->udev->dev, "sending data: %02x\n", buffer[0]);
106 115
107 retval = usb_control_msg(kit->udev, 116 retval = usb_control_msg(kit->udev,
108 usb_sndctrlpipe(kit->udev, 0), 117 usb_sndctrlpipe(kit->udev, 0),
@@ -116,10 +125,10 @@ static int change_outputs(struct phidget_interfacekit *kit, int output_num, int
116 return retval < 0 ? retval : 0; 125 return retval < 0 ? retval : 0;
117} 126}
118 127
119static int change_string(struct phidget_interfacekit *kit, const char *display, unsigned char row) 128static int change_string(struct interfacekit *kit, const char *display, unsigned char row)
120{ 129{
121 unsigned char *buffer; 130 unsigned char *buffer;
122 unsigned char *form_buffer; 131 unsigned char *form_buffer;
123 int retval = -ENOMEM; 132 int retval = -ENOMEM;
124 int i,j, len, buf_ptr; 133 int i,j, len, buf_ptr;
125 134
@@ -175,7 +184,7 @@ exit:
175static ssize_t lcd_line_##number(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ 184static ssize_t lcd_line_##number(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
176{ \ 185{ \
177 struct usb_interface *intf = to_usb_interface(dev); \ 186 struct usb_interface *intf = to_usb_interface(dev); \
178 struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ 187 struct interfacekit *kit = usb_get_intfdata(intf); \
179 change_string(kit, buf, number - 1); \ 188 change_string(kit, buf, number - 1); \
180 return count; \ 189 return count; \
181} \ 190} \
@@ -186,7 +195,7 @@ set_lcd_line(2);
186static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 195static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
187{ 196{
188 struct usb_interface *intf = to_usb_interface(dev); 197 struct usb_interface *intf = to_usb_interface(dev);
189 struct phidget_interfacekit *kit = usb_get_intfdata(intf); 198 struct interfacekit *kit = usb_get_intfdata(intf);
190 int enabled; 199 int enabled;
191 unsigned char *buffer; 200 unsigned char *buffer;
192 int retval = -ENOMEM; 201 int retval = -ENOMEM;
@@ -220,7 +229,7 @@ exit:
220} 229}
221static DEVICE_ATTR(backlight, S_IWUGO, NULL, set_backlight); 230static DEVICE_ATTR(backlight, S_IWUGO, NULL, set_backlight);
222 231
223static void remove_lcd_files(struct phidget_interfacekit *kit) 232static void remove_lcd_files(struct interfacekit *kit)
224{ 233{
225 if (kit->lcd_files_on) { 234 if (kit->lcd_files_on) {
226 dev_dbg(&kit->udev->dev, "Removing lcd files\n"); 235 dev_dbg(&kit->udev->dev, "Removing lcd files\n");
@@ -233,7 +242,7 @@ static void remove_lcd_files(struct phidget_interfacekit *kit)
233static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 242static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
234{ 243{
235 struct usb_interface *intf = to_usb_interface(dev); 244 struct usb_interface *intf = to_usb_interface(dev);
236 struct phidget_interfacekit *kit = usb_get_intfdata(intf); 245 struct interfacekit *kit = usb_get_intfdata(intf);
237 int enable; 246 int enable;
238 247
239 if (kit->ifkit->has_lcd == 0) 248 if (kit->ifkit->has_lcd == 0)
@@ -263,10 +272,10 @@ static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files);
263 272
264static void interfacekit_irq(struct urb *urb, struct pt_regs *regs) 273static void interfacekit_irq(struct urb *urb, struct pt_regs *regs)
265{ 274{
266 struct phidget_interfacekit *kit = urb->context; 275 struct interfacekit *kit = urb->context;
267 unsigned char *buffer = kit->data; 276 unsigned char *buffer = kit->data;
277 int i, level, sensor;
268 int status; 278 int status;
269 int n;
270 279
271 switch (urb->status) { 280 switch (urb->status) {
272 case 0: /* success */ 281 case 0: /* success */
@@ -280,22 +289,63 @@ static void interfacekit_irq(struct urb *urb, struct pt_regs *regs)
280 goto resubmit; 289 goto resubmit;
281 } 290 }
282 291
283 for (n=0; n<8; n++) { 292 /* digital inputs */
284 kit->inputs[n] = buffer[1] & (1 << n) ? 1 : 0; 293 if (kit->ifkit->inputs == 16) {
294 for (i=0; i < 8; i++) {
295 level = (buffer[0] >> i) & 1;
296 if (kit->inputs[i] != level) {
297 kit->inputs[i] = level;
298 set_bit(i, &kit->input_events);
299 }
300 level = (buffer[1] >> i) & 1;
301 if (kit->inputs[8 + i] != level) {
302 kit->inputs[8 + i] = level;
303 set_bit(8 + i, &kit->input_events);
304 }
305 }
306 }
307 else if (kit->ifkit->inputs == 8) {
308 for (i=0; i < 8; i++) {
309 level = (buffer[1] >> i) & 1;
310 if (kit->inputs[i] != level) {
311 kit->inputs[i] = level;
312 set_bit(i, &kit->input_events);
313 }
314 }
285 } 315 }
286 316
287 if (buffer[0] & 1) { 317 /* analog inputs */
288 kit->sensors[4] = buffer[2] + (buffer[3] & 0x0f) * 256; 318 if (kit->ifkit->sensors) {
289 kit->sensors[5] = buffer[4] + (buffer[3] & 0xf0) * 16; 319 sensor = (buffer[0] & 1) ? 4 : 0;
290 kit->sensors[6] = buffer[5] + (buffer[6] & 0x0f) * 256; 320
291 kit->sensors[7] = buffer[7] + (buffer[6] & 0xf0) * 16; 321 level = buffer[2] + (buffer[3] & 0x0f) * 256;
292 } else { 322 if (level != kit->sensors[sensor]) {
293 kit->sensors[0] = buffer[2] + (buffer[3] & 0x0f) * 256; 323 kit->sensors[sensor] = level;
294 kit->sensors[1] = buffer[4] + (buffer[3] & 0xf0) * 16; 324 set_bit(sensor, &kit->sensor_events);
295 kit->sensors[2] = buffer[5] + (buffer[6] & 0x0f) * 256; 325 }
296 kit->sensors[3] = buffer[7] + (buffer[6] & 0xf0) * 16; 326 sensor++;
327 level = buffer[4] + (buffer[3] & 0xf0) * 16;
328 if (level != kit->sensors[sensor]) {
329 kit->sensors[sensor] = level;
330 set_bit(sensor, &kit->sensor_events);
331 }
332 sensor++;
333 level = buffer[5] + (buffer[6] & 0x0f) * 256;
334 if (level != kit->sensors[sensor]) {
335 kit->sensors[sensor] = level;
336 set_bit(sensor, &kit->sensor_events);
337 }
338 sensor++;
339 level = buffer[7] + (buffer[6] & 0xf0) * 16;
340 if (level != kit->sensors[sensor]) {
341 kit->sensors[sensor] = level;
342 set_bit(sensor, &kit->sensor_events);
343 }
297 } 344 }
298 345
346 if (kit->input_events || kit->sensor_events)
347 schedule_work(&kit->do_notify);
348
299resubmit: 349resubmit:
300 status = usb_submit_urb(urb, SLAB_ATOMIC); 350 status = usb_submit_urb(urb, SLAB_ATOMIC);
301 if (status) 351 if (status)
@@ -304,20 +354,40 @@ resubmit:
304 kit->udev->devpath, status); 354 kit->udev->devpath, status);
305} 355}
306 356
357static void do_notify(void *data)
358{
359 struct interfacekit *kit = data;
360 int i;
361 char sysfs_file[8];
362
363 for (i=0; i<kit->ifkit->inputs; i++) {
364 if (test_and_clear_bit(i, &kit->input_events)) {
365 sprintf(sysfs_file, "input%d", i + 1);
366 sysfs_notify(&kit->intf->dev.kobj, NULL, sysfs_file);
367 }
368 }
369
370 for (i=0; i<kit->ifkit->sensors; i++) {
371 if (test_and_clear_bit(i, &kit->sensor_events)) {
372 sprintf(sysfs_file, "sensor%d", i + 1);
373 sysfs_notify(&kit->intf->dev.kobj, NULL, sysfs_file);
374 }
375 }
376}
377
307#define show_set_output(value) \ 378#define show_set_output(value) \
308static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, \ 379static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, \
309 size_t count) \ 380 size_t count) \
310{ \ 381{ \
311 struct usb_interface *intf = to_usb_interface(dev); \ 382 struct usb_interface *intf = to_usb_interface(dev); \
312 struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ 383 struct interfacekit *kit = usb_get_intfdata(intf); \
313 int enabled; \ 384 int enabled; \
314 int retval; \ 385 int retval; \
315 \ 386 \
316 if (sscanf(buf, "%d", &enabled) < 1) { \ 387 if (sscanf(buf, "%d", &enabled) < 1) \
317 return -EINVAL; \ 388 return -EINVAL; \
318 } \
319 \ 389 \
320 retval = change_outputs(kit, value - 1, enabled ? 1 : 0); \ 390 retval = change_outputs(kit, value - 1, enabled); \
321 \ 391 \
322 return retval ? retval : count; \ 392 return retval ? retval : count; \
323} \ 393} \
@@ -325,9 +395,9 @@ static ssize_t set_output##value(struct device *dev, struct device_attribute *at
325static ssize_t show_output##value(struct device *dev, struct device_attribute *attr, char *buf) \ 395static ssize_t show_output##value(struct device *dev, struct device_attribute *attr, char *buf) \
326{ \ 396{ \
327 struct usb_interface *intf = to_usb_interface(dev); \ 397 struct usb_interface *intf = to_usb_interface(dev); \
328 struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ 398 struct interfacekit *kit = usb_get_intfdata(intf); \
329 \ 399 \
330 return sprintf(buf, "%d\n", kit->outputs[value - 1]); \ 400 return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\
331} \ 401} \
332static DEVICE_ATTR(output##value, S_IWUGO | S_IRUGO, \ 402static DEVICE_ATTR(output##value, S_IWUGO | S_IRUGO, \
333 show_output##value, set_output##value); 403 show_output##value, set_output##value);
@@ -338,15 +408,23 @@ show_set_output(4);
338show_set_output(5); 408show_set_output(5);
339show_set_output(6); 409show_set_output(6);
340show_set_output(7); 410show_set_output(7);
341show_set_output(8); /* should be MAX_INTERFACES - 1 */ 411show_set_output(8);
412show_set_output(9);
413show_set_output(10);
414show_set_output(11);
415show_set_output(12);
416show_set_output(13);
417show_set_output(14);
418show_set_output(15);
419show_set_output(16);
342 420
343#define show_input(value) \ 421#define show_input(value) \
344static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf) \ 422static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf) \
345{ \ 423{ \
346 struct usb_interface *intf = to_usb_interface(dev); \ 424 struct usb_interface *intf = to_usb_interface(dev); \
347 struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ 425 struct interfacekit *kit = usb_get_intfdata(intf); \
348 \ 426 \
349 return sprintf(buf, "%d\n", kit->inputs[value - 1]); \ 427 return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \
350} \ 428} \
351static DEVICE_ATTR(input##value, S_IRUGO, show_input##value, NULL); 429static DEVICE_ATTR(input##value, S_IRUGO, show_input##value, NULL);
352 430
@@ -357,15 +435,23 @@ show_input(4);
357show_input(5); 435show_input(5);
358show_input(6); 436show_input(6);
359show_input(7); 437show_input(7);
360show_input(8); /* should be MAX_INTERFACES - 1 */ 438show_input(8);
439show_input(9);
440show_input(10);
441show_input(11);
442show_input(12);
443show_input(13);
444show_input(14);
445show_input(15);
446show_input(16);
361 447
362#define show_sensor(value) \ 448#define show_sensor(value) \
363static ssize_t show_sensor##value(struct device *dev, struct device_attribute *attr, char *buf) \ 449static ssize_t show_sensor##value(struct device *dev, struct device_attribute *attr, char *buf) \
364{ \ 450{ \
365 struct usb_interface *intf = to_usb_interface(dev); \ 451 struct usb_interface *intf = to_usb_interface(dev); \
366 struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ 452 struct interfacekit *kit = usb_get_intfdata(intf); \
367 \ 453 \
368 return sprintf(buf, "%d\n", kit->sensors[value - 1]); \ 454 return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \
369} \ 455} \
370static DEVICE_ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL); 456static DEVICE_ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL);
371 457
@@ -376,16 +462,16 @@ show_sensor(4);
376show_sensor(5); 462show_sensor(5);
377show_sensor(6); 463show_sensor(6);
378show_sensor(7); 464show_sensor(7);
379show_sensor(8); /* should be MAX_INTERFACES - 1 */ 465show_sensor(8);
380 466
381static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id) 467static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id)
382{ 468{
383 struct usb_device *dev = interface_to_usbdev(intf); 469 struct usb_device *dev = interface_to_usbdev(intf);
384 struct usb_host_interface *interface; 470 struct usb_host_interface *interface;
385 struct usb_endpoint_descriptor *endpoint; 471 struct usb_endpoint_descriptor *endpoint;
386 struct phidget_interfacekit *kit; 472 struct interfacekit *kit;
387 struct driver_interfacekit *ifkit; 473 struct driver_interfacekit *ifkit;
388 int pipe, maxp; 474 int pipe, maxp, rc = -ENOMEM;
389 475
390 ifkit = (struct driver_interfacekit *)id->driver_info; 476 ifkit = (struct driver_interfacekit *)id->driver_info;
391 if (!ifkit) 477 if (!ifkit)
@@ -405,29 +491,23 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
405 maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); 491 maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
406 492
407 kit = kzalloc(sizeof(*kit), GFP_KERNEL); 493 kit = kzalloc(sizeof(*kit), GFP_KERNEL);
408 if (kit == NULL) { 494 if (!kit)
409 dev_err(&intf->dev, "%s - out of memory\n", __FUNCTION__); 495 goto out;
410 return -ENOMEM;
411 }
412 kit->ifkit = ifkit;
413 496
414 kit->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &kit->data_dma); 497 kit->ifkit = ifkit;
415 if (!kit->data) { 498 kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &kit->data_dma);
416 kfree(kit); 499 if (!kit->data)
417 return -ENOMEM; 500 goto out;
418 }
419 501
420 kit->irq = usb_alloc_urb(0, GFP_KERNEL); 502 kit->irq = usb_alloc_urb(0, GFP_KERNEL);
421 if (!kit->irq) { 503 if (!kit->irq)
422 usb_buffer_free(dev, 8, kit->data, kit->data_dma); 504 goto out;
423 kfree(kit);
424 return -ENOMEM;
425 }
426 505
427 kit->udev = usb_get_dev(dev); 506 kit->udev = usb_get_dev(dev);
428 kit->intf = intf; 507 kit->intf = intf;
508 INIT_WORK(&kit->do_notify, do_notify, kit);
429 usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data, 509 usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data,
430 (maxp > 8 ? 8 : maxp), 510 maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp,
431 interfacekit_irq, kit, endpoint->bInterval); 511 interfacekit_irq, kit, endpoint->bInterval);
432 kit->irq->transfer_dma = kit->data_dma; 512 kit->irq->transfer_dma = kit->data_dma;
433 kit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 513 kit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
@@ -435,7 +515,8 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
435 usb_set_intfdata(intf, kit); 515 usb_set_intfdata(intf, kit);
436 516
437 if (usb_submit_urb(kit->irq, GFP_KERNEL)) { 517 if (usb_submit_urb(kit->irq, GFP_KERNEL)) {
438 return -EIO; 518 rc = -EIO;
519 goto out;
439 } 520 }
440 521
441 if (ifkit->outputs >= 4) { 522 if (ifkit->outputs >= 4) {
@@ -444,12 +525,22 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
444 device_create_file(&intf->dev, &dev_attr_output3); 525 device_create_file(&intf->dev, &dev_attr_output3);
445 device_create_file(&intf->dev, &dev_attr_output4); 526 device_create_file(&intf->dev, &dev_attr_output4);
446 } 527 }
447 if (ifkit->outputs == 8) { 528 if (ifkit->outputs >= 8) {
448 device_create_file(&intf->dev, &dev_attr_output5); 529 device_create_file(&intf->dev, &dev_attr_output5);
449 device_create_file(&intf->dev, &dev_attr_output6); 530 device_create_file(&intf->dev, &dev_attr_output6);
450 device_create_file(&intf->dev, &dev_attr_output7); 531 device_create_file(&intf->dev, &dev_attr_output7);
451 device_create_file(&intf->dev, &dev_attr_output8); 532 device_create_file(&intf->dev, &dev_attr_output8);
452 } 533 }
534 if (ifkit->outputs == 16) {
535 device_create_file(&intf->dev, &dev_attr_output9);
536 device_create_file(&intf->dev, &dev_attr_output10);
537 device_create_file(&intf->dev, &dev_attr_output11);
538 device_create_file(&intf->dev, &dev_attr_output12);
539 device_create_file(&intf->dev, &dev_attr_output13);
540 device_create_file(&intf->dev, &dev_attr_output14);
541 device_create_file(&intf->dev, &dev_attr_output15);
542 device_create_file(&intf->dev, &dev_attr_output16);
543 }
453 544
454 if (ifkit->inputs >= 4) { 545 if (ifkit->inputs >= 4) {
455 device_create_file(&intf->dev, &dev_attr_input1); 546 device_create_file(&intf->dev, &dev_attr_input1);
@@ -457,12 +548,22 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
457 device_create_file(&intf->dev, &dev_attr_input3); 548 device_create_file(&intf->dev, &dev_attr_input3);
458 device_create_file(&intf->dev, &dev_attr_input4); 549 device_create_file(&intf->dev, &dev_attr_input4);
459 } 550 }
460 if (ifkit->inputs == 8) { 551 if (ifkit->inputs >= 8) {
461 device_create_file(&intf->dev, &dev_attr_input5); 552 device_create_file(&intf->dev, &dev_attr_input5);
462 device_create_file(&intf->dev, &dev_attr_input6); 553 device_create_file(&intf->dev, &dev_attr_input6);
463 device_create_file(&intf->dev, &dev_attr_input7); 554 device_create_file(&intf->dev, &dev_attr_input7);
464 device_create_file(&intf->dev, &dev_attr_input8); 555 device_create_file(&intf->dev, &dev_attr_input8);
465 } 556 }
557 if (ifkit->inputs == 16) {
558 device_create_file(&intf->dev, &dev_attr_input9);
559 device_create_file(&intf->dev, &dev_attr_input10);
560 device_create_file(&intf->dev, &dev_attr_input11);
561 device_create_file(&intf->dev, &dev_attr_input12);
562 device_create_file(&intf->dev, &dev_attr_input13);
563 device_create_file(&intf->dev, &dev_attr_input14);
564 device_create_file(&intf->dev, &dev_attr_input15);
565 device_create_file(&intf->dev, &dev_attr_input16);
566 }
466 567
467 if (ifkit->sensors >= 4) { 568 if (ifkit->sensors >= 4) {
468 device_create_file(&intf->dev, &dev_attr_sensor1); 569 device_create_file(&intf->dev, &dev_attr_sensor1);
@@ -475,9 +576,8 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
475 device_create_file(&intf->dev, &dev_attr_sensor6); 576 device_create_file(&intf->dev, &dev_attr_sensor6);
476 device_create_file(&intf->dev, &dev_attr_sensor7); 577 device_create_file(&intf->dev, &dev_attr_sensor7);
477 } 578 }
478 if (ifkit->sensors == 8) { 579 if (ifkit->sensors == 8)
479 device_create_file(&intf->dev, &dev_attr_sensor8); 580 device_create_file(&intf->dev, &dev_attr_sensor8);
480 }
481 581
482 if (ifkit->has_lcd) 582 if (ifkit->has_lcd)
483 device_create_file(&intf->dev, &dev_attr_lcd); 583 device_create_file(&intf->dev, &dev_attr_lcd);
@@ -486,29 +586,56 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
486 ifkit->sensors, ifkit->inputs, ifkit->outputs); 586 ifkit->sensors, ifkit->inputs, ifkit->outputs);
487 587
488 return 0; 588 return 0;
589
590out:
591 if (kit) {
592 if (kit->irq)
593 usb_free_urb(kit->irq);
594 if (kit->data)
595 usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma);
596 kfree(kit);
597 }
598
599 return rc;
489} 600}
490 601
491static void interfacekit_disconnect(struct usb_interface *interface) 602static void interfacekit_disconnect(struct usb_interface *interface)
492{ 603{
493 struct phidget_interfacekit *kit; 604 struct interfacekit *kit;
494 605
495 kit = usb_get_intfdata(interface); 606 kit = usb_get_intfdata(interface);
496 usb_set_intfdata(interface, NULL); 607 usb_set_intfdata(interface, NULL);
497 if (!kit) 608 if (!kit)
498 return; 609 return;
499 610
611 usb_kill_urb(kit->irq);
612 usb_free_urb(kit->irq);
613 usb_buffer_free(kit->udev, URB_INT_SIZE, kit->data, kit->data_dma);
614
615 cancel_delayed_work(&kit->do_notify);
616
500 if (kit->ifkit->outputs >= 4) { 617 if (kit->ifkit->outputs >= 4) {
501 device_remove_file(&interface->dev, &dev_attr_output1); 618 device_remove_file(&interface->dev, &dev_attr_output1);
502 device_remove_file(&interface->dev, &dev_attr_output2); 619 device_remove_file(&interface->dev, &dev_attr_output2);
503 device_remove_file(&interface->dev, &dev_attr_output3); 620 device_remove_file(&interface->dev, &dev_attr_output3);
504 device_remove_file(&interface->dev, &dev_attr_output4); 621 device_remove_file(&interface->dev, &dev_attr_output4);
505 } 622 }
506 if (kit->ifkit->outputs == 8) { 623 if (kit->ifkit->outputs >= 8) {
507 device_remove_file(&interface->dev, &dev_attr_output5); 624 device_remove_file(&interface->dev, &dev_attr_output5);
508 device_remove_file(&interface->dev, &dev_attr_output6); 625 device_remove_file(&interface->dev, &dev_attr_output6);
509 device_remove_file(&interface->dev, &dev_attr_output7); 626 device_remove_file(&interface->dev, &dev_attr_output7);
510 device_remove_file(&interface->dev, &dev_attr_output8); 627 device_remove_file(&interface->dev, &dev_attr_output8);
511 } 628 }
629 if (kit->ifkit->outputs == 16) {
630 device_remove_file(&interface->dev, &dev_attr_output9);
631 device_remove_file(&interface->dev, &dev_attr_output10);
632 device_remove_file(&interface->dev, &dev_attr_output11);
633 device_remove_file(&interface->dev, &dev_attr_output12);
634 device_remove_file(&interface->dev, &dev_attr_output13);
635 device_remove_file(&interface->dev, &dev_attr_output14);
636 device_remove_file(&interface->dev, &dev_attr_output15);
637 device_remove_file(&interface->dev, &dev_attr_output16);
638 }
512 639
513 if (kit->ifkit->inputs >= 4) { 640 if (kit->ifkit->inputs >= 4) {
514 device_remove_file(&interface->dev, &dev_attr_input1); 641 device_remove_file(&interface->dev, &dev_attr_input1);
@@ -516,12 +643,22 @@ static void interfacekit_disconnect(struct usb_interface *interface)
516 device_remove_file(&interface->dev, &dev_attr_input3); 643 device_remove_file(&interface->dev, &dev_attr_input3);
517 device_remove_file(&interface->dev, &dev_attr_input4); 644 device_remove_file(&interface->dev, &dev_attr_input4);
518 } 645 }
519 if (kit->ifkit->inputs == 8) { 646 if (kit->ifkit->inputs >= 8) {
520 device_remove_file(&interface->dev, &dev_attr_input5); 647 device_remove_file(&interface->dev, &dev_attr_input5);
521 device_remove_file(&interface->dev, &dev_attr_input6); 648 device_remove_file(&interface->dev, &dev_attr_input6);
522 device_remove_file(&interface->dev, &dev_attr_input7); 649 device_remove_file(&interface->dev, &dev_attr_input7);
523 device_remove_file(&interface->dev, &dev_attr_input8); 650 device_remove_file(&interface->dev, &dev_attr_input8);
524 } 651 }
652 if (kit->ifkit->inputs == 16) {
653 device_remove_file(&interface->dev, &dev_attr_input9);
654 device_remove_file(&interface->dev, &dev_attr_input10);
655 device_remove_file(&interface->dev, &dev_attr_input11);
656 device_remove_file(&interface->dev, &dev_attr_input12);
657 device_remove_file(&interface->dev, &dev_attr_input13);
658 device_remove_file(&interface->dev, &dev_attr_input14);
659 device_remove_file(&interface->dev, &dev_attr_input15);
660 device_remove_file(&interface->dev, &dev_attr_input16);
661 }
525 662
526 if (kit->ifkit->sensors >= 4) { 663 if (kit->ifkit->sensors >= 4) {
527 device_remove_file(&interface->dev, &dev_attr_sensor1); 664 device_remove_file(&interface->dev, &dev_attr_sensor1);
@@ -534,19 +671,15 @@ static void interfacekit_disconnect(struct usb_interface *interface)
534 device_remove_file(&interface->dev, &dev_attr_sensor6); 671 device_remove_file(&interface->dev, &dev_attr_sensor6);
535 device_remove_file(&interface->dev, &dev_attr_sensor7); 672 device_remove_file(&interface->dev, &dev_attr_sensor7);
536 } 673 }
537 if (kit->ifkit->sensors == 8) { 674 if (kit->ifkit->sensors == 8)
538 device_remove_file(&interface->dev, &dev_attr_sensor8); 675 device_remove_file(&interface->dev, &dev_attr_sensor8);
539 } 676
540 if (kit->ifkit->has_lcd) 677 if (kit->ifkit->has_lcd)
541 device_remove_file(&interface->dev, &dev_attr_lcd); 678 device_remove_file(&interface->dev, &dev_attr_lcd);
542 679
543 dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n", 680 dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n",
544 kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs); 681 kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs);
545 682
546 usb_kill_urb(kit->irq);
547 usb_free_urb(kit->irq);
548 usb_buffer_free(kit->udev, 8, kit->data, kit->data_dma);
549
550 usb_put_dev(kit->udev); 683 usb_put_dev(kit->udev);
551 kfree(kit); 684 kfree(kit);
552} 685}