Merge tag 'stable/for-linus-3.8-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel...
[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 /* called for COMEDI_DEVCONFIG ioctl for board_name "vmk80xx" */
1193 static int vmk80xx_attach(struct comedi_device *cdev,
1194                           struct comedi_devconfig *it)
1195 {
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].attached)
1202                         break;
1203         if (i == VMK80XX_MAX_BOARDS)
1204                 ret = -ENODEV;
1205         else
1206                 ret = vmk80xx_attach_common(cdev, &vmb[i]);
1207         mutex_unlock(&glb_mutex);
1208         return ret;
1209 }
1210
1211 /* called via comedi_usb_auto_config() */
1212 static int vmk80xx_auto_attach(struct comedi_device *cdev,
1213                                unsigned long context_unused)
1214 {
1215         struct usb_interface *intf = comedi_to_usb_interface(cdev);
1216         int i;
1217         int ret;
1218
1219         mutex_lock(&glb_mutex);
1220         for (i = 0; i < VMK80XX_MAX_BOARDS; i++)
1221                 if (vmb[i].probed && vmb[i].intf == intf)
1222                         break;
1223         if (i == VMK80XX_MAX_BOARDS)
1224                 ret = -ENODEV;
1225         else if (vmb[i].attached)
1226                 ret = -EBUSY;
1227         else
1228                 ret = vmk80xx_attach_common(cdev, &vmb[i]);
1229         mutex_unlock(&glb_mutex);
1230         return ret;
1231 }
1232
1233 static void vmk80xx_detach(struct comedi_device *dev)
1234 {
1235         struct vmk80xx_usb *usb = dev->private;
1236
1237         if (usb) {
1238                 down(&usb->limit_sem);
1239                 dev->private = NULL;
1240                 usb->attached = 0;
1241                 up(&usb->limit_sem);
1242         }
1243 }
1244
1245 static struct comedi_driver vmk80xx_driver = {
1246         .module         = THIS_MODULE,
1247         .driver_name    = "vmk80xx",
1248         .attach         = vmk80xx_attach,
1249         .detach         = vmk80xx_detach,
1250         .auto_attach    = vmk80xx_auto_attach,
1251 };
1252
1253 static int vmk80xx_usb_probe(struct usb_interface *intf,
1254                              const struct usb_device_id *id)
1255 {
1256         int i;
1257         struct vmk80xx_usb *dev;
1258         struct usb_host_interface *iface_desc;
1259         struct usb_endpoint_descriptor *ep_desc;
1260         size_t size;
1261
1262         mutex_lock(&glb_mutex);
1263
1264         for (i = 0; i < VMK80XX_MAX_BOARDS; i++)
1265                 if (!vmb[i].probed)
1266                         break;
1267
1268         if (i == VMK80XX_MAX_BOARDS) {
1269                 mutex_unlock(&glb_mutex);
1270                 return -EMFILE;
1271         }
1272
1273         dev = &vmb[i];
1274
1275         memset(dev, 0x00, sizeof(struct vmk80xx_usb));
1276         dev->count = i;
1277
1278         iface_desc = intf->cur_altsetting;
1279         if (iface_desc->desc.bNumEndpoints != 2)
1280                 goto error;
1281
1282         for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
1283                 ep_desc = &iface_desc->endpoint[i].desc;
1284
1285                 if (usb_endpoint_is_int_in(ep_desc)) {
1286                         dev->ep_rx = ep_desc;
1287                         continue;
1288                 }
1289
1290                 if (usb_endpoint_is_int_out(ep_desc)) {
1291                         dev->ep_tx = ep_desc;
1292                         continue;
1293                 }
1294
1295                 if (usb_endpoint_is_bulk_in(ep_desc)) {
1296                         dev->ep_rx = ep_desc;
1297                         continue;
1298                 }
1299
1300                 if (usb_endpoint_is_bulk_out(ep_desc)) {
1301                         dev->ep_tx = ep_desc;
1302                         continue;
1303                 }
1304         }
1305
1306         if (!dev->ep_rx || !dev->ep_tx)
1307                 goto error;
1308
1309         size = le16_to_cpu(dev->ep_rx->wMaxPacketSize);
1310         dev->usb_rx_buf = kmalloc(size, GFP_KERNEL);
1311         if (!dev->usb_rx_buf) {
1312                 mutex_unlock(&glb_mutex);
1313                 return -ENOMEM;
1314         }
1315
1316         size = le16_to_cpu(dev->ep_tx->wMaxPacketSize);
1317         dev->usb_tx_buf = kmalloc(size, GFP_KERNEL);
1318         if (!dev->usb_tx_buf) {
1319                 kfree(dev->usb_rx_buf);
1320                 mutex_unlock(&glb_mutex);
1321                 return -ENOMEM;
1322         }
1323
1324         dev->udev = interface_to_usbdev(intf);
1325         dev->intf = intf;
1326
1327         sema_init(&dev->limit_sem, 8);
1328         init_waitqueue_head(&dev->read_wait);
1329         init_waitqueue_head(&dev->write_wait);
1330
1331         init_usb_anchor(&dev->rx_anchor);
1332         init_usb_anchor(&dev->tx_anchor);
1333
1334         usb_set_intfdata(intf, dev);
1335
1336         switch (id->driver_info) {
1337         case DEVICE_VMK8055:
1338                 dev->board.name = "K8055 (VM110)";
1339                 dev->board.model = VMK8055_MODEL;
1340                 dev->board.range = &vmk8055_range;
1341                 dev->board.ai_chans = 2;
1342                 dev->board.ai_bits = 8;
1343                 dev->board.ao_chans = 2;
1344                 dev->board.ao_bits = 8;
1345                 dev->board.di_chans = 5;
1346                 dev->board.di_bits = 1;
1347                 dev->board.do_chans = 8;
1348                 dev->board.do_bits = 1;
1349                 dev->board.cnt_chans = 2;
1350                 dev->board.cnt_bits = 16;
1351                 dev->board.pwm_chans = 0;
1352                 dev->board.pwm_bits = 0;
1353                 break;
1354         case DEVICE_VMK8061:
1355                 dev->board.name = "K8061 (VM140)";
1356                 dev->board.model = VMK8061_MODEL;
1357                 dev->board.range = &vmk8061_range;
1358                 dev->board.ai_chans = 8;
1359                 dev->board.ai_bits = 10;
1360                 dev->board.ao_chans = 8;
1361                 dev->board.ao_bits = 8;
1362                 dev->board.di_chans = 8;
1363                 dev->board.di_bits = 1;
1364                 dev->board.do_chans = 8;
1365                 dev->board.do_bits = 1;
1366                 dev->board.cnt_chans = 2;
1367                 dev->board.cnt_bits = 0;
1368                 dev->board.pwm_chans = 1;
1369                 dev->board.pwm_bits = 10;
1370                 break;
1371         }
1372
1373         if (dev->board.model == VMK8061_MODEL) {
1374                 vmk80xx_read_eeprom(dev, IC3_VERSION);
1375                 dev_info(&intf->dev, "%s\n", dev->fw.ic3_vers);
1376
1377                 if (vmk80xx_check_data_link(dev)) {
1378                         vmk80xx_read_eeprom(dev, IC6_VERSION);
1379                         dev_info(&intf->dev, "%s\n", dev->fw.ic6_vers);
1380                 } else {
1381                         dbgcm("comedi#: vmk80xx: no conn. to CPU\n");
1382                 }
1383         }
1384
1385         if (dev->board.model == VMK8055_MODEL)
1386                 vmk80xx_reset_device(dev);
1387
1388         dev->probed = 1;
1389
1390         dev_info(&intf->dev, "board #%d [%s] now attached\n",
1391                  dev->count, dev->board.name);
1392
1393         mutex_unlock(&glb_mutex);
1394
1395         comedi_usb_auto_config(intf, &vmk80xx_driver);
1396
1397         return 0;
1398 error:
1399         mutex_unlock(&glb_mutex);
1400
1401         return -ENODEV;
1402 }
1403
1404 static void vmk80xx_usb_disconnect(struct usb_interface *intf)
1405 {
1406         struct vmk80xx_usb *dev = usb_get_intfdata(intf);
1407
1408         if (!dev)
1409                 return;
1410
1411         comedi_usb_auto_unconfig(intf);
1412
1413         mutex_lock(&glb_mutex);
1414         down(&dev->limit_sem);
1415
1416         dev->probed = 0;
1417         usb_set_intfdata(dev->intf, NULL);
1418
1419         usb_kill_anchored_urbs(&dev->rx_anchor);
1420         usb_kill_anchored_urbs(&dev->tx_anchor);
1421
1422         kfree(dev->usb_rx_buf);
1423         kfree(dev->usb_tx_buf);
1424
1425         dev_info(&intf->dev, "board #%d [%s] now detached\n",
1426                  dev->count, dev->board.name);
1427
1428         up(&dev->limit_sem);
1429         mutex_unlock(&glb_mutex);
1430 }
1431
1432 static const struct usb_device_id vmk80xx_usb_id_table[] = {
1433         { USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055 },
1434         { USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055 },
1435         { USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055 },
1436         { USB_DEVICE(0x10cf, 0x5503), .driver_info = DEVICE_VMK8055 },
1437         { USB_DEVICE(0x10cf, 0x8061), .driver_info = DEVICE_VMK8061 },
1438         { USB_DEVICE(0x10cf, 0x8062), .driver_info = DEVICE_VMK8061 },
1439         { USB_DEVICE(0x10cf, 0x8063), .driver_info = DEVICE_VMK8061 },
1440         { USB_DEVICE(0x10cf, 0x8064), .driver_info = DEVICE_VMK8061 },
1441         { USB_DEVICE(0x10cf, 0x8065), .driver_info = DEVICE_VMK8061 },
1442         { USB_DEVICE(0x10cf, 0x8066), .driver_info = DEVICE_VMK8061 },
1443         { USB_DEVICE(0x10cf, 0x8067), .driver_info = DEVICE_VMK8061 },
1444         { USB_DEVICE(0x10cf, 0x8068), .driver_info = DEVICE_VMK8061 },
1445         { }
1446 };
1447 MODULE_DEVICE_TABLE(usb, vmk80xx_usb_id_table);
1448
1449 /* TODO: Add support for suspend, resume, pre_reset,
1450  * post_reset and flush */
1451 static struct usb_driver vmk80xx_usb_driver = {
1452         .name           = "vmk80xx",
1453         .probe          = vmk80xx_usb_probe,
1454         .disconnect     = vmk80xx_usb_disconnect,
1455         .id_table       = vmk80xx_usb_id_table,
1456 };
1457 module_comedi_usb_driver(vmk80xx_driver, vmk80xx_usb_driver);
1458
1459 MODULE_AUTHOR("Manuel Gebele <forensixs@gmx.de>");
1460 MODULE_DESCRIPTION("Velleman USB Board Low-Level Driver");
1461 MODULE_SUPPORTED_DEVICE("K8055/K8061 aka VM110/VM140");
1462 MODULE_VERSION("0.8.01");
1463 MODULE_LICENSE("GPL");