]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/comedi/drivers/vmk80xx.c
staging: comedi: usbduxsigma: Declare MODULE_FIRMWARE usage
[karo-tx-linux.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                 reg[0] = VMK8061_AI_REG1;
550                 reg[1] = VMK8061_AI_REG2;
551                 dev->usb_tx_buf[0] = VMK8061_CMD_RD_AI;
552                 dev->usb_tx_buf[VMK8061_CH_REG] = chan;
553                 break;
554         }
555
556         for (n = 0; n < insn->n; n++) {
557                 if (vmk80xx_read_packet(dev))
558                         break;
559
560                 if (dev->board.model == VMK8055_MODEL) {
561                         data[n] = dev->usb_rx_buf[reg[0]];
562                         continue;
563                 }
564
565                 /* VMK8061_MODEL */
566                 data[n] = dev->usb_rx_buf[reg[0]] + 256 *
567                     dev->usb_rx_buf[reg[1]];
568         }
569
570         up(&dev->limit_sem);
571
572         return n;
573 }
574
575 static int vmk80xx_ao_winsn(struct comedi_device *cdev,
576                             struct comedi_subdevice *s,
577                             struct comedi_insn *insn, unsigned int *data)
578 {
579         struct vmk80xx_usb *dev = cdev->private;
580         int chan;
581         int cmd;
582         int reg;
583         int n;
584
585         n = rudimentary_check(dev, DIR_OUT);
586         if (n)
587                 return n;
588
589         down(&dev->limit_sem);
590         chan = CR_CHAN(insn->chanspec);
591
592         switch (dev->board.model) {
593         case VMK8055_MODEL:
594                 cmd = VMK8055_CMD_WRT_AD;
595                 if (!chan)
596                         reg = VMK8055_AO1_REG;
597                 else
598                         reg = VMK8055_AO2_REG;
599                 break;
600         default:                /* NOTE: avoid compiler warnings */
601                 cmd = VMK8061_CMD_SET_AO;
602                 reg = VMK8061_AO_REG;
603                 dev->usb_tx_buf[VMK8061_CH_REG] = chan;
604                 break;
605         }
606
607         for (n = 0; n < insn->n; n++) {
608                 dev->usb_tx_buf[reg] = data[n];
609
610                 if (vmk80xx_write_packet(dev, cmd))
611                         break;
612         }
613
614         up(&dev->limit_sem);
615
616         return n;
617 }
618
619 static int vmk80xx_ao_rinsn(struct comedi_device *cdev,
620                             struct comedi_subdevice *s,
621                             struct comedi_insn *insn, unsigned int *data)
622 {
623         struct vmk80xx_usb *dev = cdev->private;
624         int chan;
625         int reg;
626         int n;
627
628         n = rudimentary_check(dev, DIR_IN);
629         if (n)
630                 return n;
631
632         down(&dev->limit_sem);
633         chan = CR_CHAN(insn->chanspec);
634
635         reg = VMK8061_AO_REG - 1;
636
637         dev->usb_tx_buf[0] = VMK8061_CMD_RD_AO;
638
639         for (n = 0; n < insn->n; n++) {
640                 if (vmk80xx_read_packet(dev))
641                         break;
642
643                 data[n] = dev->usb_rx_buf[reg + chan];
644         }
645
646         up(&dev->limit_sem);
647
648         return n;
649 }
650
651 static int vmk80xx_di_bits(struct comedi_device *cdev,
652                            struct comedi_subdevice *s,
653                            struct comedi_insn *insn, unsigned int *data)
654 {
655         struct vmk80xx_usb *dev = cdev->private;
656         unsigned char *rx_buf;
657         int reg;
658         int retval;
659
660         retval = rudimentary_check(dev, DIR_IN);
661         if (retval)
662                 return retval;
663
664         down(&dev->limit_sem);
665
666         rx_buf = dev->usb_rx_buf;
667
668         if (dev->board.model == VMK8061_MODEL) {
669                 reg = VMK8061_DI_REG;
670                 dev->usb_tx_buf[0] = VMK8061_CMD_RD_DI;
671         } else {
672                 reg = VMK8055_DI_REG;
673         }
674
675         retval = vmk80xx_read_packet(dev);
676
677         if (!retval) {
678                 if (dev->board.model == VMK8055_MODEL)
679                         data[1] = (((rx_buf[reg] >> 4) & 0x03) |
680                                   ((rx_buf[reg] << 2) & 0x04) |
681                                   ((rx_buf[reg] >> 3) & 0x18));
682                 else
683                         data[1] = rx_buf[reg];
684
685                 retval = 2;
686         }
687
688         up(&dev->limit_sem);
689
690         return retval;
691 }
692
693 static int vmk80xx_di_rinsn(struct comedi_device *cdev,
694                             struct comedi_subdevice *s,
695                             struct comedi_insn *insn, unsigned int *data)
696 {
697         struct vmk80xx_usb *dev = cdev->private;
698         int chan;
699         unsigned char *rx_buf;
700         int reg;
701         int inp;
702         int n;
703
704         n = rudimentary_check(dev, DIR_IN);
705         if (n)
706                 return n;
707
708         down(&dev->limit_sem);
709         chan = CR_CHAN(insn->chanspec);
710
711         rx_buf = dev->usb_rx_buf;
712
713         if (dev->board.model == VMK8061_MODEL) {
714                 reg = VMK8061_DI_REG;
715                 dev->usb_tx_buf[0] = VMK8061_CMD_RD_DI;
716         } else {
717                 reg = VMK8055_DI_REG;
718         }
719         for (n = 0; n < insn->n; n++) {
720                 if (vmk80xx_read_packet(dev))
721                         break;
722
723                 if (dev->board.model == VMK8055_MODEL)
724                         inp = (((rx_buf[reg] >> 4) & 0x03) |
725                                ((rx_buf[reg] << 2) & 0x04) |
726                                ((rx_buf[reg] >> 3) & 0x18));
727                 else
728                         inp = rx_buf[reg];
729
730                 data[n] = (inp >> chan) & 1;
731         }
732
733         up(&dev->limit_sem);
734
735         return n;
736 }
737
738 static int vmk80xx_do_winsn(struct comedi_device *cdev,
739                             struct comedi_subdevice *s,
740                             struct comedi_insn *insn, unsigned int *data)
741 {
742         struct vmk80xx_usb *dev = cdev->private;
743         int chan;
744         unsigned char *tx_buf;
745         int reg;
746         int cmd;
747         int n;
748
749         n = rudimentary_check(dev, DIR_OUT);
750         if (n)
751                 return n;
752
753         down(&dev->limit_sem);
754         chan = CR_CHAN(insn->chanspec);
755
756         tx_buf = dev->usb_tx_buf;
757
758         for (n = 0; n < insn->n; n++) {
759                 if (dev->board.model == VMK8055_MODEL) {
760                         reg = VMK8055_DO_REG;
761                         cmd = VMK8055_CMD_WRT_AD;
762                         if (data[n] == 1)
763                                 tx_buf[reg] |= (1 << chan);
764                         else
765                                 tx_buf[reg] ^= (1 << chan);
766                 } else { /* VMK8061_MODEL */
767                         reg = VMK8061_DO_REG;
768                         if (data[n] == 1) {
769                                 cmd = VMK8061_CMD_SET_DO;
770                                 tx_buf[reg] = 1 << chan;
771                         } else {
772                                 cmd = VMK8061_CMD_CLR_DO;
773                                 tx_buf[reg] = 0xff - (1 << chan);
774                         }
775                 }
776
777                 if (vmk80xx_write_packet(dev, cmd))
778                         break;
779         }
780
781         up(&dev->limit_sem);
782
783         return n;
784 }
785
786 static int vmk80xx_do_rinsn(struct comedi_device *cdev,
787                             struct comedi_subdevice *s,
788                             struct comedi_insn *insn, unsigned int *data)
789 {
790         struct vmk80xx_usb *dev = cdev->private;
791         int chan;
792         int reg;
793         int n;
794
795         n = rudimentary_check(dev, DIR_IN);
796         if (n)
797                 return n;
798
799         down(&dev->limit_sem);
800         chan = CR_CHAN(insn->chanspec);
801
802         reg = VMK8061_DO_REG;
803
804         dev->usb_tx_buf[0] = VMK8061_CMD_RD_DO;
805
806         for (n = 0; n < insn->n; n++) {
807                 if (vmk80xx_read_packet(dev))
808                         break;
809
810                 data[n] = (dev->usb_rx_buf[reg] >> chan) & 1;
811         }
812
813         up(&dev->limit_sem);
814
815         return n;
816 }
817
818 static int vmk80xx_do_bits(struct comedi_device *cdev,
819                            struct comedi_subdevice *s,
820                            struct comedi_insn *insn, unsigned int *data)
821 {
822         struct vmk80xx_usb *dev = cdev->private;
823         unsigned char *rx_buf, *tx_buf;
824         int dir, reg, cmd;
825         int retval;
826
827         dir = 0;
828
829         if (data[0])
830                 dir |= DIR_OUT;
831
832         if (dev->board.model == VMK8061_MODEL)
833                 dir |= DIR_IN;
834
835         retval = rudimentary_check(dev, dir);
836         if (retval)
837                 return retval;
838
839         down(&dev->limit_sem);
840
841         rx_buf = dev->usb_rx_buf;
842         tx_buf = dev->usb_tx_buf;
843
844         if (data[0]) {
845                 if (dev->board.model == VMK8055_MODEL) {
846                         reg = VMK8055_DO_REG;
847                         cmd = VMK8055_CMD_WRT_AD;
848                 } else { /* VMK8061_MODEL */
849                         reg = VMK8061_DO_REG;
850                         cmd = VMK8061_CMD_DO;
851                 }
852
853                 tx_buf[reg] &= ~data[0];
854                 tx_buf[reg] |= (data[0] & data[1]);
855
856                 retval = vmk80xx_write_packet(dev, cmd);
857
858                 if (retval)
859                         goto out;
860         }
861
862         if (dev->board.model == VMK8061_MODEL) {
863                 reg = VMK8061_DO_REG;
864                 tx_buf[0] = VMK8061_CMD_RD_DO;
865
866                 retval = vmk80xx_read_packet(dev);
867
868                 if (!retval) {
869                         data[1] = rx_buf[reg];
870                         retval = 2;
871                 }
872         } else {
873                 data[1] = tx_buf[reg];
874                 retval = 2;
875         }
876
877 out:
878         up(&dev->limit_sem);
879
880         return retval;
881 }
882
883 static int vmk80xx_cnt_rinsn(struct comedi_device *cdev,
884                              struct comedi_subdevice *s,
885                              struct comedi_insn *insn, unsigned int *data)
886 {
887         struct vmk80xx_usb *dev = cdev->private;
888         int chan;
889         int reg[2];
890         int n;
891
892         n = rudimentary_check(dev, DIR_IN);
893         if (n)
894                 return n;
895
896         down(&dev->limit_sem);
897         chan = CR_CHAN(insn->chanspec);
898
899         switch (dev->board.model) {
900         case VMK8055_MODEL:
901                 if (!chan)
902                         reg[0] = VMK8055_CNT1_REG;
903                 else
904                         reg[0] = VMK8055_CNT2_REG;
905                 break;
906         case VMK8061_MODEL:
907                 reg[0] = VMK8061_CNT_REG;
908                 reg[1] = VMK8061_CNT_REG;
909                 dev->usb_tx_buf[0] = VMK8061_CMD_RD_CNT;
910                 break;
911         }
912
913         for (n = 0; n < insn->n; n++) {
914                 if (vmk80xx_read_packet(dev))
915                         break;
916
917                 if (dev->board.model == VMK8055_MODEL)
918                         data[n] = dev->usb_rx_buf[reg[0]];
919                 else /* VMK8061_MODEL */
920                         data[n] = dev->usb_rx_buf[reg[0] * (chan + 1) + 1]
921                             + 256 * dev->usb_rx_buf[reg[1] * 2 + 2];
922         }
923
924         up(&dev->limit_sem);
925
926         return n;
927 }
928
929 static int vmk80xx_cnt_cinsn(struct comedi_device *cdev,
930                              struct comedi_subdevice *s,
931                              struct comedi_insn *insn, unsigned int *data)
932 {
933         struct vmk80xx_usb *dev = cdev->private;
934         unsigned int insn_cmd;
935         int chan;
936         int cmd;
937         int reg;
938         int n;
939
940         n = rudimentary_check(dev, DIR_OUT);
941         if (n)
942                 return n;
943
944         insn_cmd = data[0];
945         if (insn_cmd != INSN_CONFIG_RESET && insn_cmd != GPCT_RESET)
946                 return -EINVAL;
947
948         down(&dev->limit_sem);
949
950         chan = CR_CHAN(insn->chanspec);
951
952         if (dev->board.model == VMK8055_MODEL) {
953                 if (!chan) {
954                         cmd = VMK8055_CMD_RST_CNT1;
955                         reg = VMK8055_CNT1_REG;
956                 } else {
957                         cmd = VMK8055_CMD_RST_CNT2;
958                         reg = VMK8055_CNT2_REG;
959                 }
960
961                 dev->usb_tx_buf[reg] = 0x00;
962         } else {
963                 cmd = VMK8061_CMD_RST_CNT;
964         }
965
966         for (n = 0; n < insn->n; n++)
967                 if (vmk80xx_write_packet(dev, cmd))
968                         break;
969
970         up(&dev->limit_sem);
971
972         return n;
973 }
974
975 static int vmk80xx_cnt_winsn(struct comedi_device *cdev,
976                              struct comedi_subdevice *s,
977                              struct comedi_insn *insn, unsigned int *data)
978 {
979         struct vmk80xx_usb *dev = cdev->private;
980         unsigned long debtime;
981         unsigned long val;
982         int chan;
983         int cmd;
984         int n;
985
986         n = rudimentary_check(dev, DIR_OUT);
987         if (n)
988                 return n;
989
990         down(&dev->limit_sem);
991         chan = CR_CHAN(insn->chanspec);
992
993         if (!chan)
994                 cmd = VMK8055_CMD_DEB1_TIME;
995         else
996                 cmd = VMK8055_CMD_DEB2_TIME;
997
998         for (n = 0; n < insn->n; n++) {
999                 debtime = data[n];
1000                 if (debtime == 0)
1001                         debtime = 1;
1002
1003                 /* TODO: Prevent overflows */
1004                 if (debtime > 7450)
1005                         debtime = 7450;
1006
1007                 val = int_sqrt(debtime * 1000 / 115);
1008                 if (((val + 1) * val) < debtime * 1000 / 115)
1009                         val += 1;
1010
1011                 dev->usb_tx_buf[6 + chan] = val;
1012
1013                 if (vmk80xx_write_packet(dev, cmd))
1014                         break;
1015         }
1016
1017         up(&dev->limit_sem);
1018
1019         return n;
1020 }
1021
1022 static int vmk80xx_pwm_rinsn(struct comedi_device *cdev,
1023                              struct comedi_subdevice *s,
1024                              struct comedi_insn *insn, unsigned int *data)
1025 {
1026         struct vmk80xx_usb *dev = cdev->private;
1027         int reg[2];
1028         int n;
1029
1030         n = rudimentary_check(dev, DIR_IN);
1031         if (n)
1032                 return n;
1033
1034         down(&dev->limit_sem);
1035
1036         reg[0] = VMK8061_PWM_REG1;
1037         reg[1] = VMK8061_PWM_REG2;
1038
1039         dev->usb_tx_buf[0] = VMK8061_CMD_RD_PWM;
1040
1041         for (n = 0; n < insn->n; n++) {
1042                 if (vmk80xx_read_packet(dev))
1043                         break;
1044
1045                 data[n] = dev->usb_rx_buf[reg[0]] + 4 * dev->usb_rx_buf[reg[1]];
1046         }
1047
1048         up(&dev->limit_sem);
1049
1050         return n;
1051 }
1052
1053 static int vmk80xx_pwm_winsn(struct comedi_device *cdev,
1054                              struct comedi_subdevice *s,
1055                              struct comedi_insn *insn, unsigned int *data)
1056 {
1057         struct vmk80xx_usb *dev = cdev->private;
1058         unsigned char *tx_buf;
1059         int reg[2];
1060         int cmd;
1061         int n;
1062
1063         n = rudimentary_check(dev, DIR_OUT);
1064         if (n)
1065                 return n;
1066
1067         down(&dev->limit_sem);
1068
1069         tx_buf = dev->usb_tx_buf;
1070
1071         reg[0] = VMK8061_PWM_REG1;
1072         reg[1] = VMK8061_PWM_REG2;
1073
1074         cmd = VMK8061_CMD_OUT_PWM;
1075
1076         /*
1077          * The followin piece of code was translated from the inline
1078          * assembler code in the DLL source code.
1079          *
1080          * asm
1081          *   mov eax, k  ; k is the value (data[n])
1082          *   and al, 03h ; al are the lower 8 bits of eax
1083          *   mov lo, al  ; lo is the low part (tx_buf[reg[0]])
1084          *   mov eax, k
1085          *   shr eax, 2  ; right shift eax register by 2
1086          *   mov hi, al  ; hi is the high part (tx_buf[reg[1]])
1087          * end;
1088          */
1089         for (n = 0; n < insn->n; n++) {
1090                 tx_buf[reg[0]] = (unsigned char)(data[n] & 0x03);
1091                 tx_buf[reg[1]] = (unsigned char)(data[n] >> 2) & 0xff;
1092
1093                 if (vmk80xx_write_packet(dev, cmd))
1094                         break;
1095         }
1096
1097         up(&dev->limit_sem);
1098
1099         return n;
1100 }
1101
1102 static int vmk80xx_attach_common(struct comedi_device *cdev,
1103                                  struct vmk80xx_usb *dev)
1104 {
1105         int n_subd;
1106         struct comedi_subdevice *s;
1107         int ret;
1108
1109         down(&dev->limit_sem);
1110         cdev->board_name = dev->board.name;
1111         cdev->private = dev;
1112         if (dev->board.model == VMK8055_MODEL)
1113                 n_subd = 5;
1114         else
1115                 n_subd = 6;
1116         ret = comedi_alloc_subdevices(cdev, n_subd);
1117         if (ret) {
1118                 up(&dev->limit_sem);
1119                 return ret;
1120         }
1121         /* Analog input subdevice */
1122         s = cdev->subdevices + VMK80XX_SUBD_AI;
1123         s->type = COMEDI_SUBD_AI;
1124         s->subdev_flags = SDF_READABLE | SDF_GROUND;
1125         s->n_chan = dev->board.ai_chans;
1126         s->maxdata = (1 << dev->board.ai_bits) - 1;
1127         s->range_table = dev->board.range;
1128         s->insn_read = vmk80xx_ai_rinsn;
1129         /* Analog output subdevice */
1130         s = cdev->subdevices + VMK80XX_SUBD_AO;
1131         s->type = COMEDI_SUBD_AO;
1132         s->subdev_flags = SDF_WRITEABLE | SDF_GROUND;
1133         s->n_chan = dev->board.ao_chans;
1134         s->maxdata = (1 << dev->board.ao_bits) - 1;
1135         s->range_table = dev->board.range;
1136         s->insn_write = vmk80xx_ao_winsn;
1137         if (dev->board.model == VMK8061_MODEL) {
1138                 s->subdev_flags |= SDF_READABLE;
1139                 s->insn_read = vmk80xx_ao_rinsn;
1140         }
1141         /* Digital input subdevice */
1142         s = cdev->subdevices + VMK80XX_SUBD_DI;
1143         s->type = COMEDI_SUBD_DI;
1144         s->subdev_flags = SDF_READABLE | SDF_GROUND;
1145         s->n_chan = dev->board.di_chans;
1146         s->maxdata = 1;
1147         s->insn_read = vmk80xx_di_rinsn;
1148         s->insn_bits = vmk80xx_di_bits;
1149         /* Digital output subdevice */
1150         s = cdev->subdevices + VMK80XX_SUBD_DO;
1151         s->type = COMEDI_SUBD_DO;
1152         s->subdev_flags = SDF_WRITEABLE | SDF_GROUND;
1153         s->n_chan = dev->board.do_chans;
1154         s->maxdata = 1;
1155         s->insn_write = vmk80xx_do_winsn;
1156         s->insn_bits = vmk80xx_do_bits;
1157         if (dev->board.model == VMK8061_MODEL) {
1158                 s->subdev_flags |= SDF_READABLE;
1159                 s->insn_read = vmk80xx_do_rinsn;
1160         }
1161         /* Counter subdevice */
1162         s = cdev->subdevices + VMK80XX_SUBD_CNT;
1163         s->type = COMEDI_SUBD_COUNTER;
1164         s->subdev_flags = SDF_READABLE;
1165         s->n_chan = dev->board.cnt_chans;
1166         s->insn_read = vmk80xx_cnt_rinsn;
1167         s->insn_config = vmk80xx_cnt_cinsn;
1168         if (dev->board.model == VMK8055_MODEL) {
1169                 s->subdev_flags |= SDF_WRITEABLE;
1170                 s->maxdata = (1 << dev->board.cnt_bits) - 1;
1171                 s->insn_write = vmk80xx_cnt_winsn;
1172         }
1173         /* PWM subdevice */
1174         if (dev->board.model == VMK8061_MODEL) {
1175                 s = cdev->subdevices + VMK80XX_SUBD_PWM;
1176                 s->type = COMEDI_SUBD_PWM;
1177                 s->subdev_flags = SDF_READABLE | SDF_WRITEABLE;
1178                 s->n_chan = dev->board.pwm_chans;
1179                 s->maxdata = (1 << dev->board.pwm_bits) - 1;
1180                 s->insn_read = vmk80xx_pwm_rinsn;
1181                 s->insn_write = vmk80xx_pwm_winsn;
1182         }
1183         dev->attached = 1;
1184         dev_info(cdev->class_dev, "vmk80xx: board #%d [%s] attached\n",
1185                  dev->count, dev->board.name);
1186         up(&dev->limit_sem);
1187         return 0;
1188 }
1189
1190 /* called for COMEDI_DEVCONFIG ioctl for board_name "vmk80xx" */
1191 static int vmk80xx_attach(struct comedi_device *cdev,
1192                           struct comedi_devconfig *it)
1193 {
1194         int i;
1195         int ret;
1196
1197         mutex_lock(&glb_mutex);
1198         for (i = 0; i < VMK80XX_MAX_BOARDS; i++)
1199                 if (vmb[i].probed && !vmb[i].attached)
1200                         break;
1201         if (i == VMK80XX_MAX_BOARDS)
1202                 ret = -ENODEV;
1203         else
1204                 ret = vmk80xx_attach_common(cdev, &vmb[i]);
1205         mutex_unlock(&glb_mutex);
1206         return ret;
1207 }
1208
1209 /* called via comedi_usb_auto_config() */
1210 static int vmk80xx_attach_usb(struct comedi_device *cdev,
1211                               struct usb_interface *intf)
1212 {
1213         int i;
1214         int ret;
1215
1216         mutex_lock(&glb_mutex);
1217         for (i = 0; i < VMK80XX_MAX_BOARDS; i++)
1218                 if (vmb[i].probed && vmb[i].intf == intf)
1219                         break;
1220         if (i == VMK80XX_MAX_BOARDS)
1221                 ret = -ENODEV;
1222         else if (vmb[i].attached)
1223                 ret = -EBUSY;
1224         else
1225                 ret = vmk80xx_attach_common(cdev, &vmb[i]);
1226         mutex_unlock(&glb_mutex);
1227         return ret;
1228 }
1229
1230 static void vmk80xx_detach(struct comedi_device *dev)
1231 {
1232         struct vmk80xx_usb *usb = dev->private;
1233
1234         if (usb) {
1235                 down(&usb->limit_sem);
1236                 dev->private = NULL;
1237                 usb->attached = 0;
1238                 up(&usb->limit_sem);
1239         }
1240 }
1241
1242 static struct comedi_driver vmk80xx_driver = {
1243         .module         = THIS_MODULE,
1244         .driver_name    = "vmk80xx",
1245         .attach         = vmk80xx_attach,
1246         .detach         = vmk80xx_detach,
1247         .attach_usb     = vmk80xx_attach_usb,
1248 };
1249
1250 static int vmk80xx_usb_probe(struct usb_interface *intf,
1251                              const struct usb_device_id *id)
1252 {
1253         int i;
1254         struct vmk80xx_usb *dev;
1255         struct usb_host_interface *iface_desc;
1256         struct usb_endpoint_descriptor *ep_desc;
1257         size_t size;
1258
1259         mutex_lock(&glb_mutex);
1260
1261         for (i = 0; i < VMK80XX_MAX_BOARDS; i++)
1262                 if (!vmb[i].probed)
1263                         break;
1264
1265         if (i == VMK80XX_MAX_BOARDS) {
1266                 mutex_unlock(&glb_mutex);
1267                 return -EMFILE;
1268         }
1269
1270         dev = &vmb[i];
1271
1272         memset(dev, 0x00, sizeof(struct vmk80xx_usb));
1273         dev->count = i;
1274
1275         iface_desc = intf->cur_altsetting;
1276         if (iface_desc->desc.bNumEndpoints != 2)
1277                 goto error;
1278
1279         for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
1280                 ep_desc = &iface_desc->endpoint[i].desc;
1281
1282                 if (usb_endpoint_is_int_in(ep_desc)) {
1283                         dev->ep_rx = ep_desc;
1284                         continue;
1285                 }
1286
1287                 if (usb_endpoint_is_int_out(ep_desc)) {
1288                         dev->ep_tx = ep_desc;
1289                         continue;
1290                 }
1291
1292                 if (usb_endpoint_is_bulk_in(ep_desc)) {
1293                         dev->ep_rx = ep_desc;
1294                         continue;
1295                 }
1296
1297                 if (usb_endpoint_is_bulk_out(ep_desc)) {
1298                         dev->ep_tx = ep_desc;
1299                         continue;
1300                 }
1301         }
1302
1303         if (!dev->ep_rx || !dev->ep_tx)
1304                 goto error;
1305
1306         size = le16_to_cpu(dev->ep_rx->wMaxPacketSize);
1307         dev->usb_rx_buf = kmalloc(size, GFP_KERNEL);
1308         if (!dev->usb_rx_buf) {
1309                 mutex_unlock(&glb_mutex);
1310                 return -ENOMEM;
1311         }
1312
1313         size = le16_to_cpu(dev->ep_tx->wMaxPacketSize);
1314         dev->usb_tx_buf = kmalloc(size, GFP_KERNEL);
1315         if (!dev->usb_tx_buf) {
1316                 kfree(dev->usb_rx_buf);
1317                 mutex_unlock(&glb_mutex);
1318                 return -ENOMEM;
1319         }
1320
1321         dev->udev = interface_to_usbdev(intf);
1322         dev->intf = intf;
1323
1324         sema_init(&dev->limit_sem, 8);
1325         init_waitqueue_head(&dev->read_wait);
1326         init_waitqueue_head(&dev->write_wait);
1327
1328         init_usb_anchor(&dev->rx_anchor);
1329         init_usb_anchor(&dev->tx_anchor);
1330
1331         usb_set_intfdata(intf, dev);
1332
1333         switch (id->driver_info) {
1334         case DEVICE_VMK8055:
1335                 dev->board.name = "K8055 (VM110)";
1336                 dev->board.model = VMK8055_MODEL;
1337                 dev->board.range = &vmk8055_range;
1338                 dev->board.ai_chans = 2;
1339                 dev->board.ai_bits = 8;
1340                 dev->board.ao_chans = 2;
1341                 dev->board.ao_bits = 8;
1342                 dev->board.di_chans = 5;
1343                 dev->board.di_bits = 1;
1344                 dev->board.do_chans = 8;
1345                 dev->board.do_bits = 1;
1346                 dev->board.cnt_chans = 2;
1347                 dev->board.cnt_bits = 16;
1348                 dev->board.pwm_chans = 0;
1349                 dev->board.pwm_bits = 0;
1350                 break;
1351         case DEVICE_VMK8061:
1352                 dev->board.name = "K8061 (VM140)";
1353                 dev->board.model = VMK8061_MODEL;
1354                 dev->board.range = &vmk8061_range;
1355                 dev->board.ai_chans = 8;
1356                 dev->board.ai_bits = 10;
1357                 dev->board.ao_chans = 8;
1358                 dev->board.ao_bits = 8;
1359                 dev->board.di_chans = 8;
1360                 dev->board.di_bits = 1;
1361                 dev->board.do_chans = 8;
1362                 dev->board.do_bits = 1;
1363                 dev->board.cnt_chans = 2;
1364                 dev->board.cnt_bits = 0;
1365                 dev->board.pwm_chans = 1;
1366                 dev->board.pwm_bits = 10;
1367                 break;
1368         }
1369
1370         if (dev->board.model == VMK8061_MODEL) {
1371                 vmk80xx_read_eeprom(dev, IC3_VERSION);
1372                 printk(KERN_INFO "comedi#: vmk80xx: %s\n", dev->fw.ic3_vers);
1373
1374                 if (vmk80xx_check_data_link(dev)) {
1375                         vmk80xx_read_eeprom(dev, IC6_VERSION);
1376                         printk(KERN_INFO "comedi#: vmk80xx: %s\n",
1377                                dev->fw.ic6_vers);
1378                 } else {
1379                         dbgcm("comedi#: vmk80xx: no conn. to CPU\n");
1380                 }
1381         }
1382
1383         if (dev->board.model == VMK8055_MODEL)
1384                 vmk80xx_reset_device(dev);
1385
1386         dev->probed = 1;
1387
1388         printk(KERN_INFO "comedi#: vmk80xx: board #%d [%s] now attached\n",
1389                dev->count, dev->board.name);
1390
1391         mutex_unlock(&glb_mutex);
1392
1393         comedi_usb_auto_config(intf, &vmk80xx_driver);
1394
1395         return 0;
1396 error:
1397         mutex_unlock(&glb_mutex);
1398
1399         return -ENODEV;
1400 }
1401
1402 static void vmk80xx_usb_disconnect(struct usb_interface *intf)
1403 {
1404         struct vmk80xx_usb *dev = usb_get_intfdata(intf);
1405
1406         if (!dev)
1407                 return;
1408
1409         comedi_usb_auto_unconfig(intf);
1410
1411         mutex_lock(&glb_mutex);
1412         down(&dev->limit_sem);
1413
1414         dev->probed = 0;
1415         usb_set_intfdata(dev->intf, NULL);
1416
1417         usb_kill_anchored_urbs(&dev->rx_anchor);
1418         usb_kill_anchored_urbs(&dev->tx_anchor);
1419
1420         kfree(dev->usb_rx_buf);
1421         kfree(dev->usb_tx_buf);
1422
1423         printk(KERN_INFO "comedi#: vmk80xx: board #%d [%s] now detached\n",
1424                dev->count, dev->board.name);
1425
1426         up(&dev->limit_sem);
1427         mutex_unlock(&glb_mutex);
1428 }
1429
1430 static const struct usb_device_id vmk80xx_usb_id_table[] = {
1431         { USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055 },
1432         { USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055 },
1433         { USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055 },
1434         { USB_DEVICE(0x10cf, 0x5503), .driver_info = DEVICE_VMK8055 },
1435         { USB_DEVICE(0x10cf, 0x8061), .driver_info = DEVICE_VMK8061 },
1436         { USB_DEVICE(0x10cf, 0x8062), .driver_info = DEVICE_VMK8061 },
1437         { USB_DEVICE(0x10cf, 0x8063), .driver_info = DEVICE_VMK8061 },
1438         { USB_DEVICE(0x10cf, 0x8064), .driver_info = DEVICE_VMK8061 },
1439         { USB_DEVICE(0x10cf, 0x8065), .driver_info = DEVICE_VMK8061 },
1440         { USB_DEVICE(0x10cf, 0x8066), .driver_info = DEVICE_VMK8061 },
1441         { USB_DEVICE(0x10cf, 0x8067), .driver_info = DEVICE_VMK8061 },
1442         { USB_DEVICE(0x10cf, 0x8068), .driver_info = DEVICE_VMK8061 },
1443         { }
1444 };
1445 MODULE_DEVICE_TABLE(usb, vmk80xx_usb_id_table);
1446
1447 /* TODO: Add support for suspend, resume, pre_reset,
1448  * post_reset and flush */
1449 static struct usb_driver vmk80xx_usb_driver = {
1450         .name           = "vmk80xx",
1451         .probe          = vmk80xx_usb_probe,
1452         .disconnect     = vmk80xx_usb_disconnect,
1453         .id_table       = vmk80xx_usb_id_table,
1454 };
1455 module_comedi_usb_driver(vmk80xx_driver, vmk80xx_usb_driver);
1456
1457 MODULE_AUTHOR("Manuel Gebele <forensixs@gmx.de>");
1458 MODULE_DESCRIPTION("Velleman USB Board Low-Level Driver");
1459 MODULE_SUPPORTED_DEVICE("K8055/K8061 aka VM110/VM140");
1460 MODULE_VERSION("0.8.01");
1461 MODULE_LICENSE("GPL");