staging: comedi: vmk80xx: move usb_driver (*disconnect) code
[firefly-linux-kernel-4.4.55.git] / drivers / staging / comedi / drivers / vmk80xx.c
1 /*
2     comedi/drivers/vmk80xx.c
3     Velleman USB Board Low-Level Driver
4
5     Copyright (C) 2009 Manuel Gebele <forensixs@gmx.de>, Germany
6
7     COMEDI - Linux Control and Measurement Device Interface
8     Copyright (C) 2000 David A. Schleef <ds@schleef.org>
9
10     This program is free software; you can redistribute it and/or modify
11     it under the terms of the GNU General Public License as published by
12     the Free Software Foundation; either version 2 of the License, or
13     (at your option) any later version.
14
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
19
20     You should have received a copy of the GNU General Public License
21     along with this program; if not, write to the Free Software
22     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24 */
25 /*
26 Driver: vmk80xx
27 Description: Velleman USB Board Low-Level Driver
28 Devices: K8055/K8061 aka VM110/VM140
29 Author: Manuel Gebele <forensixs@gmx.de>
30 Updated: Sun, 10 May 2009 11:14:59 +0200
31 Status: works
32
33 Supports:
34  - analog input
35  - analog output
36  - digital input
37  - digital output
38  - counter
39  - pwm
40 */
41 /*
42 Changelog:
43
44 0.8.81  -3-  code completely rewritten (adjust driver logic)
45 0.8.81  -2-  full support for K8061
46 0.8.81  -1-  fix some mistaken among others the number of
47              supported boards and I/O handling
48
49 0.7.76  -4-  renamed to vmk80xx
50 0.7.76  -3-  detect K8061 (only theoretically supported)
51 0.7.76  -2-  code completely rewritten (adjust driver logic)
52 0.7.76  -1-  support for digital and counter subdevice
53 */
54
55 #include <linux/kernel.h>
56 #include <linux/module.h>
57 #include <linux/mutex.h>
58 #include <linux/errno.h>
59 #include <linux/input.h>
60 #include <linux/slab.h>
61 #include <linux/poll.h>
62 #include <linux/usb.h>
63 #include <linux/uaccess.h>
64
65 #include "../comedidev.h"
66
67 enum {
68         DEVICE_VMK8055,
69         DEVICE_VMK8061
70 };
71
72 #define VMK8055_DI_REG          0x00
73 #define VMK8055_DO_REG          0x01
74 #define VMK8055_AO1_REG         0x02
75 #define VMK8055_AO2_REG         0x03
76 #define VMK8055_AI1_REG         0x02
77 #define VMK8055_AI2_REG         0x03
78 #define VMK8055_CNT1_REG        0x04
79 #define VMK8055_CNT2_REG        0x06
80
81 #define VMK8061_CH_REG          0x01
82 #define VMK8061_DI_REG          0x01
83 #define VMK8061_DO_REG          0x01
84 #define VMK8061_PWM_REG1        0x01
85 #define VMK8061_PWM_REG2        0x02
86 #define VMK8061_CNT_REG         0x02
87 #define VMK8061_AO_REG          0x02
88 #define VMK8061_AI_REG1         0x02
89 #define VMK8061_AI_REG2         0x03
90
91 #define VMK8055_CMD_RST         0x00
92 #define VMK8055_CMD_DEB1_TIME   0x01
93 #define VMK8055_CMD_DEB2_TIME   0x02
94 #define VMK8055_CMD_RST_CNT1    0x03
95 #define VMK8055_CMD_RST_CNT2    0x04
96 #define VMK8055_CMD_WRT_AD      0x05
97
98 #define VMK8061_CMD_RD_AI       0x00
99 #define VMK8061_CMR_RD_ALL_AI   0x01    /* !non-active! */
100 #define VMK8061_CMD_SET_AO      0x02
101 #define VMK8061_CMD_SET_ALL_AO  0x03    /* !non-active! */
102 #define VMK8061_CMD_OUT_PWM     0x04
103 #define VMK8061_CMD_RD_DI       0x05
104 #define VMK8061_CMD_DO          0x06    /* !non-active! */
105 #define VMK8061_CMD_CLR_DO      0x07
106 #define VMK8061_CMD_SET_DO      0x08
107 #define VMK8061_CMD_RD_CNT      0x09    /* TODO: completely pointless? */
108 #define VMK8061_CMD_RST_CNT     0x0a    /* TODO: completely pointless? */
109 #define VMK8061_CMD_RD_VERSION  0x0b    /* internal usage */
110 #define VMK8061_CMD_RD_JMP_STAT 0x0c    /* TODO: not implemented yet */
111 #define VMK8061_CMD_RD_PWR_STAT 0x0d    /* internal usage */
112 #define VMK8061_CMD_RD_DO       0x0e
113 #define VMK8061_CMD_RD_AO       0x0f
114 #define VMK8061_CMD_RD_PWM      0x10
115
116 #define VMK80XX_MAX_BOARDS      COMEDI_NUM_BOARD_MINORS
117
118 #define TRANS_OUT_BUSY          1
119 #define TRANS_IN_BUSY           2
120 #define TRANS_IN_RUNNING        3
121
122 #define IC3_VERSION             (1 << 0)
123 #define IC6_VERSION             (1 << 1)
124
125 #define URB_RCV_FLAG            (1 << 0)
126 #define URB_SND_FLAG            (1 << 1)
127
128 #ifdef CONFIG_COMEDI_DEBUG
129 static int dbgcm = 1;
130 #else
131 static int dbgcm;
132 #endif
133
134 #define dbgcm(fmt, arg...)                     \
135 do {                                           \
136         if (dbgcm)                             \
137                 printk(KERN_DEBUG fmt, ##arg); \
138 } while (0)
139
140 enum vmk80xx_model {
141         VMK8055_MODEL,
142         VMK8061_MODEL
143 };
144
145 struct firmware_version {
146         unsigned char ic3_vers[32];     /* USB-Controller */
147         unsigned char ic6_vers[32];     /* CPU */
148 };
149
150 static const struct comedi_lrange vmk8055_range = {
151         1, {UNI_RANGE(5)}
152 };
153
154 static const struct comedi_lrange vmk8061_range = {
155         2, {UNI_RANGE(5), UNI_RANGE(10)}
156 };
157
158 struct vmk80xx_board {
159         const char *name;
160         enum vmk80xx_model model;
161         const struct comedi_lrange *range;
162         __u8 ai_chans;
163         __le16 ai_bits;
164         __u8 ao_chans;
165         __le16 ao_bits;
166         __u8 di_chans;
167         __le16 di_bits;
168         __u8 do_chans;
169         __le16 do_bits;
170         __u8 cnt_chans;
171         __le16 cnt_bits;
172         __u8 pwm_chans;
173         __le16 pwm_bits;
174 };
175
176 enum {
177         VMK80XX_SUBD_AI,
178         VMK80XX_SUBD_AO,
179         VMK80XX_SUBD_DI,
180         VMK80XX_SUBD_DO,
181         VMK80XX_SUBD_CNT,
182         VMK80XX_SUBD_PWM,
183 };
184
185 struct vmk80xx_usb {
186         struct usb_device *udev;
187         struct usb_interface *intf;
188         struct usb_endpoint_descriptor *ep_rx;
189         struct usb_endpoint_descriptor *ep_tx;
190         struct usb_anchor rx_anchor;
191         struct usb_anchor tx_anchor;
192         struct vmk80xx_board board;
193         struct firmware_version fw;
194         struct semaphore limit_sem;
195         wait_queue_head_t read_wait;
196         wait_queue_head_t write_wait;
197         unsigned char *usb_rx_buf;
198         unsigned char *usb_tx_buf;
199         unsigned long flags;
200         int probed;
201         int attached;
202         int count;
203 };
204
205 static struct vmk80xx_usb vmb[VMK80XX_MAX_BOARDS];
206
207 static DEFINE_MUTEX(glb_mutex);
208
209 static void vmk80xx_tx_callback(struct urb *urb)
210 {
211         struct vmk80xx_usb *dev = urb->context;
212         int stat = urb->status;
213
214         if (stat && !(stat == -ENOENT
215                       || stat == -ECONNRESET || stat == -ESHUTDOWN))
216                 dbgcm("comedi#: vmk80xx: %s - nonzero urb status (%d)\n",
217                       __func__, stat);
218
219         if (!test_bit(TRANS_OUT_BUSY, &dev->flags))
220                 return;
221
222         clear_bit(TRANS_OUT_BUSY, &dev->flags);
223
224         wake_up_interruptible(&dev->write_wait);
225 }
226
227 static void vmk80xx_rx_callback(struct urb *urb)
228 {
229         struct vmk80xx_usb *dev = urb->context;
230         int stat = urb->status;
231
232         switch (stat) {
233         case 0:
234                 break;
235         case -ENOENT:
236         case -ECONNRESET:
237         case -ESHUTDOWN:
238                 break;
239         default:
240                 dbgcm("comedi#: vmk80xx: %s - nonzero urb status (%d)\n",
241                       __func__, stat);
242                 goto resubmit;
243         }
244
245         goto exit;
246 resubmit:
247         if (test_bit(TRANS_IN_RUNNING, &dev->flags) && dev->intf) {
248                 usb_anchor_urb(urb, &dev->rx_anchor);
249
250                 if (!usb_submit_urb(urb, GFP_KERNEL))
251                         goto exit;
252
253                 dev_err(&urb->dev->dev,
254                         "comedi#: vmk80xx: %s - submit urb failed\n",
255                         __func__);
256
257                 usb_unanchor_urb(urb);
258         }
259 exit:
260         clear_bit(TRANS_IN_BUSY, &dev->flags);
261
262         wake_up_interruptible(&dev->read_wait);
263 }
264
265 static int vmk80xx_check_data_link(struct vmk80xx_usb *dev)
266 {
267         unsigned int tx_pipe;
268         unsigned int rx_pipe;
269         unsigned char tx[1];
270         unsigned char rx[2];
271
272         tx_pipe = usb_sndbulkpipe(dev->udev, 0x01);
273         rx_pipe = usb_rcvbulkpipe(dev->udev, 0x81);
274
275         tx[0] = VMK8061_CMD_RD_PWR_STAT;
276
277         /*
278          * Check that IC6 (PIC16F871) is powered and
279          * running and the data link between IC3 and
280          * IC6 is working properly
281          */
282         usb_bulk_msg(dev->udev, tx_pipe, tx, 1, NULL, dev->ep_tx->bInterval);
283         usb_bulk_msg(dev->udev, rx_pipe, rx, 2, NULL, HZ * 10);
284
285         return (int)rx[1];
286 }
287
288 static void vmk80xx_read_eeprom(struct vmk80xx_usb *dev, int flag)
289 {
290         unsigned int tx_pipe;
291         unsigned int rx_pipe;
292         unsigned char tx[1];
293         unsigned char rx[64];
294         int cnt;
295
296         tx_pipe = usb_sndbulkpipe(dev->udev, 0x01);
297         rx_pipe = usb_rcvbulkpipe(dev->udev, 0x81);
298
299         tx[0] = VMK8061_CMD_RD_VERSION;
300
301         /*
302          * Read the firmware version info of IC3 and
303          * IC6 from the internal EEPROM of the IC
304          */
305         usb_bulk_msg(dev->udev, tx_pipe, tx, 1, NULL, dev->ep_tx->bInterval);
306         usb_bulk_msg(dev->udev, rx_pipe, rx, 64, &cnt, HZ * 10);
307
308         rx[cnt] = '\0';
309
310         if (flag & IC3_VERSION)
311                 strncpy(dev->fw.ic3_vers, rx + 1, 24);
312         else                    /* IC6_VERSION */
313                 strncpy(dev->fw.ic6_vers, rx + 25, 24);
314 }
315
316 static int vmk80xx_reset_device(struct vmk80xx_usb *dev)
317 {
318         struct urb *urb;
319         unsigned int tx_pipe;
320         int ival;
321         size_t size;
322
323         urb = usb_alloc_urb(0, GFP_KERNEL);
324         if (!urb)
325                 return -ENOMEM;
326
327         tx_pipe = usb_sndintpipe(dev->udev, 0x01);
328
329         ival = dev->ep_tx->bInterval;
330         size = le16_to_cpu(dev->ep_tx->wMaxPacketSize);
331
332         dev->usb_tx_buf[0] = VMK8055_CMD_RST;
333         dev->usb_tx_buf[1] = 0x00;
334         dev->usb_tx_buf[2] = 0x00;
335         dev->usb_tx_buf[3] = 0x00;
336         dev->usb_tx_buf[4] = 0x00;
337         dev->usb_tx_buf[5] = 0x00;
338         dev->usb_tx_buf[6] = 0x00;
339         dev->usb_tx_buf[7] = 0x00;
340
341         usb_fill_int_urb(urb, dev->udev, tx_pipe, dev->usb_tx_buf,
342                          size, vmk80xx_tx_callback, dev, ival);
343
344         usb_anchor_urb(urb, &dev->tx_anchor);
345
346         return usb_submit_urb(urb, GFP_KERNEL);
347 }
348
349 static void vmk80xx_build_int_urb(struct urb *urb, int flag)
350 {
351         struct vmk80xx_usb *dev = urb->context;
352         __u8 rx_addr;
353         __u8 tx_addr;
354         unsigned int pipe;
355         unsigned char *buf;
356         size_t size;
357         void (*callback) (struct urb *);
358         int ival;
359
360         if (flag & URB_RCV_FLAG) {
361                 rx_addr = dev->ep_rx->bEndpointAddress;
362                 pipe = usb_rcvintpipe(dev->udev, rx_addr);
363                 buf = dev->usb_rx_buf;
364                 size = le16_to_cpu(dev->ep_rx->wMaxPacketSize);
365                 callback = vmk80xx_rx_callback;
366                 ival = dev->ep_rx->bInterval;
367         } else {                /* URB_SND_FLAG */
368                 tx_addr = dev->ep_tx->bEndpointAddress;
369                 pipe = usb_sndintpipe(dev->udev, tx_addr);
370                 buf = dev->usb_tx_buf;
371                 size = le16_to_cpu(dev->ep_tx->wMaxPacketSize);
372                 callback = vmk80xx_tx_callback;
373                 ival = dev->ep_tx->bInterval;
374         }
375
376         usb_fill_int_urb(urb, dev->udev, pipe, buf, size, callback, dev, ival);
377 }
378
379 static void vmk80xx_do_bulk_msg(struct vmk80xx_usb *dev)
380 {
381         __u8 tx_addr;
382         __u8 rx_addr;
383         unsigned int tx_pipe;
384         unsigned int rx_pipe;
385         size_t size;
386
387         set_bit(TRANS_IN_BUSY, &dev->flags);
388         set_bit(TRANS_OUT_BUSY, &dev->flags);
389
390         tx_addr = dev->ep_tx->bEndpointAddress;
391         rx_addr = dev->ep_rx->bEndpointAddress;
392         tx_pipe = usb_sndbulkpipe(dev->udev, tx_addr);
393         rx_pipe = usb_rcvbulkpipe(dev->udev, rx_addr);
394
395         /*
396          * The max packet size attributes of the K8061
397          * input/output endpoints are identical
398          */
399         size = le16_to_cpu(dev->ep_tx->wMaxPacketSize);
400
401         usb_bulk_msg(dev->udev, tx_pipe, dev->usb_tx_buf,
402                      size, NULL, dev->ep_tx->bInterval);
403         usb_bulk_msg(dev->udev, rx_pipe, dev->usb_rx_buf, size, NULL, HZ * 10);
404
405         clear_bit(TRANS_OUT_BUSY, &dev->flags);
406         clear_bit(TRANS_IN_BUSY, &dev->flags);
407 }
408
409 static int vmk80xx_read_packet(struct vmk80xx_usb *dev)
410 {
411         struct urb *urb;
412         int retval;
413
414         if (!dev->intf)
415                 return -ENODEV;
416
417         /* Only useful for interrupt transfers */
418         if (test_bit(TRANS_IN_BUSY, &dev->flags))
419                 if (wait_event_interruptible(dev->read_wait,
420                                              !test_bit(TRANS_IN_BUSY,
421                                                        &dev->flags)))
422                         return -ERESTART;
423
424         if (dev->board.model == VMK8061_MODEL) {
425                 vmk80xx_do_bulk_msg(dev);
426
427                 return 0;
428         }
429
430         urb = usb_alloc_urb(0, GFP_KERNEL);
431         if (!urb)
432                 return -ENOMEM;
433
434         urb->context = dev;
435         vmk80xx_build_int_urb(urb, URB_RCV_FLAG);
436
437         set_bit(TRANS_IN_RUNNING, &dev->flags);
438         set_bit(TRANS_IN_BUSY, &dev->flags);
439
440         usb_anchor_urb(urb, &dev->rx_anchor);
441
442         retval = usb_submit_urb(urb, GFP_KERNEL);
443         if (!retval)
444                 goto exit;
445
446         clear_bit(TRANS_IN_RUNNING, &dev->flags);
447         usb_unanchor_urb(urb);
448
449 exit:
450         usb_free_urb(urb);
451
452         return retval;
453 }
454
455 static int vmk80xx_write_packet(struct vmk80xx_usb *dev, int cmd)
456 {
457         struct urb *urb;
458         int retval;
459
460         if (!dev->intf)
461                 return -ENODEV;
462
463         if (test_bit(TRANS_OUT_BUSY, &dev->flags))
464                 if (wait_event_interruptible(dev->write_wait,
465                                              !test_bit(TRANS_OUT_BUSY,
466                                                        &dev->flags)))
467                         return -ERESTART;
468
469         if (dev->board.model == VMK8061_MODEL) {
470                 dev->usb_tx_buf[0] = cmd;
471                 vmk80xx_do_bulk_msg(dev);
472
473                 return 0;
474         }
475
476         urb = usb_alloc_urb(0, GFP_KERNEL);
477         if (!urb)
478                 return -ENOMEM;
479
480         urb->context = dev;
481         vmk80xx_build_int_urb(urb, URB_SND_FLAG);
482
483         set_bit(TRANS_OUT_BUSY, &dev->flags);
484
485         usb_anchor_urb(urb, &dev->tx_anchor);
486
487         dev->usb_tx_buf[0] = cmd;
488
489         retval = usb_submit_urb(urb, GFP_KERNEL);
490         if (!retval)
491                 goto exit;
492
493         clear_bit(TRANS_OUT_BUSY, &dev->flags);
494         usb_unanchor_urb(urb);
495
496 exit:
497         usb_free_urb(urb);
498
499         return retval;
500 }
501
502 #define DIR_IN  1
503 #define DIR_OUT 2
504
505 static int rudimentary_check(struct vmk80xx_usb *dev, int dir)
506 {
507         if (!dev)
508                 return -EFAULT;
509         if (!dev->probed)
510                 return -ENODEV;
511         if (!dev->attached)
512                 return -ENODEV;
513         if (dir & DIR_IN) {
514                 if (test_bit(TRANS_IN_BUSY, &dev->flags))
515                         return -EBUSY;
516         }
517         if (dir & DIR_OUT) {
518                 if (test_bit(TRANS_OUT_BUSY, &dev->flags))
519                         return -EBUSY;
520         }
521
522         return 0;
523 }
524
525 static int vmk80xx_ai_rinsn(struct comedi_device *cdev,
526                             struct comedi_subdevice *s,
527                             struct comedi_insn *insn, unsigned int *data)
528 {
529         struct vmk80xx_usb *dev = cdev->private;
530         int chan;
531         int reg[2];
532         int n;
533
534         n = rudimentary_check(dev, DIR_IN);
535         if (n)
536                 return n;
537
538         down(&dev->limit_sem);
539         chan = CR_CHAN(insn->chanspec);
540
541         switch (dev->board.model) {
542         case VMK8055_MODEL:
543                 if (!chan)
544                         reg[0] = VMK8055_AI1_REG;
545                 else
546                         reg[0] = VMK8055_AI2_REG;
547                 break;
548         case VMK8061_MODEL:
549         default:
550                 reg[0] = VMK8061_AI_REG1;
551                 reg[1] = VMK8061_AI_REG2;
552                 dev->usb_tx_buf[0] = VMK8061_CMD_RD_AI;
553                 dev->usb_tx_buf[VMK8061_CH_REG] = chan;
554                 break;
555         }
556
557         for (n = 0; n < insn->n; n++) {
558                 if (vmk80xx_read_packet(dev))
559                         break;
560
561                 if (dev->board.model == VMK8055_MODEL) {
562                         data[n] = dev->usb_rx_buf[reg[0]];
563                         continue;
564                 }
565
566                 /* VMK8061_MODEL */
567                 data[n] = dev->usb_rx_buf[reg[0]] + 256 *
568                     dev->usb_rx_buf[reg[1]];
569         }
570
571         up(&dev->limit_sem);
572
573         return n;
574 }
575
576 static int vmk80xx_ao_winsn(struct comedi_device *cdev,
577                             struct comedi_subdevice *s,
578                             struct comedi_insn *insn, unsigned int *data)
579 {
580         struct vmk80xx_usb *dev = cdev->private;
581         int chan;
582         int cmd;
583         int reg;
584         int n;
585
586         n = rudimentary_check(dev, DIR_OUT);
587         if (n)
588                 return n;
589
590         down(&dev->limit_sem);
591         chan = CR_CHAN(insn->chanspec);
592
593         switch (dev->board.model) {
594         case VMK8055_MODEL:
595                 cmd = VMK8055_CMD_WRT_AD;
596                 if (!chan)
597                         reg = VMK8055_AO1_REG;
598                 else
599                         reg = VMK8055_AO2_REG;
600                 break;
601         default:                /* NOTE: avoid compiler warnings */
602                 cmd = VMK8061_CMD_SET_AO;
603                 reg = VMK8061_AO_REG;
604                 dev->usb_tx_buf[VMK8061_CH_REG] = chan;
605                 break;
606         }
607
608         for (n = 0; n < insn->n; n++) {
609                 dev->usb_tx_buf[reg] = data[n];
610
611                 if (vmk80xx_write_packet(dev, cmd))
612                         break;
613         }
614
615         up(&dev->limit_sem);
616
617         return n;
618 }
619
620 static int vmk80xx_ao_rinsn(struct comedi_device *cdev,
621                             struct comedi_subdevice *s,
622                             struct comedi_insn *insn, unsigned int *data)
623 {
624         struct vmk80xx_usb *dev = cdev->private;
625         int chan;
626         int reg;
627         int n;
628
629         n = rudimentary_check(dev, DIR_IN);
630         if (n)
631                 return n;
632
633         down(&dev->limit_sem);
634         chan = CR_CHAN(insn->chanspec);
635
636         reg = VMK8061_AO_REG - 1;
637
638         dev->usb_tx_buf[0] = VMK8061_CMD_RD_AO;
639
640         for (n = 0; n < insn->n; n++) {
641                 if (vmk80xx_read_packet(dev))
642                         break;
643
644                 data[n] = dev->usb_rx_buf[reg + chan];
645         }
646
647         up(&dev->limit_sem);
648
649         return n;
650 }
651
652 static int vmk80xx_di_bits(struct comedi_device *cdev,
653                            struct comedi_subdevice *s,
654                            struct comedi_insn *insn, unsigned int *data)
655 {
656         struct vmk80xx_usb *dev = cdev->private;
657         unsigned char *rx_buf;
658         int reg;
659         int retval;
660
661         retval = rudimentary_check(dev, DIR_IN);
662         if (retval)
663                 return retval;
664
665         down(&dev->limit_sem);
666
667         rx_buf = dev->usb_rx_buf;
668
669         if (dev->board.model == VMK8061_MODEL) {
670                 reg = VMK8061_DI_REG;
671                 dev->usb_tx_buf[0] = VMK8061_CMD_RD_DI;
672         } else {
673                 reg = VMK8055_DI_REG;
674         }
675
676         retval = vmk80xx_read_packet(dev);
677
678         if (!retval) {
679                 if (dev->board.model == VMK8055_MODEL)
680                         data[1] = (((rx_buf[reg] >> 4) & 0x03) |
681                                   ((rx_buf[reg] << 2) & 0x04) |
682                                   ((rx_buf[reg] >> 3) & 0x18));
683                 else
684                         data[1] = rx_buf[reg];
685
686                 retval = 2;
687         }
688
689         up(&dev->limit_sem);
690
691         return retval;
692 }
693
694 static int vmk80xx_di_rinsn(struct comedi_device *cdev,
695                             struct comedi_subdevice *s,
696                             struct comedi_insn *insn, unsigned int *data)
697 {
698         struct vmk80xx_usb *dev = cdev->private;
699         int chan;
700         unsigned char *rx_buf;
701         int reg;
702         int inp;
703         int n;
704
705         n = rudimentary_check(dev, DIR_IN);
706         if (n)
707                 return n;
708
709         down(&dev->limit_sem);
710         chan = CR_CHAN(insn->chanspec);
711
712         rx_buf = dev->usb_rx_buf;
713
714         if (dev->board.model == VMK8061_MODEL) {
715                 reg = VMK8061_DI_REG;
716                 dev->usb_tx_buf[0] = VMK8061_CMD_RD_DI;
717         } else {
718                 reg = VMK8055_DI_REG;
719         }
720         for (n = 0; n < insn->n; n++) {
721                 if (vmk80xx_read_packet(dev))
722                         break;
723
724                 if (dev->board.model == VMK8055_MODEL)
725                         inp = (((rx_buf[reg] >> 4) & 0x03) |
726                                ((rx_buf[reg] << 2) & 0x04) |
727                                ((rx_buf[reg] >> 3) & 0x18));
728                 else
729                         inp = rx_buf[reg];
730
731                 data[n] = (inp >> chan) & 1;
732         }
733
734         up(&dev->limit_sem);
735
736         return n;
737 }
738
739 static int vmk80xx_do_winsn(struct comedi_device *cdev,
740                             struct comedi_subdevice *s,
741                             struct comedi_insn *insn, unsigned int *data)
742 {
743         struct vmk80xx_usb *dev = cdev->private;
744         int chan;
745         unsigned char *tx_buf;
746         int reg;
747         int cmd;
748         int n;
749
750         n = rudimentary_check(dev, DIR_OUT);
751         if (n)
752                 return n;
753
754         down(&dev->limit_sem);
755         chan = CR_CHAN(insn->chanspec);
756
757         tx_buf = dev->usb_tx_buf;
758
759         for (n = 0; n < insn->n; n++) {
760                 if (dev->board.model == VMK8055_MODEL) {
761                         reg = VMK8055_DO_REG;
762                         cmd = VMK8055_CMD_WRT_AD;
763                         if (data[n] == 1)
764                                 tx_buf[reg] |= (1 << chan);
765                         else
766                                 tx_buf[reg] ^= (1 << chan);
767                 } else { /* VMK8061_MODEL */
768                         reg = VMK8061_DO_REG;
769                         if (data[n] == 1) {
770                                 cmd = VMK8061_CMD_SET_DO;
771                                 tx_buf[reg] = 1 << chan;
772                         } else {
773                                 cmd = VMK8061_CMD_CLR_DO;
774                                 tx_buf[reg] = 0xff - (1 << chan);
775                         }
776                 }
777
778                 if (vmk80xx_write_packet(dev, cmd))
779                         break;
780         }
781
782         up(&dev->limit_sem);
783
784         return n;
785 }
786
787 static int vmk80xx_do_rinsn(struct comedi_device *cdev,
788                             struct comedi_subdevice *s,
789                             struct comedi_insn *insn, unsigned int *data)
790 {
791         struct vmk80xx_usb *dev = cdev->private;
792         int chan;
793         int reg;
794         int n;
795
796         n = rudimentary_check(dev, DIR_IN);
797         if (n)
798                 return n;
799
800         down(&dev->limit_sem);
801         chan = CR_CHAN(insn->chanspec);
802
803         reg = VMK8061_DO_REG;
804
805         dev->usb_tx_buf[0] = VMK8061_CMD_RD_DO;
806
807         for (n = 0; n < insn->n; n++) {
808                 if (vmk80xx_read_packet(dev))
809                         break;
810
811                 data[n] = (dev->usb_rx_buf[reg] >> chan) & 1;
812         }
813
814         up(&dev->limit_sem);
815
816         return n;
817 }
818
819 static int vmk80xx_do_bits(struct comedi_device *cdev,
820                            struct comedi_subdevice *s,
821                            struct comedi_insn *insn, unsigned int *data)
822 {
823         struct vmk80xx_usb *dev = cdev->private;
824         unsigned char *rx_buf, *tx_buf;
825         int dir, reg, cmd;
826         int retval;
827
828         dir = 0;
829
830         if (data[0])
831                 dir |= DIR_OUT;
832
833         if (dev->board.model == VMK8061_MODEL)
834                 dir |= DIR_IN;
835
836         retval = rudimentary_check(dev, dir);
837         if (retval)
838                 return retval;
839
840         down(&dev->limit_sem);
841
842         rx_buf = dev->usb_rx_buf;
843         tx_buf = dev->usb_tx_buf;
844
845         if (data[0]) {
846                 if (dev->board.model == VMK8055_MODEL) {
847                         reg = VMK8055_DO_REG;
848                         cmd = VMK8055_CMD_WRT_AD;
849                 } else { /* VMK8061_MODEL */
850                         reg = VMK8061_DO_REG;
851                         cmd = VMK8061_CMD_DO;
852                 }
853
854                 tx_buf[reg] &= ~data[0];
855                 tx_buf[reg] |= (data[0] & data[1]);
856
857                 retval = vmk80xx_write_packet(dev, cmd);
858
859                 if (retval)
860                         goto out;
861         }
862
863         if (dev->board.model == VMK8061_MODEL) {
864                 reg = VMK8061_DO_REG;
865                 tx_buf[0] = VMK8061_CMD_RD_DO;
866
867                 retval = vmk80xx_read_packet(dev);
868
869                 if (!retval) {
870                         data[1] = rx_buf[reg];
871                         retval = 2;
872                 }
873         } else {
874                 data[1] = tx_buf[reg];
875                 retval = 2;
876         }
877
878 out:
879         up(&dev->limit_sem);
880
881         return retval;
882 }
883
884 static int vmk80xx_cnt_rinsn(struct comedi_device *cdev,
885                              struct comedi_subdevice *s,
886                              struct comedi_insn *insn, unsigned int *data)
887 {
888         struct vmk80xx_usb *dev = cdev->private;
889         int chan;
890         int reg[2];
891         int n;
892
893         n = rudimentary_check(dev, DIR_IN);
894         if (n)
895                 return n;
896
897         down(&dev->limit_sem);
898         chan = CR_CHAN(insn->chanspec);
899
900         switch (dev->board.model) {
901         case VMK8055_MODEL:
902                 if (!chan)
903                         reg[0] = VMK8055_CNT1_REG;
904                 else
905                         reg[0] = VMK8055_CNT2_REG;
906                 break;
907         case VMK8061_MODEL:
908         default:
909                 reg[0] = VMK8061_CNT_REG;
910                 reg[1] = VMK8061_CNT_REG;
911                 dev->usb_tx_buf[0] = VMK8061_CMD_RD_CNT;
912                 break;
913         }
914
915         for (n = 0; n < insn->n; n++) {
916                 if (vmk80xx_read_packet(dev))
917                         break;
918
919                 if (dev->board.model == VMK8055_MODEL)
920                         data[n] = dev->usb_rx_buf[reg[0]];
921                 else /* VMK8061_MODEL */
922                         data[n] = dev->usb_rx_buf[reg[0] * (chan + 1) + 1]
923                             + 256 * dev->usb_rx_buf[reg[1] * 2 + 2];
924         }
925
926         up(&dev->limit_sem);
927
928         return n;
929 }
930
931 static int vmk80xx_cnt_cinsn(struct comedi_device *cdev,
932                              struct comedi_subdevice *s,
933                              struct comedi_insn *insn, unsigned int *data)
934 {
935         struct vmk80xx_usb *dev = cdev->private;
936         unsigned int insn_cmd;
937         int chan;
938         int cmd;
939         int reg;
940         int n;
941
942         n = rudimentary_check(dev, DIR_OUT);
943         if (n)
944                 return n;
945
946         insn_cmd = data[0];
947         if (insn_cmd != INSN_CONFIG_RESET && insn_cmd != GPCT_RESET)
948                 return -EINVAL;
949
950         down(&dev->limit_sem);
951
952         chan = CR_CHAN(insn->chanspec);
953
954         if (dev->board.model == VMK8055_MODEL) {
955                 if (!chan) {
956                         cmd = VMK8055_CMD_RST_CNT1;
957                         reg = VMK8055_CNT1_REG;
958                 } else {
959                         cmd = VMK8055_CMD_RST_CNT2;
960                         reg = VMK8055_CNT2_REG;
961                 }
962
963                 dev->usb_tx_buf[reg] = 0x00;
964         } else {
965                 cmd = VMK8061_CMD_RST_CNT;
966         }
967
968         for (n = 0; n < insn->n; n++)
969                 if (vmk80xx_write_packet(dev, cmd))
970                         break;
971
972         up(&dev->limit_sem);
973
974         return n;
975 }
976
977 static int vmk80xx_cnt_winsn(struct comedi_device *cdev,
978                              struct comedi_subdevice *s,
979                              struct comedi_insn *insn, unsigned int *data)
980 {
981         struct vmk80xx_usb *dev = cdev->private;
982         unsigned long debtime;
983         unsigned long val;
984         int chan;
985         int cmd;
986         int n;
987
988         n = rudimentary_check(dev, DIR_OUT);
989         if (n)
990                 return n;
991
992         down(&dev->limit_sem);
993         chan = CR_CHAN(insn->chanspec);
994
995         if (!chan)
996                 cmd = VMK8055_CMD_DEB1_TIME;
997         else
998                 cmd = VMK8055_CMD_DEB2_TIME;
999
1000         for (n = 0; n < insn->n; n++) {
1001                 debtime = data[n];
1002                 if (debtime == 0)
1003                         debtime = 1;
1004
1005                 /* TODO: Prevent overflows */
1006                 if (debtime > 7450)
1007                         debtime = 7450;
1008
1009                 val = int_sqrt(debtime * 1000 / 115);
1010                 if (((val + 1) * val) < debtime * 1000 / 115)
1011                         val += 1;
1012
1013                 dev->usb_tx_buf[6 + chan] = val;
1014
1015                 if (vmk80xx_write_packet(dev, cmd))
1016                         break;
1017         }
1018
1019         up(&dev->limit_sem);
1020
1021         return n;
1022 }
1023
1024 static int vmk80xx_pwm_rinsn(struct comedi_device *cdev,
1025                              struct comedi_subdevice *s,
1026                              struct comedi_insn *insn, unsigned int *data)
1027 {
1028         struct vmk80xx_usb *dev = cdev->private;
1029         int reg[2];
1030         int n;
1031
1032         n = rudimentary_check(dev, DIR_IN);
1033         if (n)
1034                 return n;
1035
1036         down(&dev->limit_sem);
1037
1038         reg[0] = VMK8061_PWM_REG1;
1039         reg[1] = VMK8061_PWM_REG2;
1040
1041         dev->usb_tx_buf[0] = VMK8061_CMD_RD_PWM;
1042
1043         for (n = 0; n < insn->n; n++) {
1044                 if (vmk80xx_read_packet(dev))
1045                         break;
1046
1047                 data[n] = dev->usb_rx_buf[reg[0]] + 4 * dev->usb_rx_buf[reg[1]];
1048         }
1049
1050         up(&dev->limit_sem);
1051
1052         return n;
1053 }
1054
1055 static int vmk80xx_pwm_winsn(struct comedi_device *cdev,
1056                              struct comedi_subdevice *s,
1057                              struct comedi_insn *insn, unsigned int *data)
1058 {
1059         struct vmk80xx_usb *dev = cdev->private;
1060         unsigned char *tx_buf;
1061         int reg[2];
1062         int cmd;
1063         int n;
1064
1065         n = rudimentary_check(dev, DIR_OUT);
1066         if (n)
1067                 return n;
1068
1069         down(&dev->limit_sem);
1070
1071         tx_buf = dev->usb_tx_buf;
1072
1073         reg[0] = VMK8061_PWM_REG1;
1074         reg[1] = VMK8061_PWM_REG2;
1075
1076         cmd = VMK8061_CMD_OUT_PWM;
1077
1078         /*
1079          * The followin piece of code was translated from the inline
1080          * assembler code in the DLL source code.
1081          *
1082          * asm
1083          *   mov eax, k  ; k is the value (data[n])
1084          *   and al, 03h ; al are the lower 8 bits of eax
1085          *   mov lo, al  ; lo is the low part (tx_buf[reg[0]])
1086          *   mov eax, k
1087          *   shr eax, 2  ; right shift eax register by 2
1088          *   mov hi, al  ; hi is the high part (tx_buf[reg[1]])
1089          * end;
1090          */
1091         for (n = 0; n < insn->n; n++) {
1092                 tx_buf[reg[0]] = (unsigned char)(data[n] & 0x03);
1093                 tx_buf[reg[1]] = (unsigned char)(data[n] >> 2) & 0xff;
1094
1095                 if (vmk80xx_write_packet(dev, cmd))
1096                         break;
1097         }
1098
1099         up(&dev->limit_sem);
1100
1101         return n;
1102 }
1103
1104 static int vmk80xx_attach_common(struct comedi_device *cdev,
1105                                  struct vmk80xx_usb *dev)
1106 {
1107         int n_subd;
1108         struct comedi_subdevice *s;
1109         int ret;
1110
1111         down(&dev->limit_sem);
1112         cdev->board_name = dev->board.name;
1113         cdev->private = dev;
1114         if (dev->board.model == VMK8055_MODEL)
1115                 n_subd = 5;
1116         else
1117                 n_subd = 6;
1118         ret = comedi_alloc_subdevices(cdev, n_subd);
1119         if (ret) {
1120                 up(&dev->limit_sem);
1121                 return ret;
1122         }
1123         /* Analog input subdevice */
1124         s = &cdev->subdevices[VMK80XX_SUBD_AI];
1125         s->type = COMEDI_SUBD_AI;
1126         s->subdev_flags = SDF_READABLE | SDF_GROUND;
1127         s->n_chan = dev->board.ai_chans;
1128         s->maxdata = (1 << dev->board.ai_bits) - 1;
1129         s->range_table = dev->board.range;
1130         s->insn_read = vmk80xx_ai_rinsn;
1131         /* Analog output subdevice */
1132         s = &cdev->subdevices[VMK80XX_SUBD_AO];
1133         s->type = COMEDI_SUBD_AO;
1134         s->subdev_flags = SDF_WRITEABLE | SDF_GROUND;
1135         s->n_chan = dev->board.ao_chans;
1136         s->maxdata = (1 << dev->board.ao_bits) - 1;
1137         s->range_table = dev->board.range;
1138         s->insn_write = vmk80xx_ao_winsn;
1139         if (dev->board.model == VMK8061_MODEL) {
1140                 s->subdev_flags |= SDF_READABLE;
1141                 s->insn_read = vmk80xx_ao_rinsn;
1142         }
1143         /* Digital input subdevice */
1144         s = &cdev->subdevices[VMK80XX_SUBD_DI];
1145         s->type = COMEDI_SUBD_DI;
1146         s->subdev_flags = SDF_READABLE | SDF_GROUND;
1147         s->n_chan = dev->board.di_chans;
1148         s->maxdata = 1;
1149         s->insn_read = vmk80xx_di_rinsn;
1150         s->insn_bits = vmk80xx_di_bits;
1151         /* Digital output subdevice */
1152         s = &cdev->subdevices[VMK80XX_SUBD_DO];
1153         s->type = COMEDI_SUBD_DO;
1154         s->subdev_flags = SDF_WRITEABLE | SDF_GROUND;
1155         s->n_chan = dev->board.do_chans;
1156         s->maxdata = 1;
1157         s->insn_write = vmk80xx_do_winsn;
1158         s->insn_bits = vmk80xx_do_bits;
1159         if (dev->board.model == VMK8061_MODEL) {
1160                 s->subdev_flags |= SDF_READABLE;
1161                 s->insn_read = vmk80xx_do_rinsn;
1162         }
1163         /* Counter subdevice */
1164         s = &cdev->subdevices[VMK80XX_SUBD_CNT];
1165         s->type = COMEDI_SUBD_COUNTER;
1166         s->subdev_flags = SDF_READABLE;
1167         s->n_chan = dev->board.cnt_chans;
1168         s->insn_read = vmk80xx_cnt_rinsn;
1169         s->insn_config = vmk80xx_cnt_cinsn;
1170         if (dev->board.model == VMK8055_MODEL) {
1171                 s->subdev_flags |= SDF_WRITEABLE;
1172                 s->maxdata = (1 << dev->board.cnt_bits) - 1;
1173                 s->insn_write = vmk80xx_cnt_winsn;
1174         }
1175         /* PWM subdevice */
1176         if (dev->board.model == VMK8061_MODEL) {
1177                 s = &cdev->subdevices[VMK80XX_SUBD_PWM];
1178                 s->type = COMEDI_SUBD_PWM;
1179                 s->subdev_flags = SDF_READABLE | SDF_WRITEABLE;
1180                 s->n_chan = dev->board.pwm_chans;
1181                 s->maxdata = (1 << dev->board.pwm_bits) - 1;
1182                 s->insn_read = vmk80xx_pwm_rinsn;
1183                 s->insn_write = vmk80xx_pwm_winsn;
1184         }
1185         dev->attached = 1;
1186         dev_info(cdev->class_dev, "vmk80xx: board #%d [%s] attached\n",
1187                  dev->count, dev->board.name);
1188         up(&dev->limit_sem);
1189         return 0;
1190 }
1191
1192 static int vmk80xx_auto_attach(struct comedi_device *cdev,
1193                                unsigned long context_unused)
1194 {
1195         struct usb_interface *intf = comedi_to_usb_interface(cdev);
1196         int i;
1197         int ret;
1198
1199         mutex_lock(&glb_mutex);
1200         for (i = 0; i < VMK80XX_MAX_BOARDS; i++)
1201                 if (vmb[i].probed && vmb[i].intf == intf)
1202                         break;
1203         if (i == VMK80XX_MAX_BOARDS)
1204                 ret = -ENODEV;
1205         else if (vmb[i].attached)
1206                 ret = -EBUSY;
1207         else
1208                 ret = vmk80xx_attach_common(cdev, &vmb[i]);
1209         mutex_unlock(&glb_mutex);
1210         return ret;
1211 }
1212
1213 static void vmk80xx_detach(struct comedi_device *dev)
1214 {
1215         struct vmk80xx_usb *usb = dev->private;
1216
1217         if (!usb)
1218                 return;
1219
1220         mutex_lock(&glb_mutex);
1221         down(&usb->limit_sem);
1222
1223         dev->private = NULL;
1224
1225         usb->attached = 0;
1226         usb->probed = 0;
1227         usb_set_intfdata(usb->intf, NULL);
1228
1229         usb_kill_anchored_urbs(&usb->rx_anchor);
1230         usb_kill_anchored_urbs(&usb->tx_anchor);
1231
1232         kfree(usb->usb_rx_buf);
1233         kfree(usb->usb_tx_buf);
1234
1235         up(&usb->limit_sem);
1236         mutex_unlock(&glb_mutex);
1237 }
1238
1239 static struct comedi_driver vmk80xx_driver = {
1240         .module         = THIS_MODULE,
1241         .driver_name    = "vmk80xx",
1242         .auto_attach    = vmk80xx_auto_attach,
1243         .detach         = vmk80xx_detach,
1244 };
1245
1246 static int vmk80xx_usb_probe(struct usb_interface *intf,
1247                              const struct usb_device_id *id)
1248 {
1249         int i;
1250         struct vmk80xx_usb *dev;
1251         struct usb_host_interface *iface_desc;
1252         struct usb_endpoint_descriptor *ep_desc;
1253         size_t size;
1254
1255         mutex_lock(&glb_mutex);
1256
1257         for (i = 0; i < VMK80XX_MAX_BOARDS; i++)
1258                 if (!vmb[i].probed)
1259                         break;
1260
1261         if (i == VMK80XX_MAX_BOARDS) {
1262                 mutex_unlock(&glb_mutex);
1263                 return -EMFILE;
1264         }
1265
1266         dev = &vmb[i];
1267
1268         memset(dev, 0x00, sizeof(struct vmk80xx_usb));
1269         dev->count = i;
1270
1271         iface_desc = intf->cur_altsetting;
1272         if (iface_desc->desc.bNumEndpoints != 2)
1273                 goto error;
1274
1275         for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
1276                 ep_desc = &iface_desc->endpoint[i].desc;
1277
1278                 if (usb_endpoint_is_int_in(ep_desc)) {
1279                         dev->ep_rx = ep_desc;
1280                         continue;
1281                 }
1282
1283                 if (usb_endpoint_is_int_out(ep_desc)) {
1284                         dev->ep_tx = ep_desc;
1285                         continue;
1286                 }
1287
1288                 if (usb_endpoint_is_bulk_in(ep_desc)) {
1289                         dev->ep_rx = ep_desc;
1290                         continue;
1291                 }
1292
1293                 if (usb_endpoint_is_bulk_out(ep_desc)) {
1294                         dev->ep_tx = ep_desc;
1295                         continue;
1296                 }
1297         }
1298
1299         if (!dev->ep_rx || !dev->ep_tx)
1300                 goto error;
1301
1302         size = le16_to_cpu(dev->ep_rx->wMaxPacketSize);
1303         dev->usb_rx_buf = kmalloc(size, GFP_KERNEL);
1304         if (!dev->usb_rx_buf) {
1305                 mutex_unlock(&glb_mutex);
1306                 return -ENOMEM;
1307         }
1308
1309         size = le16_to_cpu(dev->ep_tx->wMaxPacketSize);
1310         dev->usb_tx_buf = kmalloc(size, GFP_KERNEL);
1311         if (!dev->usb_tx_buf) {
1312                 kfree(dev->usb_rx_buf);
1313                 mutex_unlock(&glb_mutex);
1314                 return -ENOMEM;
1315         }
1316
1317         dev->udev = interface_to_usbdev(intf);
1318         dev->intf = intf;
1319
1320         sema_init(&dev->limit_sem, 8);
1321         init_waitqueue_head(&dev->read_wait);
1322         init_waitqueue_head(&dev->write_wait);
1323
1324         init_usb_anchor(&dev->rx_anchor);
1325         init_usb_anchor(&dev->tx_anchor);
1326
1327         usb_set_intfdata(intf, dev);
1328
1329         switch (id->driver_info) {
1330         case DEVICE_VMK8055:
1331                 dev->board.name = "K8055 (VM110)";
1332                 dev->board.model = VMK8055_MODEL;
1333                 dev->board.range = &vmk8055_range;
1334                 dev->board.ai_chans = 2;
1335                 dev->board.ai_bits = 8;
1336                 dev->board.ao_chans = 2;
1337                 dev->board.ao_bits = 8;
1338                 dev->board.di_chans = 5;
1339                 dev->board.di_bits = 1;
1340                 dev->board.do_chans = 8;
1341                 dev->board.do_bits = 1;
1342                 dev->board.cnt_chans = 2;
1343                 dev->board.cnt_bits = 16;
1344                 dev->board.pwm_chans = 0;
1345                 dev->board.pwm_bits = 0;
1346                 break;
1347         case DEVICE_VMK8061:
1348                 dev->board.name = "K8061 (VM140)";
1349                 dev->board.model = VMK8061_MODEL;
1350                 dev->board.range = &vmk8061_range;
1351                 dev->board.ai_chans = 8;
1352                 dev->board.ai_bits = 10;
1353                 dev->board.ao_chans = 8;
1354                 dev->board.ao_bits = 8;
1355                 dev->board.di_chans = 8;
1356                 dev->board.di_bits = 1;
1357                 dev->board.do_chans = 8;
1358                 dev->board.do_bits = 1;
1359                 dev->board.cnt_chans = 2;
1360                 dev->board.cnt_bits = 0;
1361                 dev->board.pwm_chans = 1;
1362                 dev->board.pwm_bits = 10;
1363                 break;
1364         }
1365
1366         if (dev->board.model == VMK8061_MODEL) {
1367                 vmk80xx_read_eeprom(dev, IC3_VERSION);
1368                 dev_info(&intf->dev, "%s\n", dev->fw.ic3_vers);
1369
1370                 if (vmk80xx_check_data_link(dev)) {
1371                         vmk80xx_read_eeprom(dev, IC6_VERSION);
1372                         dev_info(&intf->dev, "%s\n", dev->fw.ic6_vers);
1373                 } else {
1374                         dbgcm("comedi#: vmk80xx: no conn. to CPU\n");
1375                 }
1376         }
1377
1378         if (dev->board.model == VMK8055_MODEL)
1379                 vmk80xx_reset_device(dev);
1380
1381         dev->probed = 1;
1382
1383         dev_info(&intf->dev, "board #%d [%s] now attached\n",
1384                  dev->count, dev->board.name);
1385
1386         mutex_unlock(&glb_mutex);
1387
1388         comedi_usb_auto_config(intf, &vmk80xx_driver);
1389
1390         return 0;
1391 error:
1392         mutex_unlock(&glb_mutex);
1393
1394         return -ENODEV;
1395 }
1396
1397 static void vmk80xx_usb_disconnect(struct usb_interface *intf)
1398 {
1399         comedi_usb_auto_unconfig(intf);
1400 }
1401
1402 static const struct usb_device_id vmk80xx_usb_id_table[] = {
1403         { USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055 },
1404         { USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055 },
1405         { USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055 },
1406         { USB_DEVICE(0x10cf, 0x5503), .driver_info = DEVICE_VMK8055 },
1407         { USB_DEVICE(0x10cf, 0x8061), .driver_info = DEVICE_VMK8061 },
1408         { USB_DEVICE(0x10cf, 0x8062), .driver_info = DEVICE_VMK8061 },
1409         { USB_DEVICE(0x10cf, 0x8063), .driver_info = DEVICE_VMK8061 },
1410         { USB_DEVICE(0x10cf, 0x8064), .driver_info = DEVICE_VMK8061 },
1411         { USB_DEVICE(0x10cf, 0x8065), .driver_info = DEVICE_VMK8061 },
1412         { USB_DEVICE(0x10cf, 0x8066), .driver_info = DEVICE_VMK8061 },
1413         { USB_DEVICE(0x10cf, 0x8067), .driver_info = DEVICE_VMK8061 },
1414         { USB_DEVICE(0x10cf, 0x8068), .driver_info = DEVICE_VMK8061 },
1415         { }
1416 };
1417 MODULE_DEVICE_TABLE(usb, vmk80xx_usb_id_table);
1418
1419 /* TODO: Add support for suspend, resume, pre_reset,
1420  * post_reset and flush */
1421 static struct usb_driver vmk80xx_usb_driver = {
1422         .name           = "vmk80xx",
1423         .probe          = vmk80xx_usb_probe,
1424         .disconnect     = vmk80xx_usb_disconnect,
1425         .id_table       = vmk80xx_usb_id_table,
1426 };
1427 module_comedi_usb_driver(vmk80xx_driver, vmk80xx_usb_driver);
1428
1429 MODULE_AUTHOR("Manuel Gebele <forensixs@gmx.de>");
1430 MODULE_DESCRIPTION("Velleman USB Board Low-Level Driver");
1431 MODULE_SUPPORTED_DEVICE("K8055/K8061 aka VM110/VM140");
1432 MODULE_VERSION("0.8.01");
1433 MODULE_LICENSE("GPL");