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