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