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