1 // SPDX-License-Identifier: GPL-2.0+
4 * Copyright (C) 2003-2014 Bernd Porr, mail@berndporr.me.uk
9 * Description: University of Stirling USB DAQ & INCITE Technology Limited
10 * Devices: [ITL] USB-DUX (usbdux)
11 * Author: Bernd Porr <mail@berndporr.me.uk>
12 * Updated: 10 Oct 2014
15 * Connection scheme for the counter at the digital port:
16 * 0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1.
17 * The sampling rate of the counter is approximately 500Hz.
19 * Note that under USB2.0 the length of the channel list determines
20 * the max sampling rate. If you sample only one channel you get 8kHz
21 * sampling rate. If you sample two channels you get 4kHz and so on.
25 * I must give credit here to Chris Baugher who
26 * wrote the driver for AT-MIO-16d. I used some parts of this
27 * driver. I also must give credits to David Brownell
28 * who supported me with the USB development.
34 * 0.94: D/A output should work now with any channel list combinations
35 * 0.95: .owner commented out for kernel vers below 2.4.19
36 * sanity checks in ai/ao_cmd
37 * 0.96: trying to get it working with 2.6, moved all memory alloc to comedi's
38 * attach final USB IDs
39 * moved memory allocation completely to the corresponding comedi
40 * functions firmware upload is by fxload and no longer by comedi (due to
42 * 0.97: USB IDs received, adjusted table
43 * 0.98: SMP, locking, memory alloc: moved all usb memory alloc
44 * to the usb subsystem and moved all comedi related memory
46 * | kernel | registration | usbdux-usb | usbdux-comedi | comedi |
47 * 0.99: USB 2.0: changed protocol to isochronous transfer
48 * IRQ transfer is too buggy and too risky in 2.0
49 * for the high speed ISO transfer is now a working version
51 * 0.99b: Increased the iso transfer buffer for high sp.to 10 buffers. Some VIA
52 * chipsets miss out IRQs. Deeper buffering is needed.
53 * 1.00: full USB 2.0 support for the A/D converter. Now: max 8kHz sampling
55 * Firmware vers 1.00 is needed for this.
56 * Two 16 bit up/down/reset counter with a sampling rate of 1kHz
57 * And loads of cleaning up, in particular streamlining the
59 * 1.1: moved EP4 transfers to EP1 to make space for a PWM output on EP4
60 * 1.2: added PWM support via EP4
61 * 2.0: PWM seems to be stable and is not interfering with the other functions
62 * 2.1: changed PWM API
63 * 2.2: added firmware kernel request to fix an udev problem
64 * 2.3: corrected a bug in bulk timeouts which were far too short
65 * 2.4: fixed a bug which causes the driver to hang when it ran out of data.
66 * Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it.
70 #include <linux/kernel.h>
71 #include <linux/module.h>
72 #include <linux/slab.h>
73 #include <linux/input.h>
74 #include <linux/fcntl.h>
75 #include <linux/compiler.h>
76 #include <linux/comedi/comedi_usb.h>
78 /* constants for firmware upload and download */
79 #define USBDUX_FIRMWARE "usbdux_firmware.bin"
80 #define USBDUX_FIRMWARE_MAX_LEN 0x2000
81 #define USBDUX_FIRMWARE_CMD 0xa0
82 #define VENDOR_DIR_IN 0xc0
83 #define VENDOR_DIR_OUT 0x40
84 #define USBDUX_CPU_CS 0xe600
86 /* usbdux bulk transfer commands */
87 #define USBDUX_CMD_MULT_AI 0
88 #define USBDUX_CMD_AO 1
89 #define USBDUX_CMD_DIO_CFG 2
90 #define USBDUX_CMD_DIO_BITS 3
91 #define USBDUX_CMD_SINGLE_AI 4
92 #define USBDUX_CMD_TIMER_RD 5
93 #define USBDUX_CMD_TIMER_WR 6
94 #define USBDUX_CMD_PWM_ON 7
95 #define USBDUX_CMD_PWM_OFF 8
97 /* timeout for the USB-transfer in ms */
98 #define BULK_TIMEOUT 1000
100 /* 300Hz max frequ under PWM */
101 #define MIN_PWM_PERIOD ((long)(1E9 / 300))
103 /* Default PWM frequency */
104 #define PWM_DEFAULT_PERIOD ((long)(1E9 / 100))
106 /* Size of one A/D value */
107 #define SIZEADIN ((sizeof(u16)))
110 * Size of the input-buffer IN BYTES
111 * Always multiple of 8 for 8 microframes which is needed in the highspeed mode
113 #define SIZEINBUF (8 * SIZEADIN)
116 #define SIZEINSNBUF 16
118 /* size of one value for the D/A converter: channel and value */
119 #define SIZEDAOUT ((sizeof(u8) + sizeof(u16)))
122 * Size of the output-buffer in bytes
123 * Actually only the first 4 triplets are used but for the
124 * high speed mode we need to pad it to 8 (microframes).
126 #define SIZEOUTBUF (8 * SIZEDAOUT)
129 * Size of the buffer for the dux commands: just now max size is determined
130 * by the analogue out + command byte + panic bytes...
132 #define SIZEOFDUXBUFFER (8 * SIZEDAOUT + 2)
134 /* Number of in-URBs which receive the data: min=2 */
135 #define NUMOFINBUFFERSFULL 5
137 /* Number of out-URBs which send the data: min=2 */
138 #define NUMOFOUTBUFFERSFULL 5
140 /* Number of in-URBs which receive the data: min=5 */
141 /* must have more buffers due to buggy USB ctr */
142 #define NUMOFINBUFFERSHIGH 10
144 /* Number of out-URBs which send the data: min=5 */
145 /* must have more buffers due to buggy USB ctr */
146 #define NUMOFOUTBUFFERSHIGH 10
148 /* number of retries to get the right dux command */
151 static const struct comedi_lrange range_usbdux_ai_range
= {
154 BIP_RANGE(4.096 / 2),
160 static const struct comedi_lrange range_usbdux_ao_range
= {
167 struct usbdux_private
{
168 /* actual number of in-buffers */
170 /* actual number of out-buffers */
172 /* ISO-transfer handling: buffers */
173 struct urb
**ai_urbs
;
174 struct urb
**ao_urbs
;
175 /* pwm-transfer handling */
178 unsigned int pwm_period
;
179 /* PWM internal delay for the GPIF in the FX2 */
181 /* size of the PWM buffer which holds the bit pattern */
183 /* input buffer for the ISO-transfer */
185 /* input buffer for single insn */
188 unsigned int high_speed
:1;
189 unsigned int ai_cmd_running
:1;
190 unsigned int ao_cmd_running
:1;
191 unsigned int pwm_cmd_running
:1;
193 /* time between samples in units of the timer */
194 unsigned int ai_timer
;
195 unsigned int ao_timer
;
196 /* counter between aquisitions */
197 unsigned int ai_counter
;
198 unsigned int ao_counter
;
199 /* interval in frames/uframes */
200 unsigned int ai_interval
;
206 static void usbdux_unlink_urbs(struct urb
**urbs
, int num_urbs
)
210 for (i
= 0; i
< num_urbs
; i
++)
211 usb_kill_urb(urbs
[i
]);
214 static void usbdux_ai_stop(struct comedi_device
*dev
, int do_unlink
)
216 struct usbdux_private
*devpriv
= dev
->private;
218 if (do_unlink
&& devpriv
->ai_urbs
)
219 usbdux_unlink_urbs(devpriv
->ai_urbs
, devpriv
->n_ai_urbs
);
221 devpriv
->ai_cmd_running
= 0;
224 static int usbdux_ai_cancel(struct comedi_device
*dev
,
225 struct comedi_subdevice
*s
)
227 struct usbdux_private
*devpriv
= dev
->private;
229 /* prevent other CPUs from submitting new commands just now */
230 mutex_lock(&devpriv
->mut
);
231 /* unlink only if the urb really has been submitted */
232 usbdux_ai_stop(dev
, devpriv
->ai_cmd_running
);
233 mutex_unlock(&devpriv
->mut
);
238 static void usbduxsub_ai_handle_urb(struct comedi_device
*dev
,
239 struct comedi_subdevice
*s
,
242 struct usbdux_private
*devpriv
= dev
->private;
243 struct comedi_async
*async
= s
->async
;
244 struct comedi_cmd
*cmd
= &async
->cmd
;
248 devpriv
->ai_counter
--;
249 if (devpriv
->ai_counter
== 0) {
250 devpriv
->ai_counter
= devpriv
->ai_timer
;
252 /* get the data from the USB bus and hand it over to comedi */
253 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
254 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
255 u16 val
= le16_to_cpu(devpriv
->in_buf
[i
]);
257 /* bipolar data is two's-complement */
258 if (comedi_range_is_bipolar(s
, range
))
259 val
= comedi_offset_munge(s
, val
);
262 if (!comedi_buf_write_samples(s
, &val
, 1))
266 if (cmd
->stop_src
== TRIG_COUNT
&&
267 async
->scans_done
>= cmd
->stop_arg
)
268 async
->events
|= COMEDI_CB_EOA
;
271 /* if command is still running, resubmit urb */
272 if (!(async
->events
& COMEDI_CB_CANCEL_MASK
)) {
273 urb
->dev
= comedi_to_usb_dev(dev
);
274 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
276 dev_err(dev
->class_dev
,
277 "urb resubmit failed in int-context! err=%d\n",
279 if (ret
== -EL2NSYNC
)
280 dev_err(dev
->class_dev
,
281 "buggy USB host controller or bug in IRQ handler!\n");
282 async
->events
|= COMEDI_CB_ERROR
;
287 static void usbduxsub_ai_isoc_irq(struct urb
*urb
)
289 struct comedi_device
*dev
= urb
->context
;
290 struct comedi_subdevice
*s
= dev
->read_subdev
;
291 struct comedi_async
*async
= s
->async
;
292 struct usbdux_private
*devpriv
= dev
->private;
294 /* exit if not running a command, do not resubmit urb */
295 if (!devpriv
->ai_cmd_running
)
298 switch (urb
->status
) {
300 /* copy the result in the transfer buffer */
301 memcpy(devpriv
->in_buf
, urb
->transfer_buffer
, SIZEINBUF
);
302 usbduxsub_ai_handle_urb(dev
, s
, urb
);
307 * error in the ISOchronous data
308 * we don't copy the data into the transfer buffer
309 * and recycle the last data byte
311 dev_dbg(dev
->class_dev
, "CRC error in ISO IN stream\n");
312 usbduxsub_ai_handle_urb(dev
, s
, urb
);
319 /* after an unlink command, unplug, ... etc */
320 async
->events
|= COMEDI_CB_ERROR
;
325 dev_err(dev
->class_dev
,
326 "Non-zero urb status received in ai intr context: %d\n",
328 async
->events
|= COMEDI_CB_ERROR
;
333 * comedi_handle_events() cannot be used in this driver. The (*cancel)
334 * operation would unlink the urb.
336 if (async
->events
& COMEDI_CB_CANCEL_MASK
)
337 usbdux_ai_stop(dev
, 0);
339 comedi_event(dev
, s
);
342 static void usbdux_ao_stop(struct comedi_device
*dev
, int do_unlink
)
344 struct usbdux_private
*devpriv
= dev
->private;
346 if (do_unlink
&& devpriv
->ao_urbs
)
347 usbdux_unlink_urbs(devpriv
->ao_urbs
, devpriv
->n_ao_urbs
);
349 devpriv
->ao_cmd_running
= 0;
352 static int usbdux_ao_cancel(struct comedi_device
*dev
,
353 struct comedi_subdevice
*s
)
355 struct usbdux_private
*devpriv
= dev
->private;
357 /* prevent other CPUs from submitting a command just now */
358 mutex_lock(&devpriv
->mut
);
359 /* unlink only if it is really running */
360 usbdux_ao_stop(dev
, devpriv
->ao_cmd_running
);
361 mutex_unlock(&devpriv
->mut
);
366 static void usbduxsub_ao_handle_urb(struct comedi_device
*dev
,
367 struct comedi_subdevice
*s
,
370 struct usbdux_private
*devpriv
= dev
->private;
371 struct comedi_async
*async
= s
->async
;
372 struct comedi_cmd
*cmd
= &async
->cmd
;
377 devpriv
->ao_counter
--;
378 if (devpriv
->ao_counter
== 0) {
379 devpriv
->ao_counter
= devpriv
->ao_timer
;
381 if (cmd
->stop_src
== TRIG_COUNT
&&
382 async
->scans_done
>= cmd
->stop_arg
) {
383 async
->events
|= COMEDI_CB_EOA
;
387 /* transmit data to the USB bus */
388 datap
= urb
->transfer_buffer
;
389 *datap
++ = cmd
->chanlist_len
;
390 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
391 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
394 if (!comedi_buf_read_samples(s
, &val
, 1)) {
395 dev_err(dev
->class_dev
, "buffer underflow\n");
396 async
->events
|= COMEDI_CB_OVERFLOW
;
400 /* pointer to the DA */
401 *datap
++ = val
& 0xff;
402 *datap
++ = (val
>> 8) & 0xff;
403 *datap
++ = chan
<< 6;
404 s
->readback
[chan
] = val
;
408 /* if command is still running, resubmit urb for BULK transfer */
409 if (!(async
->events
& COMEDI_CB_CANCEL_MASK
)) {
410 urb
->transfer_buffer_length
= SIZEOUTBUF
;
411 urb
->dev
= comedi_to_usb_dev(dev
);
413 if (devpriv
->high_speed
)
414 urb
->interval
= 8; /* uframes */
416 urb
->interval
= 1; /* frames */
417 urb
->number_of_packets
= 1;
418 urb
->iso_frame_desc
[0].offset
= 0;
419 urb
->iso_frame_desc
[0].length
= SIZEOUTBUF
;
420 urb
->iso_frame_desc
[0].status
= 0;
421 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
423 dev_err(dev
->class_dev
,
424 "ao urb resubm failed in int-cont. ret=%d",
426 if (ret
== -EL2NSYNC
)
427 dev_err(dev
->class_dev
,
428 "buggy USB host controller or bug in IRQ handling!\n");
429 async
->events
|= COMEDI_CB_ERROR
;
434 static void usbduxsub_ao_isoc_irq(struct urb
*urb
)
436 struct comedi_device
*dev
= urb
->context
;
437 struct comedi_subdevice
*s
= dev
->write_subdev
;
438 struct comedi_async
*async
= s
->async
;
439 struct usbdux_private
*devpriv
= dev
->private;
441 /* exit if not running a command, do not resubmit urb */
442 if (!devpriv
->ao_cmd_running
)
445 switch (urb
->status
) {
447 usbduxsub_ao_handle_urb(dev
, s
, urb
);
454 /* after an unlink command, unplug, ... etc */
455 async
->events
|= COMEDI_CB_ERROR
;
460 dev_err(dev
->class_dev
,
461 "Non-zero urb status received in ao intr context: %d\n",
463 async
->events
|= COMEDI_CB_ERROR
;
468 * comedi_handle_events() cannot be used in this driver. The (*cancel)
469 * operation would unlink the urb.
471 if (async
->events
& COMEDI_CB_CANCEL_MASK
)
472 usbdux_ao_stop(dev
, 0);
474 comedi_event(dev
, s
);
477 static int usbdux_submit_urbs(struct comedi_device
*dev
,
478 struct urb
**urbs
, int num_urbs
,
481 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
482 struct usbdux_private
*devpriv
= dev
->private;
487 /* Submit all URBs and start the transfer on the bus */
488 for (i
= 0; i
< num_urbs
; i
++) {
491 /* in case of a resubmission after an unlink... */
493 urb
->interval
= devpriv
->ai_interval
;
497 urb
->transfer_flags
= URB_ISO_ASAP
;
499 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
506 static int usbdux_ai_cmdtest(struct comedi_device
*dev
,
507 struct comedi_subdevice
*s
, struct comedi_cmd
*cmd
)
509 struct usbdux_private
*devpriv
= dev
->private;
512 /* Step 1 : check if triggers are trivially valid */
514 err
|= comedi_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_INT
);
515 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
, TRIG_TIMER
);
516 err
|= comedi_check_trigger_src(&cmd
->convert_src
, TRIG_NOW
);
517 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
518 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
523 /* Step 2a : make sure trigger sources are unique */
525 err
|= comedi_check_trigger_is_unique(cmd
->start_src
);
526 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
528 /* Step 2b : and mutually compatible */
533 /* Step 3: check if arguments are trivially valid */
535 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
537 if (cmd
->scan_begin_src
== TRIG_FOLLOW
) /* internal trigger */
538 err
|= comedi_check_trigger_arg_is(&cmd
->scan_begin_arg
, 0);
540 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
541 /* full speed does 1kHz scans every USB frame */
542 unsigned int arg
= 1000000;
543 unsigned int min_arg
= arg
;
545 if (devpriv
->high_speed
) {
547 * In high speed mode microframes are possible.
548 * However, during one microframe we can roughly
549 * sample one channel. Thus, the more channels
550 * are in the channel list the more time we need.
554 /* find a power of 2 for the number of channels */
555 while (i
< cmd
->chanlist_len
)
561 err
|= comedi_check_trigger_arg_min(&cmd
->scan_begin_arg
,
563 /* calc the real sampling rate with the rounding errors */
564 arg
= (cmd
->scan_begin_arg
/ arg
) * arg
;
565 err
|= comedi_check_trigger_arg_is(&cmd
->scan_begin_arg
, arg
);
568 err
|= comedi_check_trigger_arg_is(&cmd
->scan_end_arg
,
571 if (cmd
->stop_src
== TRIG_COUNT
)
572 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
574 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
583 * creates the ADC command for the MAX1271
584 * range is the range value from comedi
586 static u8
create_adc_command(unsigned int chan
, unsigned int range
)
589 u8 r
= ((range
% 2) == 0);
591 return (chan
<< 4) | ((p
== 1) << 2) | ((r
== 1) << 3);
594 static int send_dux_commands(struct comedi_device
*dev
, unsigned int cmd_type
)
596 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
597 struct usbdux_private
*devpriv
= dev
->private;
600 devpriv
->dux_commands
[0] = cmd_type
;
602 return usb_bulk_msg(usb
, usb_sndbulkpipe(usb
, 1),
603 devpriv
->dux_commands
, SIZEOFDUXBUFFER
,
604 &nsent
, BULK_TIMEOUT
);
607 static int receive_dux_commands(struct comedi_device
*dev
, unsigned int command
)
609 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
610 struct usbdux_private
*devpriv
= dev
->private;
615 for (i
= 0; i
< RETRIES
; i
++) {
616 ret
= usb_bulk_msg(usb
, usb_rcvbulkpipe(usb
, 8),
617 devpriv
->insn_buf
, SIZEINSNBUF
,
618 &nrec
, BULK_TIMEOUT
);
621 if (le16_to_cpu(devpriv
->insn_buf
[0]) == command
)
624 /* command not received */
628 static int usbdux_ai_inttrig(struct comedi_device
*dev
,
629 struct comedi_subdevice
*s
,
630 unsigned int trig_num
)
632 struct usbdux_private
*devpriv
= dev
->private;
633 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
636 if (trig_num
!= cmd
->start_arg
)
639 mutex_lock(&devpriv
->mut
);
641 if (!devpriv
->ai_cmd_running
) {
642 devpriv
->ai_cmd_running
= 1;
643 ret
= usbdux_submit_urbs(dev
, devpriv
->ai_urbs
,
644 devpriv
->n_ai_urbs
, 1);
646 devpriv
->ai_cmd_running
= 0;
649 s
->async
->inttrig
= NULL
;
655 mutex_unlock(&devpriv
->mut
);
659 static int usbdux_ai_cmd(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
661 struct usbdux_private
*devpriv
= dev
->private;
662 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
663 int len
= cmd
->chanlist_len
;
667 /* block other CPUs from starting an ai_cmd */
668 mutex_lock(&devpriv
->mut
);
670 if (devpriv
->ai_cmd_running
)
673 devpriv
->dux_commands
[1] = len
;
674 for (i
= 0; i
< len
; ++i
) {
675 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
676 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
678 devpriv
->dux_commands
[i
+ 2] = create_adc_command(chan
, range
);
681 ret
= send_dux_commands(dev
, USBDUX_CMD_MULT_AI
);
685 if (devpriv
->high_speed
) {
687 * every channel gets a time window of 125us. Thus, if we
688 * sample all 8 channels we need 1ms. If we sample only one
689 * channel we need only 125us
691 devpriv
->ai_interval
= 1;
692 /* find a power of 2 for the interval */
693 while (devpriv
->ai_interval
< len
)
694 devpriv
->ai_interval
*= 2;
696 devpriv
->ai_timer
= cmd
->scan_begin_arg
/
697 (125000 * devpriv
->ai_interval
);
699 /* interval always 1ms */
700 devpriv
->ai_interval
= 1;
701 devpriv
->ai_timer
= cmd
->scan_begin_arg
/ 1000000;
703 if (devpriv
->ai_timer
< 1) {
708 devpriv
->ai_counter
= devpriv
->ai_timer
;
710 if (cmd
->start_src
== TRIG_NOW
) {
711 /* enable this acquisition operation */
712 devpriv
->ai_cmd_running
= 1;
713 ret
= usbdux_submit_urbs(dev
, devpriv
->ai_urbs
,
714 devpriv
->n_ai_urbs
, 1);
716 devpriv
->ai_cmd_running
= 0;
717 /* fixme: unlink here?? */
720 s
->async
->inttrig
= NULL
;
723 /* don't enable the acquision operation */
724 /* wait for an internal signal */
725 s
->async
->inttrig
= usbdux_ai_inttrig
;
729 mutex_unlock(&devpriv
->mut
);
734 /* Mode 0 is used to get a single conversion on demand */
735 static int usbdux_ai_insn_read(struct comedi_device
*dev
,
736 struct comedi_subdevice
*s
,
737 struct comedi_insn
*insn
,
740 struct usbdux_private
*devpriv
= dev
->private;
741 unsigned int chan
= CR_CHAN(insn
->chanspec
);
742 unsigned int range
= CR_RANGE(insn
->chanspec
);
747 mutex_lock(&devpriv
->mut
);
749 if (devpriv
->ai_cmd_running
)
752 /* set command for the first channel */
753 devpriv
->dux_commands
[1] = create_adc_command(chan
, range
);
756 ret
= send_dux_commands(dev
, USBDUX_CMD_SINGLE_AI
);
760 for (i
= 0; i
< insn
->n
; i
++) {
761 ret
= receive_dux_commands(dev
, USBDUX_CMD_SINGLE_AI
);
765 val
= le16_to_cpu(devpriv
->insn_buf
[1]);
767 /* bipolar data is two's-complement */
768 if (comedi_range_is_bipolar(s
, range
))
769 val
= comedi_offset_munge(s
, val
);
775 mutex_unlock(&devpriv
->mut
);
777 return ret
? ret
: insn
->n
;
780 static int usbdux_ao_insn_read(struct comedi_device
*dev
,
781 struct comedi_subdevice
*s
,
782 struct comedi_insn
*insn
,
785 struct usbdux_private
*devpriv
= dev
->private;
788 mutex_lock(&devpriv
->mut
);
789 ret
= comedi_readback_insn_read(dev
, s
, insn
, data
);
790 mutex_unlock(&devpriv
->mut
);
795 static int usbdux_ao_insn_write(struct comedi_device
*dev
,
796 struct comedi_subdevice
*s
,
797 struct comedi_insn
*insn
,
800 struct usbdux_private
*devpriv
= dev
->private;
801 unsigned int chan
= CR_CHAN(insn
->chanspec
);
802 __le16
*p
= (__le16
*)&devpriv
->dux_commands
[2];
806 mutex_lock(&devpriv
->mut
);
808 if (devpriv
->ao_cmd_running
)
811 /* number of channels: 1 */
812 devpriv
->dux_commands
[1] = 1;
814 devpriv
->dux_commands
[4] = chan
<< 6;
816 for (i
= 0; i
< insn
->n
; i
++) {
817 unsigned int val
= data
[i
];
819 /* one 16 bit value */
820 *p
= cpu_to_le16(val
);
822 ret
= send_dux_commands(dev
, USBDUX_CMD_AO
);
826 s
->readback
[chan
] = val
;
830 mutex_unlock(&devpriv
->mut
);
832 return ret
? ret
: insn
->n
;
835 static int usbdux_ao_inttrig(struct comedi_device
*dev
,
836 struct comedi_subdevice
*s
,
837 unsigned int trig_num
)
839 struct usbdux_private
*devpriv
= dev
->private;
840 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
843 if (trig_num
!= cmd
->start_arg
)
846 mutex_lock(&devpriv
->mut
);
848 if (!devpriv
->ao_cmd_running
) {
849 devpriv
->ao_cmd_running
= 1;
850 ret
= usbdux_submit_urbs(dev
, devpriv
->ao_urbs
,
851 devpriv
->n_ao_urbs
, 0);
853 devpriv
->ao_cmd_running
= 0;
856 s
->async
->inttrig
= NULL
;
862 mutex_unlock(&devpriv
->mut
);
866 static int usbdux_ao_cmdtest(struct comedi_device
*dev
,
867 struct comedi_subdevice
*s
, struct comedi_cmd
*cmd
)
872 /* Step 1 : check if triggers are trivially valid */
874 err
|= comedi_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_INT
);
876 if (0) { /* (devpriv->high_speed) */
877 /* the sampling rate is set by the coversion rate */
880 /* start a new scan (output at once) with a timer */
883 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
, flags
);
885 if (0) { /* (devpriv->high_speed) */
887 * in usb-2.0 only one conversion it transmitted
893 * all conversion events happen simultaneously with
898 err
|= comedi_check_trigger_src(&cmd
->convert_src
, flags
);
900 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
901 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
906 /* Step 2a : make sure trigger sources are unique */
908 err
|= comedi_check_trigger_is_unique(cmd
->start_src
);
909 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
911 /* Step 2b : and mutually compatible */
916 /* Step 3: check if arguments are trivially valid */
918 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
920 if (cmd
->scan_begin_src
== TRIG_FOLLOW
) /* internal trigger */
921 err
|= comedi_check_trigger_arg_is(&cmd
->scan_begin_arg
, 0);
923 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
924 err
|= comedi_check_trigger_arg_min(&cmd
->scan_begin_arg
,
928 /* not used now, is for later use */
929 if (cmd
->convert_src
== TRIG_TIMER
)
930 err
|= comedi_check_trigger_arg_min(&cmd
->convert_arg
, 125000);
932 err
|= comedi_check_trigger_arg_is(&cmd
->scan_end_arg
,
935 if (cmd
->stop_src
== TRIG_COUNT
)
936 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
938 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
946 static int usbdux_ao_cmd(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
948 struct usbdux_private
*devpriv
= dev
->private;
949 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
952 mutex_lock(&devpriv
->mut
);
954 if (devpriv
->ao_cmd_running
)
957 /* we count in steps of 1ms (125us) */
958 /* 125us mode not used yet */
959 if (0) { /* (devpriv->high_speed) */
961 /* timing of the conversion itself: every 125 us */
962 devpriv
->ao_timer
= cmd
->convert_arg
/ 125000;
965 /* timing of the scan: we get all channels at once */
966 devpriv
->ao_timer
= cmd
->scan_begin_arg
/ 1000000;
967 if (devpriv
->ao_timer
< 1) {
973 devpriv
->ao_counter
= devpriv
->ao_timer
;
975 if (cmd
->start_src
== TRIG_NOW
) {
976 /* enable this acquisition operation */
977 devpriv
->ao_cmd_running
= 1;
978 ret
= usbdux_submit_urbs(dev
, devpriv
->ao_urbs
,
979 devpriv
->n_ao_urbs
, 0);
981 devpriv
->ao_cmd_running
= 0;
982 /* fixme: unlink here?? */
985 s
->async
->inttrig
= NULL
;
988 /* submit the urbs later */
989 /* wait for an internal signal */
990 s
->async
->inttrig
= usbdux_ao_inttrig
;
994 mutex_unlock(&devpriv
->mut
);
999 static int usbdux_dio_insn_config(struct comedi_device
*dev
,
1000 struct comedi_subdevice
*s
,
1001 struct comedi_insn
*insn
,
1006 ret
= comedi_dio_insn_config(dev
, s
, insn
, data
, 0);
1011 * We don't tell the firmware here as it would take 8 frames
1012 * to submit the information. We do it in the insn_bits.
1017 static int usbdux_dio_insn_bits(struct comedi_device
*dev
,
1018 struct comedi_subdevice
*s
,
1019 struct comedi_insn
*insn
,
1022 struct usbdux_private
*devpriv
= dev
->private;
1025 mutex_lock(&devpriv
->mut
);
1027 comedi_dio_update_state(s
, data
);
1029 /* Always update the hardware. See the (*insn_config). */
1030 devpriv
->dux_commands
[1] = s
->io_bits
;
1031 devpriv
->dux_commands
[2] = s
->state
;
1034 * This command also tells the firmware to return
1035 * the digital input lines.
1037 ret
= send_dux_commands(dev
, USBDUX_CMD_DIO_BITS
);
1040 ret
= receive_dux_commands(dev
, USBDUX_CMD_DIO_BITS
);
1044 data
[1] = le16_to_cpu(devpriv
->insn_buf
[1]);
1047 mutex_unlock(&devpriv
->mut
);
1049 return ret
? ret
: insn
->n
;
1052 static int usbdux_counter_read(struct comedi_device
*dev
,
1053 struct comedi_subdevice
*s
,
1054 struct comedi_insn
*insn
,
1057 struct usbdux_private
*devpriv
= dev
->private;
1058 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1062 mutex_lock(&devpriv
->mut
);
1064 for (i
= 0; i
< insn
->n
; i
++) {
1065 ret
= send_dux_commands(dev
, USBDUX_CMD_TIMER_RD
);
1067 goto counter_read_exit
;
1068 ret
= receive_dux_commands(dev
, USBDUX_CMD_TIMER_RD
);
1070 goto counter_read_exit
;
1072 data
[i
] = le16_to_cpu(devpriv
->insn_buf
[chan
+ 1]);
1076 mutex_unlock(&devpriv
->mut
);
1078 return ret
? ret
: insn
->n
;
1081 static int usbdux_counter_write(struct comedi_device
*dev
,
1082 struct comedi_subdevice
*s
,
1083 struct comedi_insn
*insn
,
1086 struct usbdux_private
*devpriv
= dev
->private;
1087 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1088 __le16
*p
= (__le16
*)&devpriv
->dux_commands
[2];
1092 mutex_lock(&devpriv
->mut
);
1094 devpriv
->dux_commands
[1] = chan
;
1096 for (i
= 0; i
< insn
->n
; i
++) {
1097 *p
= cpu_to_le16(data
[i
]);
1099 ret
= send_dux_commands(dev
, USBDUX_CMD_TIMER_WR
);
1104 mutex_unlock(&devpriv
->mut
);
1106 return ret
? ret
: insn
->n
;
1109 static int usbdux_counter_config(struct comedi_device
*dev
,
1110 struct comedi_subdevice
*s
,
1111 struct comedi_insn
*insn
, unsigned int *data
)
1113 /* nothing to do so far */
1117 static void usbduxsub_unlink_pwm_urbs(struct comedi_device
*dev
)
1119 struct usbdux_private
*devpriv
= dev
->private;
1121 usb_kill_urb(devpriv
->pwm_urb
);
1124 static void usbdux_pwm_stop(struct comedi_device
*dev
, int do_unlink
)
1126 struct usbdux_private
*devpriv
= dev
->private;
1129 usbduxsub_unlink_pwm_urbs(dev
);
1131 devpriv
->pwm_cmd_running
= 0;
1134 static int usbdux_pwm_cancel(struct comedi_device
*dev
,
1135 struct comedi_subdevice
*s
)
1137 struct usbdux_private
*devpriv
= dev
->private;
1140 mutex_lock(&devpriv
->mut
);
1141 /* unlink only if it is really running */
1142 usbdux_pwm_stop(dev
, devpriv
->pwm_cmd_running
);
1143 ret
= send_dux_commands(dev
, USBDUX_CMD_PWM_OFF
);
1144 mutex_unlock(&devpriv
->mut
);
1149 static void usbduxsub_pwm_irq(struct urb
*urb
)
1151 struct comedi_device
*dev
= urb
->context
;
1152 struct usbdux_private
*devpriv
= dev
->private;
1155 switch (urb
->status
) {
1165 * after an unlink command, unplug, ... etc
1166 * no unlink needed here. Already shutting down.
1168 if (devpriv
->pwm_cmd_running
)
1169 usbdux_pwm_stop(dev
, 0);
1175 if (devpriv
->pwm_cmd_running
) {
1176 dev_err(dev
->class_dev
,
1177 "Non-zero urb status received in pwm intr context: %d\n",
1179 usbdux_pwm_stop(dev
, 0);
1184 /* are we actually running? */
1185 if (!devpriv
->pwm_cmd_running
)
1188 urb
->transfer_buffer_length
= devpriv
->pwm_buf_sz
;
1189 urb
->dev
= comedi_to_usb_dev(dev
);
1191 if (devpriv
->pwm_cmd_running
) {
1192 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
1194 dev_err(dev
->class_dev
,
1195 "pwm urb resubm failed in int-cont. ret=%d",
1197 if (ret
== -EL2NSYNC
)
1198 dev_err(dev
->class_dev
,
1199 "buggy USB host controller or bug in IRQ handling!\n");
1201 /* don't do an unlink here */
1202 usbdux_pwm_stop(dev
, 0);
1207 static int usbduxsub_submit_pwm_urbs(struct comedi_device
*dev
)
1209 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
1210 struct usbdux_private
*devpriv
= dev
->private;
1211 struct urb
*urb
= devpriv
->pwm_urb
;
1213 /* in case of a resubmission after an unlink... */
1214 usb_fill_bulk_urb(urb
, usb
, usb_sndbulkpipe(usb
, 4),
1215 urb
->transfer_buffer
,
1216 devpriv
->pwm_buf_sz
,
1220 return usb_submit_urb(urb
, GFP_ATOMIC
);
1223 static int usbdux_pwm_period(struct comedi_device
*dev
,
1224 struct comedi_subdevice
*s
,
1225 unsigned int period
)
1227 struct usbdux_private
*devpriv
= dev
->private;
1230 if (period
< MIN_PWM_PERIOD
)
1233 fx2delay
= (period
/ (6 * 512 * 1000 / 33)) - 6;
1237 devpriv
->pwm_delay
= fx2delay
;
1238 devpriv
->pwm_period
= period
;
1243 static int usbdux_pwm_start(struct comedi_device
*dev
,
1244 struct comedi_subdevice
*s
)
1246 struct usbdux_private
*devpriv
= dev
->private;
1249 mutex_lock(&devpriv
->mut
);
1251 if (devpriv
->pwm_cmd_running
)
1252 goto pwm_start_exit
;
1254 devpriv
->dux_commands
[1] = devpriv
->pwm_delay
;
1255 ret
= send_dux_commands(dev
, USBDUX_CMD_PWM_ON
);
1257 goto pwm_start_exit
;
1259 /* initialise the buffer */
1260 memset(devpriv
->pwm_urb
->transfer_buffer
, 0, devpriv
->pwm_buf_sz
);
1262 devpriv
->pwm_cmd_running
= 1;
1263 ret
= usbduxsub_submit_pwm_urbs(dev
);
1265 devpriv
->pwm_cmd_running
= 0;
1268 mutex_unlock(&devpriv
->mut
);
1273 static void usbdux_pwm_pattern(struct comedi_device
*dev
,
1274 struct comedi_subdevice
*s
,
1279 struct usbdux_private
*devpriv
= dev
->private;
1280 char pwm_mask
= (1 << chan
); /* DIO bit for the PWM data */
1281 char sgn_mask
= (16 << chan
); /* DIO bit for the sign */
1282 char *buf
= (char *)(devpriv
->pwm_urb
->transfer_buffer
);
1283 int szbuf
= devpriv
->pwm_buf_sz
;
1286 for (i
= 0; i
< szbuf
; i
++) {
1300 static int usbdux_pwm_write(struct comedi_device
*dev
,
1301 struct comedi_subdevice
*s
,
1302 struct comedi_insn
*insn
,
1305 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1308 * It doesn't make sense to support more than one value here
1309 * because it would just overwrite the PWM buffer.
1315 * The sign is set via a special INSN only, this gives us 8 bits
1316 * for normal operation, sign is 0 by default.
1318 usbdux_pwm_pattern(dev
, s
, chan
, data
[0], 0);
1323 static int usbdux_pwm_config(struct comedi_device
*dev
,
1324 struct comedi_subdevice
*s
,
1325 struct comedi_insn
*insn
,
1328 struct usbdux_private
*devpriv
= dev
->private;
1329 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1332 case INSN_CONFIG_ARM
:
1334 * if not zero the PWM is limited to a certain time which is
1335 * not supported here
1339 return usbdux_pwm_start(dev
, s
);
1340 case INSN_CONFIG_DISARM
:
1341 return usbdux_pwm_cancel(dev
, s
);
1342 case INSN_CONFIG_GET_PWM_STATUS
:
1343 data
[1] = devpriv
->pwm_cmd_running
;
1345 case INSN_CONFIG_PWM_SET_PERIOD
:
1346 return usbdux_pwm_period(dev
, s
, data
[1]);
1347 case INSN_CONFIG_PWM_GET_PERIOD
:
1348 data
[1] = devpriv
->pwm_period
;
1350 case INSN_CONFIG_PWM_SET_H_BRIDGE
:
1353 * data[2] = sign (for a relay)
1355 usbdux_pwm_pattern(dev
, s
, chan
, data
[1], (data
[2] != 0));
1357 case INSN_CONFIG_PWM_GET_H_BRIDGE
:
1358 /* values are not kept in this driver, nothing to return here */
1364 static int usbdux_firmware_upload(struct comedi_device
*dev
,
1365 const u8
*data
, size_t size
,
1366 unsigned long context
)
1368 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
1376 if (size
> USBDUX_FIRMWARE_MAX_LEN
) {
1377 dev_err(dev
->class_dev
,
1378 "usbdux firmware binary it too large for FX2.\n");
1382 /* we generate a local buffer for the firmware */
1383 buf
= kmemdup(data
, size
, GFP_KERNEL
);
1387 /* we need a malloc'ed buffer for usb_control_msg() */
1388 tmp
= kmalloc(1, GFP_KERNEL
);
1394 /* stop the current firmware on the device */
1395 *tmp
= 1; /* 7f92 to one */
1396 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
1397 USBDUX_FIRMWARE_CMD
,
1399 USBDUX_CPU_CS
, 0x0000,
1403 dev_err(dev
->class_dev
, "can not stop firmware\n");
1407 /* upload the new firmware to the device */
1408 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
1409 USBDUX_FIRMWARE_CMD
,
1415 dev_err(dev
->class_dev
, "firmware upload failed\n");
1419 /* start the new firmware on the device */
1420 *tmp
= 0; /* 7f92 to zero */
1421 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
1422 USBDUX_FIRMWARE_CMD
,
1424 USBDUX_CPU_CS
, 0x0000,
1428 dev_err(dev
->class_dev
, "can not start firmware\n");
1436 static int usbdux_alloc_usb_buffers(struct comedi_device
*dev
)
1438 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
1439 struct usbdux_private
*devpriv
= dev
->private;
1443 devpriv
->dux_commands
= kzalloc(SIZEOFDUXBUFFER
, GFP_KERNEL
);
1444 devpriv
->in_buf
= kzalloc(SIZEINBUF
, GFP_KERNEL
);
1445 devpriv
->insn_buf
= kzalloc(SIZEINSNBUF
, GFP_KERNEL
);
1446 devpriv
->ai_urbs
= kcalloc(devpriv
->n_ai_urbs
, sizeof(void *),
1448 devpriv
->ao_urbs
= kcalloc(devpriv
->n_ao_urbs
, sizeof(void *),
1450 if (!devpriv
->dux_commands
|| !devpriv
->in_buf
|| !devpriv
->insn_buf
||
1451 !devpriv
->ai_urbs
|| !devpriv
->ao_urbs
)
1454 for (i
= 0; i
< devpriv
->n_ai_urbs
; i
++) {
1455 /* one frame: 1ms */
1456 urb
= usb_alloc_urb(1, GFP_KERNEL
);
1459 devpriv
->ai_urbs
[i
] = urb
;
1463 urb
->pipe
= usb_rcvisocpipe(usb
, 6);
1464 urb
->transfer_flags
= URB_ISO_ASAP
;
1465 urb
->transfer_buffer
= kzalloc(SIZEINBUF
, GFP_KERNEL
);
1466 if (!urb
->transfer_buffer
)
1469 urb
->complete
= usbduxsub_ai_isoc_irq
;
1470 urb
->number_of_packets
= 1;
1471 urb
->transfer_buffer_length
= SIZEINBUF
;
1472 urb
->iso_frame_desc
[0].offset
= 0;
1473 urb
->iso_frame_desc
[0].length
= SIZEINBUF
;
1476 for (i
= 0; i
< devpriv
->n_ao_urbs
; i
++) {
1477 /* one frame: 1ms */
1478 urb
= usb_alloc_urb(1, GFP_KERNEL
);
1481 devpriv
->ao_urbs
[i
] = urb
;
1485 urb
->pipe
= usb_sndisocpipe(usb
, 2);
1486 urb
->transfer_flags
= URB_ISO_ASAP
;
1487 urb
->transfer_buffer
= kzalloc(SIZEOUTBUF
, GFP_KERNEL
);
1488 if (!urb
->transfer_buffer
)
1491 urb
->complete
= usbduxsub_ao_isoc_irq
;
1492 urb
->number_of_packets
= 1;
1493 urb
->transfer_buffer_length
= SIZEOUTBUF
;
1494 urb
->iso_frame_desc
[0].offset
= 0;
1495 urb
->iso_frame_desc
[0].length
= SIZEOUTBUF
;
1496 if (devpriv
->high_speed
)
1497 urb
->interval
= 8; /* uframes */
1499 urb
->interval
= 1; /* frames */
1503 if (devpriv
->pwm_buf_sz
) {
1504 urb
= usb_alloc_urb(0, GFP_KERNEL
);
1507 devpriv
->pwm_urb
= urb
;
1509 /* max bulk ep size in high speed */
1510 urb
->transfer_buffer
= kzalloc(devpriv
->pwm_buf_sz
,
1512 if (!urb
->transfer_buffer
)
1519 static void usbdux_free_usb_buffers(struct comedi_device
*dev
)
1521 struct usbdux_private
*devpriv
= dev
->private;
1525 urb
= devpriv
->pwm_urb
;
1527 kfree(urb
->transfer_buffer
);
1530 if (devpriv
->ao_urbs
) {
1531 for (i
= 0; i
< devpriv
->n_ao_urbs
; i
++) {
1532 urb
= devpriv
->ao_urbs
[i
];
1534 kfree(urb
->transfer_buffer
);
1538 kfree(devpriv
->ao_urbs
);
1540 if (devpriv
->ai_urbs
) {
1541 for (i
= 0; i
< devpriv
->n_ai_urbs
; i
++) {
1542 urb
= devpriv
->ai_urbs
[i
];
1544 kfree(urb
->transfer_buffer
);
1548 kfree(devpriv
->ai_urbs
);
1550 kfree(devpriv
->insn_buf
);
1551 kfree(devpriv
->in_buf
);
1552 kfree(devpriv
->dux_commands
);
1555 static int usbdux_auto_attach(struct comedi_device
*dev
,
1556 unsigned long context_unused
)
1558 struct usb_interface
*intf
= comedi_to_usb_interface(dev
);
1559 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
1560 struct usbdux_private
*devpriv
;
1561 struct comedi_subdevice
*s
;
1564 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
1568 mutex_init(&devpriv
->mut
);
1570 usb_set_intfdata(intf
, devpriv
);
1572 devpriv
->high_speed
= (usb
->speed
== USB_SPEED_HIGH
);
1573 if (devpriv
->high_speed
) {
1574 devpriv
->n_ai_urbs
= NUMOFINBUFFERSHIGH
;
1575 devpriv
->n_ao_urbs
= NUMOFOUTBUFFERSHIGH
;
1576 devpriv
->pwm_buf_sz
= 512;
1578 devpriv
->n_ai_urbs
= NUMOFINBUFFERSFULL
;
1579 devpriv
->n_ao_urbs
= NUMOFOUTBUFFERSFULL
;
1582 ret
= usbdux_alloc_usb_buffers(dev
);
1586 /* setting to alternate setting 3: enabling iso ep and bulk ep. */
1587 ret
= usb_set_interface(usb
, intf
->altsetting
->desc
.bInterfaceNumber
,
1590 dev_err(dev
->class_dev
,
1591 "could not set alternate setting 3 in high speed\n");
1595 ret
= comedi_load_firmware(dev
, &usb
->dev
, USBDUX_FIRMWARE
,
1596 usbdux_firmware_upload
, 0);
1600 ret
= comedi_alloc_subdevices(dev
, (devpriv
->high_speed
) ? 5 : 4);
1604 /* Analog Input subdevice */
1605 s
= &dev
->subdevices
[0];
1606 dev
->read_subdev
= s
;
1607 s
->type
= COMEDI_SUBD_AI
;
1608 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
| SDF_CMD_READ
;
1610 s
->maxdata
= 0x0fff;
1611 s
->len_chanlist
= 8;
1612 s
->range_table
= &range_usbdux_ai_range
;
1613 s
->insn_read
= usbdux_ai_insn_read
;
1614 s
->do_cmdtest
= usbdux_ai_cmdtest
;
1615 s
->do_cmd
= usbdux_ai_cmd
;
1616 s
->cancel
= usbdux_ai_cancel
;
1618 /* Analog Output subdevice */
1619 s
= &dev
->subdevices
[1];
1620 dev
->write_subdev
= s
;
1621 s
->type
= COMEDI_SUBD_AO
;
1622 s
->subdev_flags
= SDF_WRITABLE
| SDF_GROUND
| SDF_CMD_WRITE
;
1624 s
->maxdata
= 0x0fff;
1625 s
->len_chanlist
= s
->n_chan
;
1626 s
->range_table
= &range_usbdux_ao_range
;
1627 s
->do_cmdtest
= usbdux_ao_cmdtest
;
1628 s
->do_cmd
= usbdux_ao_cmd
;
1629 s
->cancel
= usbdux_ao_cancel
;
1630 s
->insn_read
= usbdux_ao_insn_read
;
1631 s
->insn_write
= usbdux_ao_insn_write
;
1633 ret
= comedi_alloc_subdev_readback(s
);
1637 /* Digital I/O subdevice */
1638 s
= &dev
->subdevices
[2];
1639 s
->type
= COMEDI_SUBD_DIO
;
1640 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
1643 s
->range_table
= &range_digital
;
1644 s
->insn_bits
= usbdux_dio_insn_bits
;
1645 s
->insn_config
= usbdux_dio_insn_config
;
1647 /* Counter subdevice */
1648 s
= &dev
->subdevices
[3];
1649 s
->type
= COMEDI_SUBD_COUNTER
;
1650 s
->subdev_flags
= SDF_WRITABLE
| SDF_READABLE
;
1652 s
->maxdata
= 0xffff;
1653 s
->insn_read
= usbdux_counter_read
;
1654 s
->insn_write
= usbdux_counter_write
;
1655 s
->insn_config
= usbdux_counter_config
;
1657 if (devpriv
->high_speed
) {
1659 s
= &dev
->subdevices
[4];
1660 s
->type
= COMEDI_SUBD_PWM
;
1661 s
->subdev_flags
= SDF_WRITABLE
| SDF_PWM_HBRIDGE
;
1663 s
->maxdata
= devpriv
->pwm_buf_sz
;
1664 s
->insn_write
= usbdux_pwm_write
;
1665 s
->insn_config
= usbdux_pwm_config
;
1667 usbdux_pwm_period(dev
, s
, PWM_DEFAULT_PERIOD
);
1673 static void usbdux_detach(struct comedi_device
*dev
)
1675 struct usb_interface
*intf
= comedi_to_usb_interface(dev
);
1676 struct usbdux_private
*devpriv
= dev
->private;
1678 usb_set_intfdata(intf
, NULL
);
1683 mutex_lock(&devpriv
->mut
);
1685 /* force unlink all urbs */
1686 usbdux_pwm_stop(dev
, 1);
1687 usbdux_ao_stop(dev
, 1);
1688 usbdux_ai_stop(dev
, 1);
1690 usbdux_free_usb_buffers(dev
);
1692 mutex_unlock(&devpriv
->mut
);
1694 mutex_destroy(&devpriv
->mut
);
1697 static struct comedi_driver usbdux_driver
= {
1698 .driver_name
= "usbdux",
1699 .module
= THIS_MODULE
,
1700 .auto_attach
= usbdux_auto_attach
,
1701 .detach
= usbdux_detach
,
1704 static int usbdux_usb_probe(struct usb_interface
*intf
,
1705 const struct usb_device_id
*id
)
1707 return comedi_usb_auto_config(intf
, &usbdux_driver
, 0);
1710 static const struct usb_device_id usbdux_usb_table
[] = {
1711 { USB_DEVICE(0x13d8, 0x0001) },
1712 { USB_DEVICE(0x13d8, 0x0002) },
1715 MODULE_DEVICE_TABLE(usb
, usbdux_usb_table
);
1717 static struct usb_driver usbdux_usb_driver
= {
1719 .probe
= usbdux_usb_probe
,
1720 .disconnect
= comedi_usb_auto_unconfig
,
1721 .id_table
= usbdux_usb_table
,
1723 module_comedi_usb_driver(usbdux_driver
, usbdux_usb_driver
);
1725 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1726 MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com");
1727 MODULE_LICENSE("GPL");
1728 MODULE_FIRMWARE(USBDUX_FIRMWARE
);