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