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