3 * Copyright (C) 2003-2014 Bernd Porr, mail@berndporr.me.uk
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
18 * Description: University of Stirling USB DAQ & INCITE Technology Limited
19 * Devices: [ITL] USB-DUX (usbdux)
20 * Author: Bernd Porr <mail@berndporr.me.uk>
21 * Updated: 10 Oct 2014
24 * Connection scheme for the counter at the digital port:
25 * 0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1.
26 * The sampling rate of the counter is approximately 500Hz.
28 * Note that under USB2.0 the length of the channel list determines
29 * the max sampling rate. If you sample only one channel you get 8kHz
30 * sampling rate. If you sample two channels you get 4kHz and so on.
34 * I must give credit here to Chris Baugher who
35 * wrote the driver for AT-MIO-16d. I used some parts of this
36 * driver. I also must give credits to David Brownell
37 * who supported me with the USB development.
43 * 0.94: D/A output should work now with any channel list combinations
44 * 0.95: .owner commented out for kernel vers below 2.4.19
45 * sanity checks in ai/ao_cmd
46 * 0.96: trying to get it working with 2.6, moved all memory alloc to comedi's
47 * attach final USB IDs
48 * moved memory allocation completely to the corresponding comedi
49 * functions firmware upload is by fxload and no longer by comedi (due to
51 * 0.97: USB IDs received, adjusted table
52 * 0.98: SMP, locking, memory alloc: moved all usb memory alloc
53 * to the usb subsystem and moved all comedi related memory
55 * | kernel | registration | usbdux-usb | usbdux-comedi | comedi |
56 * 0.99: USB 2.0: changed protocol to isochronous transfer
57 * IRQ transfer is too buggy and too risky in 2.0
58 * for the high speed ISO transfer is now a working version
60 * 0.99b: Increased the iso transfer buffer for high sp.to 10 buffers. Some VIA
61 * chipsets miss out IRQs. Deeper buffering is needed.
62 * 1.00: full USB 2.0 support for the A/D converter. Now: max 8kHz sampling
64 * Firmware vers 1.00 is needed for this.
65 * Two 16 bit up/down/reset counter with a sampling rate of 1kHz
66 * And loads of cleaning up, in particular streamlining the
68 * 1.1: moved EP4 transfers to EP1 to make space for a PWM output on EP4
69 * 1.2: added PWM support via EP4
70 * 2.0: PWM seems to be stable and is not interfering with the other functions
71 * 2.1: changed PWM API
72 * 2.2: added firmware kernel request to fix an udev problem
73 * 2.3: corrected a bug in bulk timeouts which were far too short
74 * 2.4: fixed a bug which causes the driver to hang when it ran out of data.
75 * Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it.
79 #include <linux/kernel.h>
80 #include <linux/module.h>
81 #include <linux/slab.h>
82 #include <linux/input.h>
83 #include <linux/fcntl.h>
84 #include <linux/compiler.h>
86 #include "../comedi_usb.h"
88 #include "comedi_fc.h"
90 /* constants for firmware upload and download */
91 #define USBDUX_FIRMWARE "usbdux_firmware.bin"
92 #define USBDUX_FIRMWARE_MAX_LEN 0x2000
93 #define USBDUX_FIRMWARE_CMD 0xa0
94 #define VENDOR_DIR_IN 0xc0
95 #define VENDOR_DIR_OUT 0x40
96 #define USBDUX_CPU_CS 0xe600
98 /* usbdux bulk transfer commands */
99 #define USBDUX_CMD_MULT_AI 0
100 #define USBDUX_CMD_AO 1
101 #define USBDUX_CMD_DIO_CFG 2
102 #define USBDUX_CMD_DIO_BITS 3
103 #define USBDUX_CMD_SINGLE_AI 4
104 #define USBDUX_CMD_TIMER_RD 5
105 #define USBDUX_CMD_TIMER_WR 6
106 #define USBDUX_CMD_PWM_ON 7
107 #define USBDUX_CMD_PWM_OFF 8
109 /* timeout for the USB-transfer in ms */
110 #define BULK_TIMEOUT 1000
112 /* 300Hz max frequ under PWM */
113 #define MIN_PWM_PERIOD ((long)(1E9/300))
115 /* Default PWM frequency */
116 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
118 /* Size of one A/D value */
119 #define SIZEADIN ((sizeof(uint16_t)))
122 * Size of the input-buffer IN BYTES
123 * Always multiple of 8 for 8 microframes which is needed in the highspeed mode
125 #define SIZEINBUF ((8*SIZEADIN))
128 #define SIZEINSNBUF 16
130 /* size of one value for the D/A converter: channel and value */
131 #define SIZEDAOUT ((sizeof(uint8_t)+sizeof(uint16_t)))
134 * Size of the output-buffer in bytes
135 * Actually only the first 4 triplets are used but for the
136 * high speed mode we need to pad it to 8 (microframes).
138 #define SIZEOUTBUF ((8*SIZEDAOUT))
141 * Size of the buffer for the dux commands: just now max size is determined
142 * by the analogue out + command byte + panic bytes...
144 #define SIZEOFDUXBUFFER ((8*SIZEDAOUT+2))
146 /* Number of in-URBs which receive the data: min=2 */
147 #define NUMOFINBUFFERSFULL 5
149 /* Number of out-URBs which send the data: min=2 */
150 #define NUMOFOUTBUFFERSFULL 5
152 /* Number of in-URBs which receive the data: min=5 */
153 /* must have more buffers due to buggy USB ctr */
154 #define NUMOFINBUFFERSHIGH 10
156 /* Number of out-URBs which send the data: min=5 */
157 /* must have more buffers due to buggy USB ctr */
158 #define NUMOFOUTBUFFERSHIGH 10
160 /* number of retries to get the right dux command */
163 static const struct comedi_lrange range_usbdux_ai_range
= {
166 BIP_RANGE(4.096 / 2),
172 static const struct comedi_lrange range_usbdux_ao_range
= {
179 struct usbdux_private
{
180 /* actual number of in-buffers */
182 /* actual number of out-buffers */
184 /* ISO-transfer handling: buffers */
185 struct urb
**ai_urbs
;
186 struct urb
**ao_urbs
;
187 /* pwm-transfer handling */
190 unsigned int pwm_period
;
191 /* PWM internal delay for the GPIF in the FX2 */
193 /* size of the PWM buffer which holds the bit pattern */
195 /* input buffer for the ISO-transfer */
197 /* input buffer for single insn */
200 unsigned int high_speed
:1;
201 unsigned int ai_cmd_running
:1;
202 unsigned int ao_cmd_running
:1;
203 unsigned int pwm_cmd_running
:1;
205 /* time between samples in units of the timer */
206 unsigned int ai_timer
;
207 unsigned int ao_timer
;
208 /* counter between aquisitions */
209 unsigned int ai_counter
;
210 unsigned int ao_counter
;
211 /* interval in frames/uframes */
212 unsigned int ai_interval
;
214 uint8_t *dux_commands
;
215 struct semaphore sem
;
218 static void usbdux_unlink_urbs(struct urb
**urbs
, int num_urbs
)
222 for (i
= 0; i
< num_urbs
; i
++)
223 usb_kill_urb(urbs
[i
]);
226 static void usbdux_ai_stop(struct comedi_device
*dev
, int do_unlink
)
228 struct usbdux_private
*devpriv
= dev
->private;
230 if (do_unlink
&& devpriv
->ai_urbs
)
231 usbdux_unlink_urbs(devpriv
->ai_urbs
, devpriv
->n_ai_urbs
);
233 devpriv
->ai_cmd_running
= 0;
236 static int usbdux_ai_cancel(struct comedi_device
*dev
,
237 struct comedi_subdevice
*s
)
239 struct usbdux_private
*devpriv
= dev
->private;
241 /* prevent other CPUs from submitting new commands just now */
243 /* unlink only if the urb really has been submitted */
244 usbdux_ai_stop(dev
, devpriv
->ai_cmd_running
);
250 static void usbduxsub_ai_handle_urb(struct comedi_device
*dev
,
251 struct comedi_subdevice
*s
,
254 struct usbdux_private
*devpriv
= dev
->private;
255 struct comedi_async
*async
= s
->async
;
256 struct comedi_cmd
*cmd
= &async
->cmd
;
260 devpriv
->ai_counter
--;
261 if (devpriv
->ai_counter
== 0) {
262 devpriv
->ai_counter
= devpriv
->ai_timer
;
264 /* get the data from the USB bus and hand it over to comedi */
265 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
266 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
267 uint16_t val
= le16_to_cpu(devpriv
->in_buf
[i
]);
269 /* bipolar data is two's-complement */
270 if (comedi_range_is_bipolar(s
, range
))
271 val
^= ((s
->maxdata
+ 1) >> 1);
274 if (!comedi_buf_write_samples(s
, &val
, 1))
278 if (cmd
->stop_src
== TRIG_COUNT
&&
279 async
->scans_done
>= cmd
->stop_arg
)
280 async
->events
|= COMEDI_CB_EOA
;
283 /* if command is still running, resubmit urb */
284 if (!(async
->events
& COMEDI_CB_CANCEL_MASK
)) {
285 urb
->dev
= comedi_to_usb_dev(dev
);
286 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
288 dev_err(dev
->class_dev
,
289 "urb resubmit failed in int-context! err=%d\n",
291 if (ret
== -EL2NSYNC
)
292 dev_err(dev
->class_dev
,
293 "buggy USB host controller or bug in IRQ handler!\n");
294 async
->events
|= COMEDI_CB_ERROR
;
299 static void usbduxsub_ai_isoc_irq(struct urb
*urb
)
301 struct comedi_device
*dev
= urb
->context
;
302 struct comedi_subdevice
*s
= dev
->read_subdev
;
303 struct comedi_async
*async
= s
->async
;
304 struct usbdux_private
*devpriv
= dev
->private;
306 /* exit if not running a command, do not resubmit urb */
307 if (!devpriv
->ai_cmd_running
)
310 switch (urb
->status
) {
312 /* copy the result in the transfer buffer */
313 memcpy(devpriv
->in_buf
, urb
->transfer_buffer
, SIZEINBUF
);
314 usbduxsub_ai_handle_urb(dev
, s
, urb
);
319 * error in the ISOchronous data
320 * we don't copy the data into the transfer buffer
321 * and recycle the last data byte
323 dev_dbg(dev
->class_dev
, "CRC error in ISO IN stream\n");
324 usbduxsub_ai_handle_urb(dev
, s
, urb
);
331 /* after an unlink command, unplug, ... etc */
332 async
->events
|= COMEDI_CB_ERROR
;
337 dev_err(dev
->class_dev
,
338 "Non-zero urb status received in ai intr context: %d\n",
340 async
->events
|= COMEDI_CB_ERROR
;
345 * comedi_handle_events() cannot be used in this driver. The (*cancel)
346 * operation would unlink the urb.
348 if (async
->events
& COMEDI_CB_CANCEL_MASK
)
349 usbdux_ai_stop(dev
, 0);
351 comedi_event(dev
, s
);
354 static void usbdux_ao_stop(struct comedi_device
*dev
, int do_unlink
)
356 struct usbdux_private
*devpriv
= dev
->private;
358 if (do_unlink
&& devpriv
->ao_urbs
)
359 usbdux_unlink_urbs(devpriv
->ao_urbs
, devpriv
->n_ao_urbs
);
361 devpriv
->ao_cmd_running
= 0;
364 static int usbdux_ao_cancel(struct comedi_device
*dev
,
365 struct comedi_subdevice
*s
)
367 struct usbdux_private
*devpriv
= dev
->private;
369 /* prevent other CPUs from submitting a command just now */
371 /* unlink only if it is really running */
372 usbdux_ao_stop(dev
, devpriv
->ao_cmd_running
);
378 static void usbduxsub_ao_handle_urb(struct comedi_device
*dev
,
379 struct comedi_subdevice
*s
,
382 struct usbdux_private
*devpriv
= dev
->private;
383 struct comedi_async
*async
= s
->async
;
384 struct comedi_cmd
*cmd
= &async
->cmd
;
389 devpriv
->ao_counter
--;
390 if (devpriv
->ao_counter
== 0) {
391 devpriv
->ao_counter
= devpriv
->ao_timer
;
393 if (cmd
->stop_src
== TRIG_COUNT
&&
394 async
->scans_done
>= cmd
->stop_arg
) {
395 async
->events
|= COMEDI_CB_EOA
;
399 /* transmit data to the USB bus */
400 datap
= urb
->transfer_buffer
;
401 *datap
++ = cmd
->chanlist_len
;
402 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
403 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
406 if (!comedi_buf_read_samples(s
, &val
, 1)) {
407 dev_err(dev
->class_dev
, "buffer underflow\n");
408 async
->events
|= COMEDI_CB_OVERFLOW
;
412 /* pointer to the DA */
413 *datap
++ = val
& 0xff;
414 *datap
++ = (val
>> 8) & 0xff;
415 *datap
++ = chan
<< 6;
416 s
->readback
[chan
] = val
;
420 /* if command is still running, resubmit urb for BULK transfer */
421 if (!(async
->events
& COMEDI_CB_CANCEL_MASK
)) {
422 urb
->transfer_buffer_length
= SIZEOUTBUF
;
423 urb
->dev
= comedi_to_usb_dev(dev
);
425 if (devpriv
->high_speed
)
426 urb
->interval
= 8; /* uframes */
428 urb
->interval
= 1; /* frames */
429 urb
->number_of_packets
= 1;
430 urb
->iso_frame_desc
[0].offset
= 0;
431 urb
->iso_frame_desc
[0].length
= SIZEOUTBUF
;
432 urb
->iso_frame_desc
[0].status
= 0;
433 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
435 dev_err(dev
->class_dev
,
436 "ao urb resubm failed in int-cont. ret=%d",
438 if (ret
== -EL2NSYNC
)
439 dev_err(dev
->class_dev
,
440 "buggy USB host controller or bug in IRQ handling!\n");
441 async
->events
|= COMEDI_CB_ERROR
;
446 static void usbduxsub_ao_isoc_irq(struct urb
*urb
)
448 struct comedi_device
*dev
= urb
->context
;
449 struct comedi_subdevice
*s
= dev
->write_subdev
;
450 struct comedi_async
*async
= s
->async
;
451 struct usbdux_private
*devpriv
= dev
->private;
453 /* exit if not running a command, do not resubmit urb */
454 if (!devpriv
->ao_cmd_running
)
457 switch (urb
->status
) {
459 usbduxsub_ao_handle_urb(dev
, s
, urb
);
466 /* after an unlink command, unplug, ... etc */
467 async
->events
|= COMEDI_CB_ERROR
;
472 dev_err(dev
->class_dev
,
473 "Non-zero urb status received in ao intr context: %d\n",
475 async
->events
|= COMEDI_CB_ERROR
;
480 * comedi_handle_events() cannot be used in this driver. The (*cancel)
481 * operation would unlink the urb.
483 if (async
->events
& COMEDI_CB_CANCEL_MASK
)
484 usbdux_ao_stop(dev
, 0);
486 comedi_event(dev
, s
);
489 static int usbdux_submit_urbs(struct comedi_device
*dev
,
490 struct urb
**urbs
, int num_urbs
,
493 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
494 struct usbdux_private
*devpriv
= dev
->private;
499 /* Submit all URBs and start the transfer on the bus */
500 for (i
= 0; i
< num_urbs
; i
++) {
503 /* in case of a resubmission after an unlink... */
505 urb
->interval
= devpriv
->ai_interval
;
509 urb
->transfer_flags
= URB_ISO_ASAP
;
511 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
518 static int usbdux_ai_cmdtest(struct comedi_device
*dev
,
519 struct comedi_subdevice
*s
, struct comedi_cmd
*cmd
)
521 struct usbdux_private
*this_usbduxsub
= dev
->private;
523 unsigned int tmp_timer
;
525 /* Step 1 : check if triggers are trivially valid */
527 err
|= cfc_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_INT
);
528 err
|= cfc_check_trigger_src(&cmd
->scan_begin_src
, TRIG_TIMER
);
529 err
|= cfc_check_trigger_src(&cmd
->convert_src
, TRIG_NOW
);
530 err
|= cfc_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
531 err
|= cfc_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
536 /* Step 2a : make sure trigger sources are unique */
538 err
|= cfc_check_trigger_is_unique(cmd
->start_src
);
539 err
|= cfc_check_trigger_is_unique(cmd
->stop_src
);
541 /* Step 2b : and mutually compatible */
546 /* Step 3: check if arguments are trivially valid */
548 err
|= cfc_check_trigger_arg_is(&cmd
->start_arg
, 0);
550 if (cmd
->scan_begin_src
== TRIG_FOLLOW
) /* internal trigger */
551 err
|= cfc_check_trigger_arg_is(&cmd
->scan_begin_arg
, 0);
553 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
554 if (this_usbduxsub
->high_speed
) {
556 * In high speed mode microframes are possible.
557 * However, during one microframe we can roughly
558 * sample one channel. Thus, the more channels
559 * are in the channel list the more time we need.
562 /* find a power of 2 for the number of channels */
563 while (i
< (cmd
->chanlist_len
))
566 err
|= cfc_check_trigger_arg_min(&cmd
->scan_begin_arg
,
568 /* now calc the real sampling rate with all the
571 ((unsigned int)(cmd
->scan_begin_arg
/ 125000)) *
575 /* 1kHz scans every USB frame */
576 err
|= cfc_check_trigger_arg_min(&cmd
->scan_begin_arg
,
579 * calc the real sampling rate with the rounding errors
581 tmp_timer
= ((unsigned int)(cmd
->scan_begin_arg
/
584 err
|= cfc_check_trigger_arg_is(&cmd
->scan_begin_arg
,
588 err
|= cfc_check_trigger_arg_is(&cmd
->scan_end_arg
, cmd
->chanlist_len
);
590 if (cmd
->stop_src
== TRIG_COUNT
)
591 err
|= cfc_check_trigger_arg_min(&cmd
->stop_arg
, 1);
593 err
|= cfc_check_trigger_arg_is(&cmd
->stop_arg
, 0);
602 * creates the ADC command for the MAX1271
603 * range is the range value from comedi
605 static uint8_t create_adc_command(unsigned int chan
, unsigned int range
)
607 uint8_t p
= (range
<= 1);
608 uint8_t r
= ((range
% 2) == 0);
610 return (chan
<< 4) | ((p
== 1) << 2) | ((r
== 1) << 3);
613 static int send_dux_commands(struct comedi_device
*dev
, unsigned int cmd_type
)
615 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
616 struct usbdux_private
*devpriv
= dev
->private;
619 devpriv
->dux_commands
[0] = cmd_type
;
621 return usb_bulk_msg(usb
, usb_sndbulkpipe(usb
, 1),
622 devpriv
->dux_commands
, SIZEOFDUXBUFFER
,
623 &nsent
, BULK_TIMEOUT
);
626 static int receive_dux_commands(struct comedi_device
*dev
, unsigned int command
)
628 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
629 struct usbdux_private
*devpriv
= dev
->private;
634 for (i
= 0; i
< RETRIES
; i
++) {
635 ret
= usb_bulk_msg(usb
, usb_rcvbulkpipe(usb
, 8),
636 devpriv
->insn_buf
, SIZEINSNBUF
,
637 &nrec
, BULK_TIMEOUT
);
640 if (le16_to_cpu(devpriv
->insn_buf
[0]) == command
)
643 /* command not received */
647 static int usbdux_ai_inttrig(struct comedi_device
*dev
,
648 struct comedi_subdevice
*s
,
649 unsigned int trig_num
)
651 struct usbdux_private
*devpriv
= dev
->private;
652 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
655 if (trig_num
!= cmd
->start_arg
)
660 if (!devpriv
->ai_cmd_running
) {
661 devpriv
->ai_cmd_running
= 1;
662 ret
= usbdux_submit_urbs(dev
, devpriv
->ai_urbs
,
663 devpriv
->n_ai_urbs
, 1);
665 devpriv
->ai_cmd_running
= 0;
668 s
->async
->inttrig
= NULL
;
678 static int usbdux_ai_cmd(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
680 struct usbdux_private
*devpriv
= dev
->private;
681 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
682 int len
= cmd
->chanlist_len
;
686 /* block other CPUs from starting an ai_cmd */
689 if (devpriv
->ai_cmd_running
)
692 devpriv
->dux_commands
[1] = len
;
693 for (i
= 0; i
< len
; ++i
) {
694 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
695 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
697 devpriv
->dux_commands
[i
+ 2] = create_adc_command(chan
, range
);
700 ret
= send_dux_commands(dev
, USBDUX_CMD_MULT_AI
);
704 if (devpriv
->high_speed
) {
706 * every channel gets a time window of 125us. Thus, if we
707 * sample all 8 channels we need 1ms. If we sample only one
708 * channel we need only 125us
710 devpriv
->ai_interval
= 1;
711 /* find a power of 2 for the interval */
712 while (devpriv
->ai_interval
< len
)
713 devpriv
->ai_interval
*= 2;
715 devpriv
->ai_timer
= cmd
->scan_begin_arg
/
716 (125000 * devpriv
->ai_interval
);
718 /* interval always 1ms */
719 devpriv
->ai_interval
= 1;
720 devpriv
->ai_timer
= cmd
->scan_begin_arg
/ 1000000;
722 if (devpriv
->ai_timer
< 1) {
727 devpriv
->ai_counter
= devpriv
->ai_timer
;
729 if (cmd
->start_src
== TRIG_NOW
) {
730 /* enable this acquisition operation */
731 devpriv
->ai_cmd_running
= 1;
732 ret
= usbdux_submit_urbs(dev
, devpriv
->ai_urbs
,
733 devpriv
->n_ai_urbs
, 1);
735 devpriv
->ai_cmd_running
= 0;
736 /* fixme: unlink here?? */
739 s
->async
->inttrig
= NULL
;
742 /* don't enable the acquision operation */
743 /* wait for an internal signal */
744 s
->async
->inttrig
= usbdux_ai_inttrig
;
753 /* Mode 0 is used to get a single conversion on demand */
754 static int usbdux_ai_insn_read(struct comedi_device
*dev
,
755 struct comedi_subdevice
*s
,
756 struct comedi_insn
*insn
,
759 struct usbdux_private
*devpriv
= dev
->private;
760 unsigned int chan
= CR_CHAN(insn
->chanspec
);
761 unsigned int range
= CR_RANGE(insn
->chanspec
);
768 if (devpriv
->ai_cmd_running
)
771 /* set command for the first channel */
772 devpriv
->dux_commands
[1] = create_adc_command(chan
, range
);
775 ret
= send_dux_commands(dev
, USBDUX_CMD_SINGLE_AI
);
779 for (i
= 0; i
< insn
->n
; i
++) {
780 ret
= receive_dux_commands(dev
, USBDUX_CMD_SINGLE_AI
);
784 val
= le16_to_cpu(devpriv
->insn_buf
[1]);
786 /* bipolar data is two's-complement */
787 if (comedi_range_is_bipolar(s
, range
))
788 val
^= ((s
->maxdata
+ 1) >> 1);
796 return ret
? ret
: insn
->n
;
799 static int usbdux_ao_insn_read(struct comedi_device
*dev
,
800 struct comedi_subdevice
*s
,
801 struct comedi_insn
*insn
,
804 struct usbdux_private
*devpriv
= dev
->private;
808 ret
= comedi_readback_insn_read(dev
, s
, insn
, data
);
814 static int usbdux_ao_insn_write(struct comedi_device
*dev
,
815 struct comedi_subdevice
*s
,
816 struct comedi_insn
*insn
,
819 struct usbdux_private
*devpriv
= dev
->private;
820 unsigned int chan
= CR_CHAN(insn
->chanspec
);
821 unsigned int val
= s
->readback
[chan
];
822 __le16
*p
= (__le16
*)&devpriv
->dux_commands
[2];
828 if (devpriv
->ao_cmd_running
)
831 /* number of channels: 1 */
832 devpriv
->dux_commands
[1] = 1;
834 devpriv
->dux_commands
[4] = chan
<< 6;
836 for (i
= 0; i
< insn
->n
; i
++) {
839 /* one 16 bit value */
840 *p
= cpu_to_le16(val
);
842 ret
= send_dux_commands(dev
, USBDUX_CMD_AO
);
846 s
->readback
[chan
] = val
;
852 return ret
? ret
: insn
->n
;
855 static int usbdux_ao_inttrig(struct comedi_device
*dev
,
856 struct comedi_subdevice
*s
,
857 unsigned int trig_num
)
859 struct usbdux_private
*devpriv
= dev
->private;
860 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
863 if (trig_num
!= cmd
->start_arg
)
868 if (!devpriv
->ao_cmd_running
) {
869 devpriv
->ao_cmd_running
= 1;
870 ret
= usbdux_submit_urbs(dev
, devpriv
->ao_urbs
,
871 devpriv
->n_ao_urbs
, 0);
873 devpriv
->ao_cmd_running
= 0;
876 s
->async
->inttrig
= NULL
;
886 static int usbdux_ao_cmdtest(struct comedi_device
*dev
,
887 struct comedi_subdevice
*s
, struct comedi_cmd
*cmd
)
889 struct usbdux_private
*this_usbduxsub
= dev
->private;
896 /* Step 1 : check if triggers are trivially valid */
898 err
|= cfc_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_INT
);
900 if (0) { /* (this_usbduxsub->high_speed) */
901 /* the sampling rate is set by the coversion rate */
904 /* start a new scan (output at once) with a timer */
907 err
|= cfc_check_trigger_src(&cmd
->scan_begin_src
, flags
);
909 if (0) { /* (this_usbduxsub->high_speed) */
911 * in usb-2.0 only one conversion it transmitted
917 * all conversion events happen simultaneously with
922 err
|= cfc_check_trigger_src(&cmd
->convert_src
, flags
);
924 err
|= cfc_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
925 err
|= cfc_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
930 /* Step 2a : make sure trigger sources are unique */
932 err
|= cfc_check_trigger_is_unique(cmd
->start_src
);
933 err
|= cfc_check_trigger_is_unique(cmd
->stop_src
);
935 /* Step 2b : and mutually compatible */
940 /* Step 3: check if arguments are trivially valid */
942 err
|= cfc_check_trigger_arg_is(&cmd
->start_arg
, 0);
944 if (cmd
->scan_begin_src
== TRIG_FOLLOW
) /* internal trigger */
945 err
|= cfc_check_trigger_arg_is(&cmd
->scan_begin_arg
, 0);
947 if (cmd
->scan_begin_src
== TRIG_TIMER
)
948 err
|= cfc_check_trigger_arg_min(&cmd
->scan_begin_arg
,
951 /* not used now, is for later use */
952 if (cmd
->convert_src
== TRIG_TIMER
)
953 err
|= cfc_check_trigger_arg_min(&cmd
->convert_arg
, 125000);
955 err
|= cfc_check_trigger_arg_is(&cmd
->scan_end_arg
, cmd
->chanlist_len
);
957 if (cmd
->stop_src
== TRIG_COUNT
)
958 err
|= cfc_check_trigger_arg_min(&cmd
->stop_arg
, 1);
960 err
|= cfc_check_trigger_arg_is(&cmd
->stop_arg
, 0);
968 static int usbdux_ao_cmd(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
970 struct usbdux_private
*devpriv
= dev
->private;
971 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
976 if (devpriv
->ao_cmd_running
)
979 /* we count in steps of 1ms (125us) */
980 /* 125us mode not used yet */
981 if (0) { /* (devpriv->high_speed) */
983 /* timing of the conversion itself: every 125 us */
984 devpriv
->ao_timer
= cmd
->convert_arg
/ 125000;
987 /* timing of the scan: we get all channels at once */
988 devpriv
->ao_timer
= cmd
->scan_begin_arg
/ 1000000;
989 if (devpriv
->ao_timer
< 1) {
995 devpriv
->ao_counter
= devpriv
->ao_timer
;
997 if (cmd
->start_src
== TRIG_NOW
) {
998 /* enable this acquisition operation */
999 devpriv
->ao_cmd_running
= 1;
1000 ret
= usbdux_submit_urbs(dev
, devpriv
->ao_urbs
,
1001 devpriv
->n_ao_urbs
, 0);
1003 devpriv
->ao_cmd_running
= 0;
1004 /* fixme: unlink here?? */
1007 s
->async
->inttrig
= NULL
;
1010 /* submit the urbs later */
1011 /* wait for an internal signal */
1012 s
->async
->inttrig
= usbdux_ao_inttrig
;
1021 static int usbdux_dio_insn_config(struct comedi_device
*dev
,
1022 struct comedi_subdevice
*s
,
1023 struct comedi_insn
*insn
,
1028 ret
= comedi_dio_insn_config(dev
, s
, insn
, data
, 0);
1033 * We don't tell the firmware here as it would take 8 frames
1034 * to submit the information. We do it in the insn_bits.
1039 static int usbdux_dio_insn_bits(struct comedi_device
*dev
,
1040 struct comedi_subdevice
*s
,
1041 struct comedi_insn
*insn
,
1045 struct usbdux_private
*devpriv
= dev
->private;
1048 down(&devpriv
->sem
);
1050 comedi_dio_update_state(s
, data
);
1052 /* Always update the hardware. See the (*insn_config). */
1053 devpriv
->dux_commands
[1] = s
->io_bits
;
1054 devpriv
->dux_commands
[2] = s
->state
;
1057 * This command also tells the firmware to return
1058 * the digital input lines.
1060 ret
= send_dux_commands(dev
, USBDUX_CMD_DIO_BITS
);
1063 ret
= receive_dux_commands(dev
, USBDUX_CMD_DIO_BITS
);
1067 data
[1] = le16_to_cpu(devpriv
->insn_buf
[1]);
1072 return ret
? ret
: insn
->n
;
1075 static int usbdux_counter_read(struct comedi_device
*dev
,
1076 struct comedi_subdevice
*s
,
1077 struct comedi_insn
*insn
,
1080 struct usbdux_private
*devpriv
= dev
->private;
1081 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1085 down(&devpriv
->sem
);
1087 for (i
= 0; i
< insn
->n
; i
++) {
1088 ret
= send_dux_commands(dev
, USBDUX_CMD_TIMER_RD
);
1090 goto counter_read_exit
;
1091 ret
= receive_dux_commands(dev
, USBDUX_CMD_TIMER_RD
);
1093 goto counter_read_exit
;
1095 data
[i
] = le16_to_cpu(devpriv
->insn_buf
[chan
+ 1]);
1101 return ret
? ret
: insn
->n
;
1104 static int usbdux_counter_write(struct comedi_device
*dev
,
1105 struct comedi_subdevice
*s
,
1106 struct comedi_insn
*insn
,
1109 struct usbdux_private
*devpriv
= dev
->private;
1110 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1111 __le16
*p
= (__le16
*)&devpriv
->dux_commands
[2];
1115 down(&devpriv
->sem
);
1117 devpriv
->dux_commands
[1] = chan
;
1119 for (i
= 0; i
< insn
->n
; i
++) {
1120 *p
= cpu_to_le16(data
[i
]);
1122 ret
= send_dux_commands(dev
, USBDUX_CMD_TIMER_WR
);
1129 return ret
? ret
: insn
->n
;
1132 static int usbdux_counter_config(struct comedi_device
*dev
,
1133 struct comedi_subdevice
*s
,
1134 struct comedi_insn
*insn
, unsigned int *data
)
1136 /* nothing to do so far */
1140 static void usbduxsub_unlink_pwm_urbs(struct comedi_device
*dev
)
1142 struct usbdux_private
*devpriv
= dev
->private;
1144 usb_kill_urb(devpriv
->pwm_urb
);
1147 static void usbdux_pwm_stop(struct comedi_device
*dev
, int do_unlink
)
1149 struct usbdux_private
*devpriv
= dev
->private;
1152 usbduxsub_unlink_pwm_urbs(dev
);
1154 devpriv
->pwm_cmd_running
= 0;
1157 static int usbdux_pwm_cancel(struct comedi_device
*dev
,
1158 struct comedi_subdevice
*s
)
1160 struct usbdux_private
*devpriv
= dev
->private;
1163 down(&devpriv
->sem
);
1164 /* unlink only if it is really running */
1165 usbdux_pwm_stop(dev
, devpriv
->pwm_cmd_running
);
1166 ret
= send_dux_commands(dev
, USBDUX_CMD_PWM_OFF
);
1172 static void usbduxsub_pwm_irq(struct urb
*urb
)
1174 struct comedi_device
*dev
= urb
->context
;
1175 struct usbdux_private
*devpriv
= dev
->private;
1178 switch (urb
->status
) {
1188 * after an unlink command, unplug, ... etc
1189 * no unlink needed here. Already shutting down.
1191 if (devpriv
->pwm_cmd_running
)
1192 usbdux_pwm_stop(dev
, 0);
1198 if (devpriv
->pwm_cmd_running
) {
1199 dev_err(dev
->class_dev
,
1200 "Non-zero urb status received in pwm intr context: %d\n",
1202 usbdux_pwm_stop(dev
, 0);
1207 /* are we actually running? */
1208 if (!devpriv
->pwm_cmd_running
)
1211 urb
->transfer_buffer_length
= devpriv
->pwm_buf_sz
;
1212 urb
->dev
= comedi_to_usb_dev(dev
);
1214 if (devpriv
->pwm_cmd_running
) {
1215 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
1217 dev_err(dev
->class_dev
,
1218 "pwm urb resubm failed in int-cont. ret=%d",
1220 if (ret
== -EL2NSYNC
)
1221 dev_err(dev
->class_dev
,
1222 "buggy USB host controller or bug in IRQ handling!\n");
1224 /* don't do an unlink here */
1225 usbdux_pwm_stop(dev
, 0);
1230 static int usbduxsub_submit_pwm_urbs(struct comedi_device
*dev
)
1232 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
1233 struct usbdux_private
*devpriv
= dev
->private;
1234 struct urb
*urb
= devpriv
->pwm_urb
;
1236 /* in case of a resubmission after an unlink... */
1237 usb_fill_bulk_urb(urb
, usb
, usb_sndbulkpipe(usb
, 4),
1238 urb
->transfer_buffer
,
1239 devpriv
->pwm_buf_sz
,
1243 return usb_submit_urb(urb
, GFP_ATOMIC
);
1246 static int usbdux_pwm_period(struct comedi_device
*dev
,
1247 struct comedi_subdevice
*s
,
1248 unsigned int period
)
1250 struct usbdux_private
*devpriv
= dev
->private;
1253 if (period
< MIN_PWM_PERIOD
)
1256 fx2delay
= (period
/ (6 * 512 * 1000 / 33)) - 6;
1260 devpriv
->pwm_delay
= fx2delay
;
1261 devpriv
->pwm_period
= period
;
1266 static int usbdux_pwm_start(struct comedi_device
*dev
,
1267 struct comedi_subdevice
*s
)
1269 struct usbdux_private
*devpriv
= dev
->private;
1272 down(&devpriv
->sem
);
1274 if (devpriv
->pwm_cmd_running
)
1275 goto pwm_start_exit
;
1277 devpriv
->dux_commands
[1] = devpriv
->pwm_delay
;
1278 ret
= send_dux_commands(dev
, USBDUX_CMD_PWM_ON
);
1280 goto pwm_start_exit
;
1282 /* initialise the buffer */
1283 memset(devpriv
->pwm_urb
->transfer_buffer
, 0, devpriv
->pwm_buf_sz
);
1285 devpriv
->pwm_cmd_running
= 1;
1286 ret
= usbduxsub_submit_pwm_urbs(dev
);
1288 devpriv
->pwm_cmd_running
= 0;
1296 static void usbdux_pwm_pattern(struct comedi_device
*dev
,
1297 struct comedi_subdevice
*s
,
1302 struct usbdux_private
*devpriv
= dev
->private;
1303 char pwm_mask
= (1 << chan
); /* DIO bit for the PWM data */
1304 char sgn_mask
= (16 << chan
); /* DIO bit for the sign */
1305 char *buf
= (char *)(devpriv
->pwm_urb
->transfer_buffer
);
1306 int szbuf
= devpriv
->pwm_buf_sz
;
1309 for (i
= 0; i
< szbuf
; i
++) {
1323 static int usbdux_pwm_write(struct comedi_device
*dev
,
1324 struct comedi_subdevice
*s
,
1325 struct comedi_insn
*insn
,
1328 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1331 * It doesn't make sense to support more than one value here
1332 * because it would just overwrite the PWM buffer.
1338 * The sign is set via a special INSN only, this gives us 8 bits
1339 * for normal operation, sign is 0 by default.
1341 usbdux_pwm_pattern(dev
, s
, chan
, data
[0], 0);
1346 static int usbdux_pwm_config(struct comedi_device
*dev
,
1347 struct comedi_subdevice
*s
,
1348 struct comedi_insn
*insn
,
1351 struct usbdux_private
*devpriv
= dev
->private;
1352 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1355 case INSN_CONFIG_ARM
:
1357 * if not zero the PWM is limited to a certain time which is
1358 * not supported here
1362 return usbdux_pwm_start(dev
, s
);
1363 case INSN_CONFIG_DISARM
:
1364 return usbdux_pwm_cancel(dev
, s
);
1365 case INSN_CONFIG_GET_PWM_STATUS
:
1366 data
[1] = devpriv
->pwm_cmd_running
;
1368 case INSN_CONFIG_PWM_SET_PERIOD
:
1369 return usbdux_pwm_period(dev
, s
, data
[1]);
1370 case INSN_CONFIG_PWM_GET_PERIOD
:
1371 data
[1] = devpriv
->pwm_period
;
1373 case INSN_CONFIG_PWM_SET_H_BRIDGE
:
1376 * data[2] = sign (for a relay)
1378 usbdux_pwm_pattern(dev
, s
, chan
, data
[1], (data
[2] != 0));
1380 case INSN_CONFIG_PWM_GET_H_BRIDGE
:
1381 /* values are not kept in this driver, nothing to return here */
1387 static int usbdux_firmware_upload(struct comedi_device
*dev
,
1388 const u8
*data
, size_t size
,
1389 unsigned long context
)
1391 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
1399 if (size
> USBDUX_FIRMWARE_MAX_LEN
) {
1400 dev_err(dev
->class_dev
,
1401 "usbdux firmware binary it too large for FX2.\n");
1405 /* we generate a local buffer for the firmware */
1406 buf
= kmemdup(data
, size
, GFP_KERNEL
);
1410 /* we need a malloc'ed buffer for usb_control_msg() */
1411 tmp
= kmalloc(1, GFP_KERNEL
);
1417 /* stop the current firmware on the device */
1418 *tmp
= 1; /* 7f92 to one */
1419 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
1420 USBDUX_FIRMWARE_CMD
,
1422 USBDUX_CPU_CS
, 0x0000,
1426 dev_err(dev
->class_dev
, "can not stop firmware\n");
1430 /* upload the new firmware to the device */
1431 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
1432 USBDUX_FIRMWARE_CMD
,
1438 dev_err(dev
->class_dev
, "firmware upload failed\n");
1442 /* start the new firmware on the device */
1443 *tmp
= 0; /* 7f92 to zero */
1444 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
1445 USBDUX_FIRMWARE_CMD
,
1447 USBDUX_CPU_CS
, 0x0000,
1451 dev_err(dev
->class_dev
, "can not start firmware\n");
1459 static int usbdux_alloc_usb_buffers(struct comedi_device
*dev
)
1461 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
1462 struct usbdux_private
*devpriv
= dev
->private;
1466 devpriv
->dux_commands
= kzalloc(SIZEOFDUXBUFFER
, GFP_KERNEL
);
1467 devpriv
->in_buf
= kzalloc(SIZEINBUF
, GFP_KERNEL
);
1468 devpriv
->insn_buf
= kzalloc(SIZEINSNBUF
, GFP_KERNEL
);
1469 devpriv
->ai_urbs
= kcalloc(devpriv
->n_ai_urbs
, sizeof(void *),
1471 devpriv
->ao_urbs
= kcalloc(devpriv
->n_ao_urbs
, sizeof(void *),
1473 if (!devpriv
->dux_commands
|| !devpriv
->in_buf
|| !devpriv
->insn_buf
||
1474 !devpriv
->ai_urbs
|| !devpriv
->ao_urbs
)
1477 for (i
= 0; i
< devpriv
->n_ai_urbs
; i
++) {
1478 /* one frame: 1ms */
1479 urb
= usb_alloc_urb(1, GFP_KERNEL
);
1482 devpriv
->ai_urbs
[i
] = urb
;
1486 urb
->pipe
= usb_rcvisocpipe(usb
, 6);
1487 urb
->transfer_flags
= URB_ISO_ASAP
;
1488 urb
->transfer_buffer
= kzalloc(SIZEINBUF
, GFP_KERNEL
);
1489 if (!urb
->transfer_buffer
)
1492 urb
->complete
= usbduxsub_ai_isoc_irq
;
1493 urb
->number_of_packets
= 1;
1494 urb
->transfer_buffer_length
= SIZEINBUF
;
1495 urb
->iso_frame_desc
[0].offset
= 0;
1496 urb
->iso_frame_desc
[0].length
= SIZEINBUF
;
1499 for (i
= 0; i
< devpriv
->n_ao_urbs
; i
++) {
1500 /* one frame: 1ms */
1501 urb
= usb_alloc_urb(1, GFP_KERNEL
);
1504 devpriv
->ao_urbs
[i
] = urb
;
1508 urb
->pipe
= usb_sndisocpipe(usb
, 2);
1509 urb
->transfer_flags
= URB_ISO_ASAP
;
1510 urb
->transfer_buffer
= kzalloc(SIZEOUTBUF
, GFP_KERNEL
);
1511 if (!urb
->transfer_buffer
)
1514 urb
->complete
= usbduxsub_ao_isoc_irq
;
1515 urb
->number_of_packets
= 1;
1516 urb
->transfer_buffer_length
= SIZEOUTBUF
;
1517 urb
->iso_frame_desc
[0].offset
= 0;
1518 urb
->iso_frame_desc
[0].length
= SIZEOUTBUF
;
1519 if (devpriv
->high_speed
)
1520 urb
->interval
= 8; /* uframes */
1522 urb
->interval
= 1; /* frames */
1526 if (devpriv
->pwm_buf_sz
) {
1527 urb
= usb_alloc_urb(0, GFP_KERNEL
);
1530 devpriv
->pwm_urb
= urb
;
1532 /* max bulk ep size in high speed */
1533 urb
->transfer_buffer
= kzalloc(devpriv
->pwm_buf_sz
,
1535 if (!urb
->transfer_buffer
)
1542 static void usbdux_free_usb_buffers(struct comedi_device
*dev
)
1544 struct usbdux_private
*devpriv
= dev
->private;
1548 urb
= devpriv
->pwm_urb
;
1550 kfree(urb
->transfer_buffer
);
1553 if (devpriv
->ao_urbs
) {
1554 for (i
= 0; i
< devpriv
->n_ao_urbs
; i
++) {
1555 urb
= devpriv
->ao_urbs
[i
];
1557 kfree(urb
->transfer_buffer
);
1561 kfree(devpriv
->ao_urbs
);
1563 if (devpriv
->ai_urbs
) {
1564 for (i
= 0; i
< devpriv
->n_ai_urbs
; i
++) {
1565 urb
= devpriv
->ai_urbs
[i
];
1567 kfree(urb
->transfer_buffer
);
1571 kfree(devpriv
->ai_urbs
);
1573 kfree(devpriv
->insn_buf
);
1574 kfree(devpriv
->in_buf
);
1575 kfree(devpriv
->dux_commands
);
1578 static int usbdux_auto_attach(struct comedi_device
*dev
,
1579 unsigned long context_unused
)
1581 struct usb_interface
*intf
= comedi_to_usb_interface(dev
);
1582 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
1583 struct usbdux_private
*devpriv
;
1584 struct comedi_subdevice
*s
;
1587 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
1591 sema_init(&devpriv
->sem
, 1);
1593 usb_set_intfdata(intf
, devpriv
);
1595 devpriv
->high_speed
= (usb
->speed
== USB_SPEED_HIGH
);
1596 if (devpriv
->high_speed
) {
1597 devpriv
->n_ai_urbs
= NUMOFINBUFFERSHIGH
;
1598 devpriv
->n_ao_urbs
= NUMOFOUTBUFFERSHIGH
;
1599 devpriv
->pwm_buf_sz
= 512;
1601 devpriv
->n_ai_urbs
= NUMOFINBUFFERSFULL
;
1602 devpriv
->n_ao_urbs
= NUMOFOUTBUFFERSFULL
;
1605 ret
= usbdux_alloc_usb_buffers(dev
);
1609 /* setting to alternate setting 3: enabling iso ep and bulk ep. */
1610 ret
= usb_set_interface(usb
, intf
->altsetting
->desc
.bInterfaceNumber
,
1613 dev_err(dev
->class_dev
,
1614 "could not set alternate setting 3 in high speed\n");
1618 ret
= comedi_load_firmware(dev
, &usb
->dev
, USBDUX_FIRMWARE
,
1619 usbdux_firmware_upload
, 0);
1623 ret
= comedi_alloc_subdevices(dev
, (devpriv
->high_speed
) ? 5 : 4);
1627 /* Analog Input subdevice */
1628 s
= &dev
->subdevices
[0];
1629 dev
->read_subdev
= s
;
1630 s
->type
= COMEDI_SUBD_AI
;
1631 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
| SDF_CMD_READ
;
1633 s
->maxdata
= 0x0fff;
1634 s
->len_chanlist
= 8;
1635 s
->range_table
= &range_usbdux_ai_range
;
1636 s
->insn_read
= usbdux_ai_insn_read
;
1637 s
->do_cmdtest
= usbdux_ai_cmdtest
;
1638 s
->do_cmd
= usbdux_ai_cmd
;
1639 s
->cancel
= usbdux_ai_cancel
;
1641 /* Analog Output subdevice */
1642 s
= &dev
->subdevices
[1];
1643 dev
->write_subdev
= s
;
1644 s
->type
= COMEDI_SUBD_AO
;
1645 s
->subdev_flags
= SDF_WRITABLE
| SDF_GROUND
| SDF_CMD_WRITE
;
1647 s
->maxdata
= 0x0fff;
1648 s
->len_chanlist
= s
->n_chan
;
1649 s
->range_table
= &range_usbdux_ao_range
;
1650 s
->do_cmdtest
= usbdux_ao_cmdtest
;
1651 s
->do_cmd
= usbdux_ao_cmd
;
1652 s
->cancel
= usbdux_ao_cancel
;
1653 s
->insn_read
= usbdux_ao_insn_read
;
1654 s
->insn_write
= usbdux_ao_insn_write
;
1656 ret
= comedi_alloc_subdev_readback(s
);
1660 /* Digital I/O subdevice */
1661 s
= &dev
->subdevices
[2];
1662 s
->type
= COMEDI_SUBD_DIO
;
1663 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
1666 s
->range_table
= &range_digital
;
1667 s
->insn_bits
= usbdux_dio_insn_bits
;
1668 s
->insn_config
= usbdux_dio_insn_config
;
1670 /* Counter subdevice */
1671 s
= &dev
->subdevices
[3];
1672 s
->type
= COMEDI_SUBD_COUNTER
;
1673 s
->subdev_flags
= SDF_WRITABLE
| SDF_READABLE
;
1675 s
->maxdata
= 0xffff;
1676 s
->insn_read
= usbdux_counter_read
;
1677 s
->insn_write
= usbdux_counter_write
;
1678 s
->insn_config
= usbdux_counter_config
;
1680 if (devpriv
->high_speed
) {
1682 s
= &dev
->subdevices
[4];
1683 s
->type
= COMEDI_SUBD_PWM
;
1684 s
->subdev_flags
= SDF_WRITABLE
| SDF_PWM_HBRIDGE
;
1686 s
->maxdata
= devpriv
->pwm_buf_sz
;
1687 s
->insn_write
= usbdux_pwm_write
;
1688 s
->insn_config
= usbdux_pwm_config
;
1690 usbdux_pwm_period(dev
, s
, PWM_DEFAULT_PERIOD
);
1696 static void usbdux_detach(struct comedi_device
*dev
)
1698 struct usb_interface
*intf
= comedi_to_usb_interface(dev
);
1699 struct usbdux_private
*devpriv
= dev
->private;
1701 usb_set_intfdata(intf
, NULL
);
1706 down(&devpriv
->sem
);
1708 /* force unlink all urbs */
1709 usbdux_pwm_stop(dev
, 1);
1710 usbdux_ao_stop(dev
, 1);
1711 usbdux_ai_stop(dev
, 1);
1713 usbdux_free_usb_buffers(dev
);
1718 static struct comedi_driver usbdux_driver
= {
1719 .driver_name
= "usbdux",
1720 .module
= THIS_MODULE
,
1721 .auto_attach
= usbdux_auto_attach
,
1722 .detach
= usbdux_detach
,
1725 static int usbdux_usb_probe(struct usb_interface
*intf
,
1726 const struct usb_device_id
*id
)
1728 return comedi_usb_auto_config(intf
, &usbdux_driver
, 0);
1731 static const struct usb_device_id usbdux_usb_table
[] = {
1732 { USB_DEVICE(0x13d8, 0x0001) },
1733 { USB_DEVICE(0x13d8, 0x0002) },
1736 MODULE_DEVICE_TABLE(usb
, usbdux_usb_table
);
1738 static struct usb_driver usbdux_usb_driver
= {
1740 .probe
= usbdux_usb_probe
,
1741 .disconnect
= comedi_usb_auto_unconfig
,
1742 .id_table
= usbdux_usb_table
,
1744 module_comedi_usb_driver(usbdux_driver
, usbdux_usb_driver
);
1746 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1747 MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com");
1748 MODULE_LICENSE("GPL");
1749 MODULE_FIRMWARE(USBDUX_FIRMWARE
);