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