2 comedi/drivers/vmk80xx.c
3 Velleman USB Board Low-Level Driver
5 Copyright (C) 2009 Manuel Gebele <forensixs@gmx.de>, Germany
7 COMEDI - Linux Control and Measurement Device Interface
8 Copyright (C) 2000 David A. Schleef <ds@schleef.org>
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.
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.
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.
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
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
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
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>
65 #include "../comedidev.h"
72 #define VMK8055_DI_REG 0x00
73 #define VMK8055_DO_REG 0x01
74 #define VMK8055_AO1_REG 0x02
75 #define VMK8055_AO2_REG 0x03
76 #define VMK8055_AI1_REG 0x02
77 #define VMK8055_AI2_REG 0x03
78 #define VMK8055_CNT1_REG 0x04
79 #define VMK8055_CNT2_REG 0x06
81 #define VMK8061_CH_REG 0x01
82 #define VMK8061_DI_REG 0x01
83 #define VMK8061_DO_REG 0x01
84 #define VMK8061_PWM_REG1 0x01
85 #define VMK8061_PWM_REG2 0x02
86 #define VMK8061_CNT_REG 0x02
87 #define VMK8061_AO_REG 0x02
88 #define VMK8061_AI_REG1 0x02
89 #define VMK8061_AI_REG2 0x03
91 #define VMK8055_CMD_RST 0x00
92 #define VMK8055_CMD_DEB1_TIME 0x01
93 #define VMK8055_CMD_DEB2_TIME 0x02
94 #define VMK8055_CMD_RST_CNT1 0x03
95 #define VMK8055_CMD_RST_CNT2 0x04
96 #define VMK8055_CMD_WRT_AD 0x05
98 #define VMK8061_CMD_RD_AI 0x00
99 #define VMK8061_CMR_RD_ALL_AI 0x01 /* !non-active! */
100 #define VMK8061_CMD_SET_AO 0x02
101 #define VMK8061_CMD_SET_ALL_AO 0x03 /* !non-active! */
102 #define VMK8061_CMD_OUT_PWM 0x04
103 #define VMK8061_CMD_RD_DI 0x05
104 #define VMK8061_CMD_DO 0x06 /* !non-active! */
105 #define VMK8061_CMD_CLR_DO 0x07
106 #define VMK8061_CMD_SET_DO 0x08
107 #define VMK8061_CMD_RD_CNT 0x09 /* TODO: completely pointless? */
108 #define VMK8061_CMD_RST_CNT 0x0a /* TODO: completely pointless? */
109 #define VMK8061_CMD_RD_VERSION 0x0b /* internal usage */
110 #define VMK8061_CMD_RD_JMP_STAT 0x0c /* TODO: not implemented yet */
111 #define VMK8061_CMD_RD_PWR_STAT 0x0d /* internal usage */
112 #define VMK8061_CMD_RD_DO 0x0e
113 #define VMK8061_CMD_RD_AO 0x0f
114 #define VMK8061_CMD_RD_PWM 0x10
116 #define VMK80XX_MAX_BOARDS COMEDI_NUM_BOARD_MINORS
118 #define TRANS_OUT_BUSY 1
119 #define TRANS_IN_BUSY 2
120 #define TRANS_IN_RUNNING 3
122 #define IC3_VERSION (1 << 0)
123 #define IC6_VERSION (1 << 1)
125 #define URB_RCV_FLAG (1 << 0)
126 #define URB_SND_FLAG (1 << 1)
128 #ifdef CONFIG_COMEDI_DEBUG
129 static int dbgcm
= 1;
134 #define dbgcm(fmt, arg...) \
137 printk(KERN_DEBUG fmt, ##arg); \
145 struct firmware_version
{
146 unsigned char ic3_vers
[32]; /* USB-Controller */
147 unsigned char ic6_vers
[32]; /* CPU */
150 static const struct comedi_lrange vmk8055_range
= {
154 static const struct comedi_lrange vmk8061_range
= {
155 2, {UNI_RANGE(5), UNI_RANGE(10)}
158 struct vmk80xx_board
{
160 enum vmk80xx_model model
;
161 const struct comedi_lrange
*range
;
186 struct usb_device
*udev
;
187 struct usb_interface
*intf
;
188 struct usb_endpoint_descriptor
*ep_rx
;
189 struct usb_endpoint_descriptor
*ep_tx
;
190 struct usb_anchor rx_anchor
;
191 struct usb_anchor tx_anchor
;
192 struct vmk80xx_board board
;
193 struct firmware_version fw
;
194 struct semaphore limit_sem
;
195 wait_queue_head_t read_wait
;
196 wait_queue_head_t write_wait
;
197 unsigned char *usb_rx_buf
;
198 unsigned char *usb_tx_buf
;
205 static struct vmk80xx_usb vmb
[VMK80XX_MAX_BOARDS
];
207 static DEFINE_MUTEX(glb_mutex
);
209 static void vmk80xx_tx_callback(struct urb
*urb
)
211 struct vmk80xx_usb
*dev
= urb
->context
;
212 int stat
= urb
->status
;
214 if (stat
&& !(stat
== -ENOENT
215 || stat
== -ECONNRESET
|| stat
== -ESHUTDOWN
))
216 dbgcm("comedi#: vmk80xx: %s - nonzero urb status (%d)\n",
219 if (!test_bit(TRANS_OUT_BUSY
, &dev
->flags
))
222 clear_bit(TRANS_OUT_BUSY
, &dev
->flags
);
224 wake_up_interruptible(&dev
->write_wait
);
227 static void vmk80xx_rx_callback(struct urb
*urb
)
229 struct vmk80xx_usb
*dev
= urb
->context
;
230 int stat
= urb
->status
;
240 dbgcm("comedi#: vmk80xx: %s - nonzero urb status (%d)\n",
247 if (test_bit(TRANS_IN_RUNNING
, &dev
->flags
) && dev
->intf
) {
248 usb_anchor_urb(urb
, &dev
->rx_anchor
);
250 if (!usb_submit_urb(urb
, GFP_KERNEL
))
253 dev_err(&urb
->dev
->dev
,
254 "comedi#: vmk80xx: %s - submit urb failed\n",
257 usb_unanchor_urb(urb
);
260 clear_bit(TRANS_IN_BUSY
, &dev
->flags
);
262 wake_up_interruptible(&dev
->read_wait
);
265 static int vmk80xx_check_data_link(struct vmk80xx_usb
*dev
)
267 unsigned int tx_pipe
;
268 unsigned int rx_pipe
;
272 tx_pipe
= usb_sndbulkpipe(dev
->udev
, 0x01);
273 rx_pipe
= usb_rcvbulkpipe(dev
->udev
, 0x81);
275 tx
[0] = VMK8061_CMD_RD_PWR_STAT
;
278 * Check that IC6 (PIC16F871) is powered and
279 * running and the data link between IC3 and
280 * IC6 is working properly
282 usb_bulk_msg(dev
->udev
, tx_pipe
, tx
, 1, NULL
, dev
->ep_tx
->bInterval
);
283 usb_bulk_msg(dev
->udev
, rx_pipe
, rx
, 2, NULL
, HZ
* 10);
288 static void vmk80xx_read_eeprom(struct vmk80xx_usb
*dev
, int flag
)
290 unsigned int tx_pipe
;
291 unsigned int rx_pipe
;
293 unsigned char rx
[64];
296 tx_pipe
= usb_sndbulkpipe(dev
->udev
, 0x01);
297 rx_pipe
= usb_rcvbulkpipe(dev
->udev
, 0x81);
299 tx
[0] = VMK8061_CMD_RD_VERSION
;
302 * Read the firmware version info of IC3 and
303 * IC6 from the internal EEPROM of the IC
305 usb_bulk_msg(dev
->udev
, tx_pipe
, tx
, 1, NULL
, dev
->ep_tx
->bInterval
);
306 usb_bulk_msg(dev
->udev
, rx_pipe
, rx
, 64, &cnt
, HZ
* 10);
310 if (flag
& IC3_VERSION
)
311 strncpy(dev
->fw
.ic3_vers
, rx
+ 1, 24);
312 else /* IC6_VERSION */
313 strncpy(dev
->fw
.ic6_vers
, rx
+ 25, 24);
316 static int vmk80xx_reset_device(struct vmk80xx_usb
*dev
)
319 unsigned int tx_pipe
;
323 urb
= usb_alloc_urb(0, GFP_KERNEL
);
327 tx_pipe
= usb_sndintpipe(dev
->udev
, 0x01);
329 ival
= dev
->ep_tx
->bInterval
;
330 size
= le16_to_cpu(dev
->ep_tx
->wMaxPacketSize
);
332 dev
->usb_tx_buf
[0] = VMK8055_CMD_RST
;
333 dev
->usb_tx_buf
[1] = 0x00;
334 dev
->usb_tx_buf
[2] = 0x00;
335 dev
->usb_tx_buf
[3] = 0x00;
336 dev
->usb_tx_buf
[4] = 0x00;
337 dev
->usb_tx_buf
[5] = 0x00;
338 dev
->usb_tx_buf
[6] = 0x00;
339 dev
->usb_tx_buf
[7] = 0x00;
341 usb_fill_int_urb(urb
, dev
->udev
, tx_pipe
, dev
->usb_tx_buf
,
342 size
, vmk80xx_tx_callback
, dev
, ival
);
344 usb_anchor_urb(urb
, &dev
->tx_anchor
);
346 return usb_submit_urb(urb
, GFP_KERNEL
);
349 static void vmk80xx_build_int_urb(struct urb
*urb
, int flag
)
351 struct vmk80xx_usb
*dev
= urb
->context
;
357 void (*callback
) (struct urb
*);
360 if (flag
& URB_RCV_FLAG
) {
361 rx_addr
= dev
->ep_rx
->bEndpointAddress
;
362 pipe
= usb_rcvintpipe(dev
->udev
, rx_addr
);
363 buf
= dev
->usb_rx_buf
;
364 size
= le16_to_cpu(dev
->ep_rx
->wMaxPacketSize
);
365 callback
= vmk80xx_rx_callback
;
366 ival
= dev
->ep_rx
->bInterval
;
367 } else { /* URB_SND_FLAG */
368 tx_addr
= dev
->ep_tx
->bEndpointAddress
;
369 pipe
= usb_sndintpipe(dev
->udev
, tx_addr
);
370 buf
= dev
->usb_tx_buf
;
371 size
= le16_to_cpu(dev
->ep_tx
->wMaxPacketSize
);
372 callback
= vmk80xx_tx_callback
;
373 ival
= dev
->ep_tx
->bInterval
;
376 usb_fill_int_urb(urb
, dev
->udev
, pipe
, buf
, size
, callback
, dev
, ival
);
379 static void vmk80xx_do_bulk_msg(struct vmk80xx_usb
*dev
)
383 unsigned int tx_pipe
;
384 unsigned int rx_pipe
;
387 set_bit(TRANS_IN_BUSY
, &dev
->flags
);
388 set_bit(TRANS_OUT_BUSY
, &dev
->flags
);
390 tx_addr
= dev
->ep_tx
->bEndpointAddress
;
391 rx_addr
= dev
->ep_rx
->bEndpointAddress
;
392 tx_pipe
= usb_sndbulkpipe(dev
->udev
, tx_addr
);
393 rx_pipe
= usb_rcvbulkpipe(dev
->udev
, rx_addr
);
396 * The max packet size attributes of the K8061
397 * input/output endpoints are identical
399 size
= le16_to_cpu(dev
->ep_tx
->wMaxPacketSize
);
401 usb_bulk_msg(dev
->udev
, tx_pipe
, dev
->usb_tx_buf
,
402 size
, NULL
, dev
->ep_tx
->bInterval
);
403 usb_bulk_msg(dev
->udev
, rx_pipe
, dev
->usb_rx_buf
, size
, NULL
, HZ
* 10);
405 clear_bit(TRANS_OUT_BUSY
, &dev
->flags
);
406 clear_bit(TRANS_IN_BUSY
, &dev
->flags
);
409 static int vmk80xx_read_packet(struct vmk80xx_usb
*dev
)
417 /* Only useful for interrupt transfers */
418 if (test_bit(TRANS_IN_BUSY
, &dev
->flags
))
419 if (wait_event_interruptible(dev
->read_wait
,
420 !test_bit(TRANS_IN_BUSY
,
424 if (dev
->board
.model
== VMK8061_MODEL
) {
425 vmk80xx_do_bulk_msg(dev
);
430 urb
= usb_alloc_urb(0, GFP_KERNEL
);
435 vmk80xx_build_int_urb(urb
, URB_RCV_FLAG
);
437 set_bit(TRANS_IN_RUNNING
, &dev
->flags
);
438 set_bit(TRANS_IN_BUSY
, &dev
->flags
);
440 usb_anchor_urb(urb
, &dev
->rx_anchor
);
442 retval
= usb_submit_urb(urb
, GFP_KERNEL
);
446 clear_bit(TRANS_IN_RUNNING
, &dev
->flags
);
447 usb_unanchor_urb(urb
);
455 static int vmk80xx_write_packet(struct vmk80xx_usb
*dev
, int cmd
)
463 if (test_bit(TRANS_OUT_BUSY
, &dev
->flags
))
464 if (wait_event_interruptible(dev
->write_wait
,
465 !test_bit(TRANS_OUT_BUSY
,
469 if (dev
->board
.model
== VMK8061_MODEL
) {
470 dev
->usb_tx_buf
[0] = cmd
;
471 vmk80xx_do_bulk_msg(dev
);
476 urb
= usb_alloc_urb(0, GFP_KERNEL
);
481 vmk80xx_build_int_urb(urb
, URB_SND_FLAG
);
483 set_bit(TRANS_OUT_BUSY
, &dev
->flags
);
485 usb_anchor_urb(urb
, &dev
->tx_anchor
);
487 dev
->usb_tx_buf
[0] = cmd
;
489 retval
= usb_submit_urb(urb
, GFP_KERNEL
);
493 clear_bit(TRANS_OUT_BUSY
, &dev
->flags
);
494 usb_unanchor_urb(urb
);
505 static int rudimentary_check(struct vmk80xx_usb
*dev
, int dir
)
514 if (test_bit(TRANS_IN_BUSY
, &dev
->flags
))
518 if (test_bit(TRANS_OUT_BUSY
, &dev
->flags
))
525 static int vmk80xx_ai_rinsn(struct comedi_device
*cdev
,
526 struct comedi_subdevice
*s
,
527 struct comedi_insn
*insn
, unsigned int *data
)
529 struct vmk80xx_usb
*dev
= cdev
->private;
534 n
= rudimentary_check(dev
, DIR_IN
);
538 down(&dev
->limit_sem
);
539 chan
= CR_CHAN(insn
->chanspec
);
541 switch (dev
->board
.model
) {
544 reg
[0] = VMK8055_AI1_REG
;
546 reg
[0] = VMK8055_AI2_REG
;
550 reg
[0] = VMK8061_AI_REG1
;
551 reg
[1] = VMK8061_AI_REG2
;
552 dev
->usb_tx_buf
[0] = VMK8061_CMD_RD_AI
;
553 dev
->usb_tx_buf
[VMK8061_CH_REG
] = chan
;
557 for (n
= 0; n
< insn
->n
; n
++) {
558 if (vmk80xx_read_packet(dev
))
561 if (dev
->board
.model
== VMK8055_MODEL
) {
562 data
[n
] = dev
->usb_rx_buf
[reg
[0]];
567 data
[n
] = dev
->usb_rx_buf
[reg
[0]] + 256 *
568 dev
->usb_rx_buf
[reg
[1]];
576 static int vmk80xx_ao_winsn(struct comedi_device
*cdev
,
577 struct comedi_subdevice
*s
,
578 struct comedi_insn
*insn
, unsigned int *data
)
580 struct vmk80xx_usb
*dev
= cdev
->private;
586 n
= rudimentary_check(dev
, DIR_OUT
);
590 down(&dev
->limit_sem
);
591 chan
= CR_CHAN(insn
->chanspec
);
593 switch (dev
->board
.model
) {
595 cmd
= VMK8055_CMD_WRT_AD
;
597 reg
= VMK8055_AO1_REG
;
599 reg
= VMK8055_AO2_REG
;
601 default: /* NOTE: avoid compiler warnings */
602 cmd
= VMK8061_CMD_SET_AO
;
603 reg
= VMK8061_AO_REG
;
604 dev
->usb_tx_buf
[VMK8061_CH_REG
] = chan
;
608 for (n
= 0; n
< insn
->n
; n
++) {
609 dev
->usb_tx_buf
[reg
] = data
[n
];
611 if (vmk80xx_write_packet(dev
, cmd
))
620 static int vmk80xx_ao_rinsn(struct comedi_device
*cdev
,
621 struct comedi_subdevice
*s
,
622 struct comedi_insn
*insn
, unsigned int *data
)
624 struct vmk80xx_usb
*dev
= cdev
->private;
629 n
= rudimentary_check(dev
, DIR_IN
);
633 down(&dev
->limit_sem
);
634 chan
= CR_CHAN(insn
->chanspec
);
636 reg
= VMK8061_AO_REG
- 1;
638 dev
->usb_tx_buf
[0] = VMK8061_CMD_RD_AO
;
640 for (n
= 0; n
< insn
->n
; n
++) {
641 if (vmk80xx_read_packet(dev
))
644 data
[n
] = dev
->usb_rx_buf
[reg
+ chan
];
652 static int vmk80xx_di_bits(struct comedi_device
*cdev
,
653 struct comedi_subdevice
*s
,
654 struct comedi_insn
*insn
, unsigned int *data
)
656 struct vmk80xx_usb
*dev
= cdev
->private;
657 unsigned char *rx_buf
;
661 retval
= rudimentary_check(dev
, DIR_IN
);
665 down(&dev
->limit_sem
);
667 rx_buf
= dev
->usb_rx_buf
;
669 if (dev
->board
.model
== VMK8061_MODEL
) {
670 reg
= VMK8061_DI_REG
;
671 dev
->usb_tx_buf
[0] = VMK8061_CMD_RD_DI
;
673 reg
= VMK8055_DI_REG
;
676 retval
= vmk80xx_read_packet(dev
);
679 if (dev
->board
.model
== VMK8055_MODEL
)
680 data
[1] = (((rx_buf
[reg
] >> 4) & 0x03) |
681 ((rx_buf
[reg
] << 2) & 0x04) |
682 ((rx_buf
[reg
] >> 3) & 0x18));
684 data
[1] = rx_buf
[reg
];
694 static int vmk80xx_di_rinsn(struct comedi_device
*cdev
,
695 struct comedi_subdevice
*s
,
696 struct comedi_insn
*insn
, unsigned int *data
)
698 struct vmk80xx_usb
*dev
= cdev
->private;
700 unsigned char *rx_buf
;
705 n
= rudimentary_check(dev
, DIR_IN
);
709 down(&dev
->limit_sem
);
710 chan
= CR_CHAN(insn
->chanspec
);
712 rx_buf
= dev
->usb_rx_buf
;
714 if (dev
->board
.model
== VMK8061_MODEL
) {
715 reg
= VMK8061_DI_REG
;
716 dev
->usb_tx_buf
[0] = VMK8061_CMD_RD_DI
;
718 reg
= VMK8055_DI_REG
;
720 for (n
= 0; n
< insn
->n
; n
++) {
721 if (vmk80xx_read_packet(dev
))
724 if (dev
->board
.model
== VMK8055_MODEL
)
725 inp
= (((rx_buf
[reg
] >> 4) & 0x03) |
726 ((rx_buf
[reg
] << 2) & 0x04) |
727 ((rx_buf
[reg
] >> 3) & 0x18));
731 data
[n
] = (inp
>> chan
) & 1;
739 static int vmk80xx_do_winsn(struct comedi_device
*cdev
,
740 struct comedi_subdevice
*s
,
741 struct comedi_insn
*insn
, unsigned int *data
)
743 struct vmk80xx_usb
*dev
= cdev
->private;
745 unsigned char *tx_buf
;
750 n
= rudimentary_check(dev
, DIR_OUT
);
754 down(&dev
->limit_sem
);
755 chan
= CR_CHAN(insn
->chanspec
);
757 tx_buf
= dev
->usb_tx_buf
;
759 for (n
= 0; n
< insn
->n
; n
++) {
760 if (dev
->board
.model
== VMK8055_MODEL
) {
761 reg
= VMK8055_DO_REG
;
762 cmd
= VMK8055_CMD_WRT_AD
;
764 tx_buf
[reg
] |= (1 << chan
);
766 tx_buf
[reg
] ^= (1 << chan
);
767 } else { /* VMK8061_MODEL */
768 reg
= VMK8061_DO_REG
;
770 cmd
= VMK8061_CMD_SET_DO
;
771 tx_buf
[reg
] = 1 << chan
;
773 cmd
= VMK8061_CMD_CLR_DO
;
774 tx_buf
[reg
] = 0xff - (1 << chan
);
778 if (vmk80xx_write_packet(dev
, cmd
))
787 static int vmk80xx_do_rinsn(struct comedi_device
*cdev
,
788 struct comedi_subdevice
*s
,
789 struct comedi_insn
*insn
, unsigned int *data
)
791 struct vmk80xx_usb
*dev
= cdev
->private;
796 n
= rudimentary_check(dev
, DIR_IN
);
800 down(&dev
->limit_sem
);
801 chan
= CR_CHAN(insn
->chanspec
);
803 reg
= VMK8061_DO_REG
;
805 dev
->usb_tx_buf
[0] = VMK8061_CMD_RD_DO
;
807 for (n
= 0; n
< insn
->n
; n
++) {
808 if (vmk80xx_read_packet(dev
))
811 data
[n
] = (dev
->usb_rx_buf
[reg
] >> chan
) & 1;
819 static int vmk80xx_do_bits(struct comedi_device
*cdev
,
820 struct comedi_subdevice
*s
,
821 struct comedi_insn
*insn
, unsigned int *data
)
823 struct vmk80xx_usb
*dev
= cdev
->private;
824 unsigned char *rx_buf
, *tx_buf
;
833 if (dev
->board
.model
== VMK8061_MODEL
)
836 retval
= rudimentary_check(dev
, dir
);
840 down(&dev
->limit_sem
);
842 rx_buf
= dev
->usb_rx_buf
;
843 tx_buf
= dev
->usb_tx_buf
;
846 if (dev
->board
.model
== VMK8055_MODEL
) {
847 reg
= VMK8055_DO_REG
;
848 cmd
= VMK8055_CMD_WRT_AD
;
849 } else { /* VMK8061_MODEL */
850 reg
= VMK8061_DO_REG
;
851 cmd
= VMK8061_CMD_DO
;
854 tx_buf
[reg
] &= ~data
[0];
855 tx_buf
[reg
] |= (data
[0] & data
[1]);
857 retval
= vmk80xx_write_packet(dev
, cmd
);
863 if (dev
->board
.model
== VMK8061_MODEL
) {
864 reg
= VMK8061_DO_REG
;
865 tx_buf
[0] = VMK8061_CMD_RD_DO
;
867 retval
= vmk80xx_read_packet(dev
);
870 data
[1] = rx_buf
[reg
];
874 data
[1] = tx_buf
[reg
];
884 static int vmk80xx_cnt_rinsn(struct comedi_device
*cdev
,
885 struct comedi_subdevice
*s
,
886 struct comedi_insn
*insn
, unsigned int *data
)
888 struct vmk80xx_usb
*dev
= cdev
->private;
893 n
= rudimentary_check(dev
, DIR_IN
);
897 down(&dev
->limit_sem
);
898 chan
= CR_CHAN(insn
->chanspec
);
900 switch (dev
->board
.model
) {
903 reg
[0] = VMK8055_CNT1_REG
;
905 reg
[0] = VMK8055_CNT2_REG
;
909 reg
[0] = VMK8061_CNT_REG
;
910 reg
[1] = VMK8061_CNT_REG
;
911 dev
->usb_tx_buf
[0] = VMK8061_CMD_RD_CNT
;
915 for (n
= 0; n
< insn
->n
; n
++) {
916 if (vmk80xx_read_packet(dev
))
919 if (dev
->board
.model
== VMK8055_MODEL
)
920 data
[n
] = dev
->usb_rx_buf
[reg
[0]];
921 else /* VMK8061_MODEL */
922 data
[n
] = dev
->usb_rx_buf
[reg
[0] * (chan
+ 1) + 1]
923 + 256 * dev
->usb_rx_buf
[reg
[1] * 2 + 2];
931 static int vmk80xx_cnt_cinsn(struct comedi_device
*cdev
,
932 struct comedi_subdevice
*s
,
933 struct comedi_insn
*insn
, unsigned int *data
)
935 struct vmk80xx_usb
*dev
= cdev
->private;
936 unsigned int insn_cmd
;
942 n
= rudimentary_check(dev
, DIR_OUT
);
947 if (insn_cmd
!= INSN_CONFIG_RESET
&& insn_cmd
!= GPCT_RESET
)
950 down(&dev
->limit_sem
);
952 chan
= CR_CHAN(insn
->chanspec
);
954 if (dev
->board
.model
== VMK8055_MODEL
) {
956 cmd
= VMK8055_CMD_RST_CNT1
;
957 reg
= VMK8055_CNT1_REG
;
959 cmd
= VMK8055_CMD_RST_CNT2
;
960 reg
= VMK8055_CNT2_REG
;
963 dev
->usb_tx_buf
[reg
] = 0x00;
965 cmd
= VMK8061_CMD_RST_CNT
;
968 for (n
= 0; n
< insn
->n
; n
++)
969 if (vmk80xx_write_packet(dev
, cmd
))
977 static int vmk80xx_cnt_winsn(struct comedi_device
*cdev
,
978 struct comedi_subdevice
*s
,
979 struct comedi_insn
*insn
, unsigned int *data
)
981 struct vmk80xx_usb
*dev
= cdev
->private;
982 unsigned long debtime
;
988 n
= rudimentary_check(dev
, DIR_OUT
);
992 down(&dev
->limit_sem
);
993 chan
= CR_CHAN(insn
->chanspec
);
996 cmd
= VMK8055_CMD_DEB1_TIME
;
998 cmd
= VMK8055_CMD_DEB2_TIME
;
1000 for (n
= 0; n
< insn
->n
; n
++) {
1005 /* TODO: Prevent overflows */
1009 val
= int_sqrt(debtime
* 1000 / 115);
1010 if (((val
+ 1) * val
) < debtime
* 1000 / 115)
1013 dev
->usb_tx_buf
[6 + chan
] = val
;
1015 if (vmk80xx_write_packet(dev
, cmd
))
1019 up(&dev
->limit_sem
);
1024 static int vmk80xx_pwm_rinsn(struct comedi_device
*cdev
,
1025 struct comedi_subdevice
*s
,
1026 struct comedi_insn
*insn
, unsigned int *data
)
1028 struct vmk80xx_usb
*dev
= cdev
->private;
1032 n
= rudimentary_check(dev
, DIR_IN
);
1036 down(&dev
->limit_sem
);
1038 reg
[0] = VMK8061_PWM_REG1
;
1039 reg
[1] = VMK8061_PWM_REG2
;
1041 dev
->usb_tx_buf
[0] = VMK8061_CMD_RD_PWM
;
1043 for (n
= 0; n
< insn
->n
; n
++) {
1044 if (vmk80xx_read_packet(dev
))
1047 data
[n
] = dev
->usb_rx_buf
[reg
[0]] + 4 * dev
->usb_rx_buf
[reg
[1]];
1050 up(&dev
->limit_sem
);
1055 static int vmk80xx_pwm_winsn(struct comedi_device
*cdev
,
1056 struct comedi_subdevice
*s
,
1057 struct comedi_insn
*insn
, unsigned int *data
)
1059 struct vmk80xx_usb
*dev
= cdev
->private;
1060 unsigned char *tx_buf
;
1065 n
= rudimentary_check(dev
, DIR_OUT
);
1069 down(&dev
->limit_sem
);
1071 tx_buf
= dev
->usb_tx_buf
;
1073 reg
[0] = VMK8061_PWM_REG1
;
1074 reg
[1] = VMK8061_PWM_REG2
;
1076 cmd
= VMK8061_CMD_OUT_PWM
;
1079 * The followin piece of code was translated from the inline
1080 * assembler code in the DLL source code.
1083 * mov eax, k ; k is the value (data[n])
1084 * and al, 03h ; al are the lower 8 bits of eax
1085 * mov lo, al ; lo is the low part (tx_buf[reg[0]])
1087 * shr eax, 2 ; right shift eax register by 2
1088 * mov hi, al ; hi is the high part (tx_buf[reg[1]])
1091 for (n
= 0; n
< insn
->n
; n
++) {
1092 tx_buf
[reg
[0]] = (unsigned char)(data
[n
] & 0x03);
1093 tx_buf
[reg
[1]] = (unsigned char)(data
[n
] >> 2) & 0xff;
1095 if (vmk80xx_write_packet(dev
, cmd
))
1099 up(&dev
->limit_sem
);
1104 static int vmk80xx_attach_common(struct comedi_device
*cdev
,
1105 struct vmk80xx_usb
*dev
)
1108 struct comedi_subdevice
*s
;
1111 down(&dev
->limit_sem
);
1112 cdev
->board_name
= dev
->board
.name
;
1113 cdev
->private = dev
;
1114 if (dev
->board
.model
== VMK8055_MODEL
)
1118 ret
= comedi_alloc_subdevices(cdev
, n_subd
);
1120 up(&dev
->limit_sem
);
1123 /* Analog input subdevice */
1124 s
= &cdev
->subdevices
[VMK80XX_SUBD_AI
];
1125 s
->type
= COMEDI_SUBD_AI
;
1126 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
;
1127 s
->n_chan
= dev
->board
.ai_chans
;
1128 s
->maxdata
= (1 << dev
->board
.ai_bits
) - 1;
1129 s
->range_table
= dev
->board
.range
;
1130 s
->insn_read
= vmk80xx_ai_rinsn
;
1131 /* Analog output subdevice */
1132 s
= &cdev
->subdevices
[VMK80XX_SUBD_AO
];
1133 s
->type
= COMEDI_SUBD_AO
;
1134 s
->subdev_flags
= SDF_WRITEABLE
| SDF_GROUND
;
1135 s
->n_chan
= dev
->board
.ao_chans
;
1136 s
->maxdata
= (1 << dev
->board
.ao_bits
) - 1;
1137 s
->range_table
= dev
->board
.range
;
1138 s
->insn_write
= vmk80xx_ao_winsn
;
1139 if (dev
->board
.model
== VMK8061_MODEL
) {
1140 s
->subdev_flags
|= SDF_READABLE
;
1141 s
->insn_read
= vmk80xx_ao_rinsn
;
1143 /* Digital input subdevice */
1144 s
= &cdev
->subdevices
[VMK80XX_SUBD_DI
];
1145 s
->type
= COMEDI_SUBD_DI
;
1146 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
;
1147 s
->n_chan
= dev
->board
.di_chans
;
1149 s
->insn_read
= vmk80xx_di_rinsn
;
1150 s
->insn_bits
= vmk80xx_di_bits
;
1151 /* Digital output subdevice */
1152 s
= &cdev
->subdevices
[VMK80XX_SUBD_DO
];
1153 s
->type
= COMEDI_SUBD_DO
;
1154 s
->subdev_flags
= SDF_WRITEABLE
| SDF_GROUND
;
1155 s
->n_chan
= dev
->board
.do_chans
;
1157 s
->insn_write
= vmk80xx_do_winsn
;
1158 s
->insn_bits
= vmk80xx_do_bits
;
1159 if (dev
->board
.model
== VMK8061_MODEL
) {
1160 s
->subdev_flags
|= SDF_READABLE
;
1161 s
->insn_read
= vmk80xx_do_rinsn
;
1163 /* Counter subdevice */
1164 s
= &cdev
->subdevices
[VMK80XX_SUBD_CNT
];
1165 s
->type
= COMEDI_SUBD_COUNTER
;
1166 s
->subdev_flags
= SDF_READABLE
;
1167 s
->n_chan
= dev
->board
.cnt_chans
;
1168 s
->insn_read
= vmk80xx_cnt_rinsn
;
1169 s
->insn_config
= vmk80xx_cnt_cinsn
;
1170 if (dev
->board
.model
== VMK8055_MODEL
) {
1171 s
->subdev_flags
|= SDF_WRITEABLE
;
1172 s
->maxdata
= (1 << dev
->board
.cnt_bits
) - 1;
1173 s
->insn_write
= vmk80xx_cnt_winsn
;
1176 if (dev
->board
.model
== VMK8061_MODEL
) {
1177 s
= &cdev
->subdevices
[VMK80XX_SUBD_PWM
];
1178 s
->type
= COMEDI_SUBD_PWM
;
1179 s
->subdev_flags
= SDF_READABLE
| SDF_WRITEABLE
;
1180 s
->n_chan
= dev
->board
.pwm_chans
;
1181 s
->maxdata
= (1 << dev
->board
.pwm_bits
) - 1;
1182 s
->insn_read
= vmk80xx_pwm_rinsn
;
1183 s
->insn_write
= vmk80xx_pwm_winsn
;
1186 dev_info(cdev
->class_dev
, "vmk80xx: board #%d [%s] attached\n",
1187 dev
->count
, dev
->board
.name
);
1188 up(&dev
->limit_sem
);
1192 /* called for COMEDI_DEVCONFIG ioctl for board_name "vmk80xx" */
1193 static int vmk80xx_attach(struct comedi_device
*cdev
,
1194 struct comedi_devconfig
*it
)
1199 mutex_lock(&glb_mutex
);
1200 for (i
= 0; i
< VMK80XX_MAX_BOARDS
; i
++)
1201 if (vmb
[i
].probed
&& !vmb
[i
].attached
)
1203 if (i
== VMK80XX_MAX_BOARDS
)
1206 ret
= vmk80xx_attach_common(cdev
, &vmb
[i
]);
1207 mutex_unlock(&glb_mutex
);
1211 /* called via comedi_usb_auto_config() */
1212 static int vmk80xx_attach_usb(struct comedi_device
*cdev
,
1213 struct usb_interface
*intf
)
1218 mutex_lock(&glb_mutex
);
1219 for (i
= 0; i
< VMK80XX_MAX_BOARDS
; i
++)
1220 if (vmb
[i
].probed
&& vmb
[i
].intf
== intf
)
1222 if (i
== VMK80XX_MAX_BOARDS
)
1224 else if (vmb
[i
].attached
)
1227 ret
= vmk80xx_attach_common(cdev
, &vmb
[i
]);
1228 mutex_unlock(&glb_mutex
);
1232 static void vmk80xx_detach(struct comedi_device
*dev
)
1234 struct vmk80xx_usb
*usb
= dev
->private;
1237 down(&usb
->limit_sem
);
1238 dev
->private = NULL
;
1240 up(&usb
->limit_sem
);
1244 static struct comedi_driver vmk80xx_driver
= {
1245 .module
= THIS_MODULE
,
1246 .driver_name
= "vmk80xx",
1247 .attach
= vmk80xx_attach
,
1248 .detach
= vmk80xx_detach
,
1249 .attach_usb
= vmk80xx_attach_usb
,
1252 static int vmk80xx_usb_probe(struct usb_interface
*intf
,
1253 const struct usb_device_id
*id
)
1256 struct vmk80xx_usb
*dev
;
1257 struct usb_host_interface
*iface_desc
;
1258 struct usb_endpoint_descriptor
*ep_desc
;
1261 mutex_lock(&glb_mutex
);
1263 for (i
= 0; i
< VMK80XX_MAX_BOARDS
; i
++)
1267 if (i
== VMK80XX_MAX_BOARDS
) {
1268 mutex_unlock(&glb_mutex
);
1274 memset(dev
, 0x00, sizeof(struct vmk80xx_usb
));
1277 iface_desc
= intf
->cur_altsetting
;
1278 if (iface_desc
->desc
.bNumEndpoints
!= 2)
1281 for (i
= 0; i
< iface_desc
->desc
.bNumEndpoints
; i
++) {
1282 ep_desc
= &iface_desc
->endpoint
[i
].desc
;
1284 if (usb_endpoint_is_int_in(ep_desc
)) {
1285 dev
->ep_rx
= ep_desc
;
1289 if (usb_endpoint_is_int_out(ep_desc
)) {
1290 dev
->ep_tx
= ep_desc
;
1294 if (usb_endpoint_is_bulk_in(ep_desc
)) {
1295 dev
->ep_rx
= ep_desc
;
1299 if (usb_endpoint_is_bulk_out(ep_desc
)) {
1300 dev
->ep_tx
= ep_desc
;
1305 if (!dev
->ep_rx
|| !dev
->ep_tx
)
1308 size
= le16_to_cpu(dev
->ep_rx
->wMaxPacketSize
);
1309 dev
->usb_rx_buf
= kmalloc(size
, GFP_KERNEL
);
1310 if (!dev
->usb_rx_buf
) {
1311 mutex_unlock(&glb_mutex
);
1315 size
= le16_to_cpu(dev
->ep_tx
->wMaxPacketSize
);
1316 dev
->usb_tx_buf
= kmalloc(size
, GFP_KERNEL
);
1317 if (!dev
->usb_tx_buf
) {
1318 kfree(dev
->usb_rx_buf
);
1319 mutex_unlock(&glb_mutex
);
1323 dev
->udev
= interface_to_usbdev(intf
);
1326 sema_init(&dev
->limit_sem
, 8);
1327 init_waitqueue_head(&dev
->read_wait
);
1328 init_waitqueue_head(&dev
->write_wait
);
1330 init_usb_anchor(&dev
->rx_anchor
);
1331 init_usb_anchor(&dev
->tx_anchor
);
1333 usb_set_intfdata(intf
, dev
);
1335 switch (id
->driver_info
) {
1336 case DEVICE_VMK8055
:
1337 dev
->board
.name
= "K8055 (VM110)";
1338 dev
->board
.model
= VMK8055_MODEL
;
1339 dev
->board
.range
= &vmk8055_range
;
1340 dev
->board
.ai_chans
= 2;
1341 dev
->board
.ai_bits
= 8;
1342 dev
->board
.ao_chans
= 2;
1343 dev
->board
.ao_bits
= 8;
1344 dev
->board
.di_chans
= 5;
1345 dev
->board
.di_bits
= 1;
1346 dev
->board
.do_chans
= 8;
1347 dev
->board
.do_bits
= 1;
1348 dev
->board
.cnt_chans
= 2;
1349 dev
->board
.cnt_bits
= 16;
1350 dev
->board
.pwm_chans
= 0;
1351 dev
->board
.pwm_bits
= 0;
1353 case DEVICE_VMK8061
:
1354 dev
->board
.name
= "K8061 (VM140)";
1355 dev
->board
.model
= VMK8061_MODEL
;
1356 dev
->board
.range
= &vmk8061_range
;
1357 dev
->board
.ai_chans
= 8;
1358 dev
->board
.ai_bits
= 10;
1359 dev
->board
.ao_chans
= 8;
1360 dev
->board
.ao_bits
= 8;
1361 dev
->board
.di_chans
= 8;
1362 dev
->board
.di_bits
= 1;
1363 dev
->board
.do_chans
= 8;
1364 dev
->board
.do_bits
= 1;
1365 dev
->board
.cnt_chans
= 2;
1366 dev
->board
.cnt_bits
= 0;
1367 dev
->board
.pwm_chans
= 1;
1368 dev
->board
.pwm_bits
= 10;
1372 if (dev
->board
.model
== VMK8061_MODEL
) {
1373 vmk80xx_read_eeprom(dev
, IC3_VERSION
);
1374 printk(KERN_INFO
"comedi#: vmk80xx: %s\n", dev
->fw
.ic3_vers
);
1376 if (vmk80xx_check_data_link(dev
)) {
1377 vmk80xx_read_eeprom(dev
, IC6_VERSION
);
1378 printk(KERN_INFO
"comedi#: vmk80xx: %s\n",
1381 dbgcm("comedi#: vmk80xx: no conn. to CPU\n");
1385 if (dev
->board
.model
== VMK8055_MODEL
)
1386 vmk80xx_reset_device(dev
);
1390 printk(KERN_INFO
"comedi#: vmk80xx: board #%d [%s] now attached\n",
1391 dev
->count
, dev
->board
.name
);
1393 mutex_unlock(&glb_mutex
);
1395 comedi_usb_auto_config(intf
, &vmk80xx_driver
);
1399 mutex_unlock(&glb_mutex
);
1404 static void vmk80xx_usb_disconnect(struct usb_interface
*intf
)
1406 struct vmk80xx_usb
*dev
= usb_get_intfdata(intf
);
1411 comedi_usb_auto_unconfig(intf
);
1413 mutex_lock(&glb_mutex
);
1414 down(&dev
->limit_sem
);
1417 usb_set_intfdata(dev
->intf
, NULL
);
1419 usb_kill_anchored_urbs(&dev
->rx_anchor
);
1420 usb_kill_anchored_urbs(&dev
->tx_anchor
);
1422 kfree(dev
->usb_rx_buf
);
1423 kfree(dev
->usb_tx_buf
);
1425 printk(KERN_INFO
"comedi#: vmk80xx: board #%d [%s] now detached\n",
1426 dev
->count
, dev
->board
.name
);
1428 up(&dev
->limit_sem
);
1429 mutex_unlock(&glb_mutex
);
1432 static const struct usb_device_id vmk80xx_usb_id_table
[] = {
1433 { USB_DEVICE(0x10cf, 0x5500), .driver_info
= DEVICE_VMK8055
},
1434 { USB_DEVICE(0x10cf, 0x5501), .driver_info
= DEVICE_VMK8055
},
1435 { USB_DEVICE(0x10cf, 0x5502), .driver_info
= DEVICE_VMK8055
},
1436 { USB_DEVICE(0x10cf, 0x5503), .driver_info
= DEVICE_VMK8055
},
1437 { USB_DEVICE(0x10cf, 0x8061), .driver_info
= DEVICE_VMK8061
},
1438 { USB_DEVICE(0x10cf, 0x8062), .driver_info
= DEVICE_VMK8061
},
1439 { USB_DEVICE(0x10cf, 0x8063), .driver_info
= DEVICE_VMK8061
},
1440 { USB_DEVICE(0x10cf, 0x8064), .driver_info
= DEVICE_VMK8061
},
1441 { USB_DEVICE(0x10cf, 0x8065), .driver_info
= DEVICE_VMK8061
},
1442 { USB_DEVICE(0x10cf, 0x8066), .driver_info
= DEVICE_VMK8061
},
1443 { USB_DEVICE(0x10cf, 0x8067), .driver_info
= DEVICE_VMK8061
},
1444 { USB_DEVICE(0x10cf, 0x8068), .driver_info
= DEVICE_VMK8061
},
1447 MODULE_DEVICE_TABLE(usb
, vmk80xx_usb_id_table
);
1449 /* TODO: Add support for suspend, resume, pre_reset,
1450 * post_reset and flush */
1451 static struct usb_driver vmk80xx_usb_driver
= {
1453 .probe
= vmk80xx_usb_probe
,
1454 .disconnect
= vmk80xx_usb_disconnect
,
1455 .id_table
= vmk80xx_usb_id_table
,
1457 module_comedi_usb_driver(vmk80xx_driver
, vmk80xx_usb_driver
);
1459 MODULE_AUTHOR("Manuel Gebele <forensixs@gmx.de>");
1460 MODULE_DESCRIPTION("Velleman USB Board Low-Level Driver");
1461 MODULE_SUPPORTED_DEVICE("K8055/K8061 aka VM110/VM140");
1462 MODULE_VERSION("0.8.01");
1463 MODULE_LICENSE("GPL");