1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2004-2019 Bernd Porr, mail@berndporr.me.uk
8 * Description: University of Stirling USB DAQ & INCITE Technology Limited
9 * Devices: [ITL] USB-DUX-FAST (usbduxfast)
10 * Author: Bernd Porr <mail@berndporr.me.uk>
11 * Updated: 16 Nov 2019
16 * I must give credit here to Chris Baugher who
17 * wrote the driver for AT-MIO-16d. I used some parts of this
18 * driver. I also must give credits to David Brownell
19 * who supported me with the USB development.
25 * 1.0: Fixed a rounding error in usbduxfast_ai_cmdtest
26 * 0.9: Dropping the first data packet which seems to be from the last transfer.
27 * Buffer overflows in the FX2 are handed over to comedi.
28 * 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
29 * Added insn command basically for testing. Sample rate is
31 * 0.99: Ian Abbott pointed out a bug which has been corrected. Thanks!
32 * 0.99a: added external trigger.
33 * 1.00: added firmware kernel request to the driver which fixed
34 * udev coldplug problem
37 #include <linux/kernel.h>
38 #include <linux/module.h>
39 #include <linux/slab.h>
40 #include <linux/input.h>
41 #include <linux/fcntl.h>
42 #include <linux/compiler.h>
43 #include "../comedi_usb.h"
46 * timeout for the USB-transfer
51 * constants for "firmware" upload and download
53 #define FIRMWARE "usbduxfast_firmware.bin"
54 #define FIRMWARE_MAX_LEN 0x2000
55 #define USBDUXFASTSUB_FIRMWARE 0xA0
56 #define VENDOR_DIR_IN 0xC0
57 #define VENDOR_DIR_OUT 0x40
60 * internal addresses of the 8051 processor
62 #define USBDUXFASTSUB_CPUCS 0xE600
65 * max length of the transfer-buffer for software upload
70 * input endpoint number
75 * endpoint for the A/D channellist: bulk OUT
77 #define CHANNELLISTEP 4
82 #define NUMCHANNELS 32
85 * size of the waveform descriptor
90 * size of one A/D value
92 #define SIZEADIN (sizeof(s16))
95 * size of the input-buffer IN BYTES
102 #define SIZEINSNBUF 512
105 * size of the buffer for the dux commands in bytes
107 #define SIZEOFDUXBUF 256
110 * number of in-URBs which receive the data: min=5
112 #define NUMOFINBUFFERSHIGH 10
115 * min delay steps for more than one channel
116 * basically when the mux gives up ;-)
118 * steps at 30MHz in the FX2
120 #define MIN_SAMPLING_PERIOD 9
123 * max number of 1/30MHz delay steps
125 #define MAX_SAMPLING_PERIOD 500
128 * number of received packets to ignore before we start handing data
129 * over to comedi, it's quad buffering and we have to ignore 4 packets
131 #define PACKETS_TO_IGNORE 4
136 static const struct comedi_lrange range_usbduxfast_ai_range
= {
144 * private structure of one subdevice
146 * this is the structure which holds all the data of this driver
147 * one sub device just now: A/D
149 struct usbduxfast_private
{
150 struct urb
*urb
; /* BULK-transfer handling: urb */
153 short int ai_cmd_running
; /* asynchronous command is running */
154 int ignore
; /* counter which ignores the first buffers */
159 * bulk transfers to usbduxfast
161 #define SENDADCOMMANDS 0
162 #define SENDINITEP6 1
164 static int usbduxfast_send_cmd(struct comedi_device
*dev
, int cmd_type
)
166 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
167 struct usbduxfast_private
*devpriv
= dev
->private;
171 devpriv
->duxbuf
[0] = cmd_type
;
173 ret
= usb_bulk_msg(usb
, usb_sndbulkpipe(usb
, CHANNELLISTEP
),
174 devpriv
->duxbuf
, SIZEOFDUXBUF
,
177 dev_err(dev
->class_dev
,
178 "could not transmit command to the usb-device, err=%d\n",
183 static void usbduxfast_cmd_data(struct comedi_device
*dev
, int index
,
184 u8 len
, u8 op
, u8 out
, u8 log
)
186 struct usbduxfast_private
*devpriv
= dev
->private;
188 /* Set the GPIF bytes, the first byte is the command byte */
189 devpriv
->duxbuf
[1 + 0x00 + index
] = len
;
190 devpriv
->duxbuf
[1 + 0x08 + index
] = op
;
191 devpriv
->duxbuf
[1 + 0x10 + index
] = out
;
192 devpriv
->duxbuf
[1 + 0x18 + index
] = log
;
195 static int usbduxfast_ai_stop(struct comedi_device
*dev
, int do_unlink
)
197 struct usbduxfast_private
*devpriv
= dev
->private;
200 devpriv
->ai_cmd_running
= 0;
202 if (do_unlink
&& devpriv
->urb
) {
203 /* kill the running transfer */
204 usb_kill_urb(devpriv
->urb
);
210 static int usbduxfast_ai_cancel(struct comedi_device
*dev
,
211 struct comedi_subdevice
*s
)
213 struct usbduxfast_private
*devpriv
= dev
->private;
216 mutex_lock(&devpriv
->mut
);
217 ret
= usbduxfast_ai_stop(dev
, 1);
218 mutex_unlock(&devpriv
->mut
);
223 static void usbduxfast_ai_handle_urb(struct comedi_device
*dev
,
224 struct comedi_subdevice
*s
,
227 struct usbduxfast_private
*devpriv
= dev
->private;
228 struct comedi_async
*async
= s
->async
;
229 struct comedi_cmd
*cmd
= &async
->cmd
;
232 if (devpriv
->ignore
) {
235 unsigned int nsamples
;
237 nsamples
= comedi_bytes_to_samples(s
, urb
->actual_length
);
238 nsamples
= comedi_nsamples_left(s
, nsamples
);
239 comedi_buf_write_samples(s
, urb
->transfer_buffer
, nsamples
);
241 if (cmd
->stop_src
== TRIG_COUNT
&&
242 async
->scans_done
>= cmd
->stop_arg
)
243 async
->events
|= COMEDI_CB_EOA
;
246 /* if command is still running, resubmit urb for BULK transfer */
247 if (!(async
->events
& COMEDI_CB_CANCEL_MASK
)) {
248 urb
->dev
= comedi_to_usb_dev(dev
);
250 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
252 dev_err(dev
->class_dev
, "urb resubm failed: %d", ret
);
253 async
->events
|= COMEDI_CB_ERROR
;
258 static void usbduxfast_ai_interrupt(struct urb
*urb
)
260 struct comedi_device
*dev
= urb
->context
;
261 struct comedi_subdevice
*s
= dev
->read_subdev
;
262 struct comedi_async
*async
= s
->async
;
263 struct usbduxfast_private
*devpriv
= dev
->private;
265 /* exit if not running a command, do not resubmit urb */
266 if (!devpriv
->ai_cmd_running
)
269 switch (urb
->status
) {
271 usbduxfast_ai_handle_urb(dev
, s
, urb
);
278 /* after an unlink command, unplug, ... etc */
279 async
->events
|= COMEDI_CB_ERROR
;
284 dev_err(dev
->class_dev
,
285 "non-zero urb status received in ai intr context: %d\n",
287 async
->events
|= COMEDI_CB_ERROR
;
292 * comedi_handle_events() cannot be used in this driver. The (*cancel)
293 * operation would unlink the urb.
295 if (async
->events
& COMEDI_CB_CANCEL_MASK
)
296 usbduxfast_ai_stop(dev
, 0);
298 comedi_event(dev
, s
);
301 static int usbduxfast_submit_urb(struct comedi_device
*dev
)
303 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
304 struct usbduxfast_private
*devpriv
= dev
->private;
307 usb_fill_bulk_urb(devpriv
->urb
, usb
, usb_rcvbulkpipe(usb
, BULKINEP
),
308 devpriv
->inbuf
, SIZEINBUF
,
309 usbduxfast_ai_interrupt
, dev
);
311 ret
= usb_submit_urb(devpriv
->urb
, GFP_ATOMIC
);
313 dev_err(dev
->class_dev
, "usb_submit_urb error %d\n", ret
);
319 static int usbduxfast_ai_check_chanlist(struct comedi_device
*dev
,
320 struct comedi_subdevice
*s
,
321 struct comedi_cmd
*cmd
)
323 unsigned int gain0
= CR_RANGE(cmd
->chanlist
[0]);
326 if (cmd
->chanlist_len
> 3 && cmd
->chanlist_len
!= 16) {
327 dev_err(dev
->class_dev
, "unsupported combination of channels\n");
331 for (i
= 0; i
< cmd
->chanlist_len
; ++i
) {
332 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
333 unsigned int gain
= CR_RANGE(cmd
->chanlist
[i
]);
336 dev_err(dev
->class_dev
,
337 "channels are not consecutive\n");
340 if (gain
!= gain0
&& cmd
->chanlist_len
> 3) {
341 dev_err(dev
->class_dev
,
342 "gain must be the same for all channels\n");
349 static int usbduxfast_ai_cmdtest(struct comedi_device
*dev
,
350 struct comedi_subdevice
*s
,
351 struct comedi_cmd
*cmd
)
358 /* Step 1 : check if triggers are trivially valid */
360 err
|= comedi_check_trigger_src(&cmd
->start_src
,
361 TRIG_NOW
| TRIG_EXT
| TRIG_INT
);
362 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
, TRIG_FOLLOW
);
363 err
|= comedi_check_trigger_src(&cmd
->convert_src
, TRIG_TIMER
);
364 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
365 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
370 /* Step 2a : make sure trigger sources are unique */
372 err
|= comedi_check_trigger_is_unique(cmd
->start_src
);
373 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
375 /* Step 2b : and mutually compatible */
380 /* Step 3: check if arguments are trivially valid */
382 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
384 if (!cmd
->chanlist_len
)
387 /* external start trigger is only valid for 1 or 16 channels */
388 if (cmd
->start_src
== TRIG_EXT
&&
389 cmd
->chanlist_len
!= 1 && cmd
->chanlist_len
!= 16)
392 err
|= comedi_check_trigger_arg_is(&cmd
->scan_end_arg
,
396 * Validate the conversion timing:
397 * for 1 channel the timing in 30MHz "steps" is:
398 * steps <= MAX_SAMPLING_PERIOD
399 * for all other chanlist_len it is:
400 * MIN_SAMPLING_PERIOD <= steps <= MAX_SAMPLING_PERIOD
402 steps
= (cmd
->convert_arg
* 30) / 1000;
403 if (cmd
->chanlist_len
!= 1)
404 err2
|= comedi_check_trigger_arg_min(&steps
,
405 MIN_SAMPLING_PERIOD
);
407 err2
|= comedi_check_trigger_arg_min(&steps
, 1);
408 err2
|= comedi_check_trigger_arg_max(&steps
, MAX_SAMPLING_PERIOD
);
411 arg
= (steps
* 1000) / 30;
412 err
|= comedi_check_trigger_arg_is(&cmd
->convert_arg
, arg
);
415 if (cmd
->stop_src
== TRIG_COUNT
)
416 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
418 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
423 /* Step 4: fix up any arguments */
425 /* Step 5: check channel list if it exists */
426 if (cmd
->chanlist
&& cmd
->chanlist_len
> 0)
427 err
|= usbduxfast_ai_check_chanlist(dev
, s
, cmd
);
434 static int usbduxfast_ai_inttrig(struct comedi_device
*dev
,
435 struct comedi_subdevice
*s
,
436 unsigned int trig_num
)
438 struct usbduxfast_private
*devpriv
= dev
->private;
439 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
442 if (trig_num
!= cmd
->start_arg
)
445 mutex_lock(&devpriv
->mut
);
447 if (!devpriv
->ai_cmd_running
) {
448 devpriv
->ai_cmd_running
= 1;
449 ret
= usbduxfast_submit_urb(dev
);
451 dev_err(dev
->class_dev
, "urbSubmit: err=%d\n", ret
);
452 devpriv
->ai_cmd_running
= 0;
453 mutex_unlock(&devpriv
->mut
);
456 s
->async
->inttrig
= NULL
;
458 dev_err(dev
->class_dev
, "ai is already running\n");
460 mutex_unlock(&devpriv
->mut
);
464 static int usbduxfast_ai_cmd(struct comedi_device
*dev
,
465 struct comedi_subdevice
*s
)
467 struct usbduxfast_private
*devpriv
= dev
->private;
468 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
469 unsigned int rngmask
= 0xff;
471 long steps
, steps_tmp
;
473 mutex_lock(&devpriv
->mut
);
474 if (devpriv
->ai_cmd_running
) {
480 * ignore the first buffers from the device if there
481 * is an error condition
483 devpriv
->ignore
= PACKETS_TO_IGNORE
;
485 steps
= (cmd
->convert_arg
* 30) / 1000;
487 switch (cmd
->chanlist_len
) {
493 if (CR_RANGE(cmd
->chanlist
[0]) > 0)
494 rngmask
= 0xff - 0x04;
499 * for external trigger: looping in this state until
500 * the RDY0 pin becomes zero
503 /* we loop here until ready has been set */
504 if (cmd
->start_src
== TRIG_EXT
) {
505 /* branch back to state 0 */
506 /* deceision state w/o data */
508 usbduxfast_cmd_data(dev
, 0, 0x01, 0x01, rngmask
, 0x00);
509 } else { /* we just proceed to state 1 */
510 usbduxfast_cmd_data(dev
, 0, 0x01, 0x00, rngmask
, 0x00);
513 if (steps
< MIN_SAMPLING_PERIOD
) {
514 /* for fast single channel aqu without mux */
517 * we just stay here at state 1 and rexecute
518 * the same state this gives us 30MHz sampling
522 /* branch back to state 1 */
523 /* deceision state with data */
525 usbduxfast_cmd_data(dev
, 1,
526 0x89, 0x03, rngmask
, 0xff);
529 * we loop through two states: data and delay
534 usbduxfast_cmd_data(dev
, 1, steps
- 1,
535 0x02, rngmask
, 0x00);
537 /* branch back to state 1 */
538 /* deceision state w/o data */
540 usbduxfast_cmd_data(dev
, 2,
541 0x09, 0x01, rngmask
, 0xff);
545 * we loop through 3 states: 2x delay and 1x data
546 * this gives a min sampling rate of 60kHz
549 /* we have 1 state with duration 1 */
552 /* do the first part of the delay */
553 usbduxfast_cmd_data(dev
, 1,
554 steps
/ 2, 0x00, rngmask
, 0x00);
556 /* and the second part */
557 usbduxfast_cmd_data(dev
, 2, steps
- steps
/ 2,
558 0x00, rngmask
, 0x00);
560 /* get the data and branch back */
562 /* branch back to state 1 */
563 /* deceision state w data */
565 usbduxfast_cmd_data(dev
, 3,
566 0x09, 0x03, rngmask
, 0xff);
573 * commit data to the FIFO
576 if (CR_RANGE(cmd
->chanlist
[0]) > 0)
577 rngmask
= 0xff - 0x04;
582 usbduxfast_cmd_data(dev
, 0, 0x01, 0x02, rngmask
, 0x00);
584 /* we have 1 state with duration 1: state 0 */
585 steps_tmp
= steps
- 1;
587 if (CR_RANGE(cmd
->chanlist
[1]) > 0)
588 rngmask
= 0xff - 0x04;
592 /* do the first part of the delay */
594 usbduxfast_cmd_data(dev
, 1, steps_tmp
/ 2,
595 0x00, 0xfe & rngmask
, 0x00);
597 /* and the second part */
598 usbduxfast_cmd_data(dev
, 2, steps_tmp
- steps_tmp
/ 2,
599 0x00, rngmask
, 0x00);
602 usbduxfast_cmd_data(dev
, 3, 0x01, 0x02, rngmask
, 0x00);
605 * we have 2 states with duration 1: step 6 and
608 steps_tmp
= steps
- 2;
610 if (CR_RANGE(cmd
->chanlist
[0]) > 0)
611 rngmask
= 0xff - 0x04;
615 /* do the first part of the delay */
617 usbduxfast_cmd_data(dev
, 4, steps_tmp
/ 2,
618 0x00, (0xff - 0x02) & rngmask
, 0x00);
620 /* and the second part */
621 usbduxfast_cmd_data(dev
, 5, steps_tmp
- steps_tmp
/ 2,
622 0x00, rngmask
, 0x00);
624 usbduxfast_cmd_data(dev
, 6, 0x01, 0x00, rngmask
, 0x00);
631 for (j
= 0; j
< 1; j
++) {
634 if (CR_RANGE(cmd
->chanlist
[j
]) > 0)
635 rngmask
= 0xff - 0x04;
639 * commit data to the FIFO and do the first part
644 usbduxfast_cmd_data(dev
, index
, steps
/ 2,
645 0x02, rngmask
, 0x00);
647 if (CR_RANGE(cmd
->chanlist
[j
+ 1]) > 0)
648 rngmask
= 0xff - 0x04;
652 /* do the second part of the delay */
655 usbduxfast_cmd_data(dev
, index
+ 1, steps
- steps
/ 2,
656 0x00, 0xfe & rngmask
, 0x00);
659 /* 2 steps with duration 1: the idele step and step 6: */
660 steps_tmp
= steps
- 2;
662 /* commit data to the FIFO and do the first part of the delay */
664 usbduxfast_cmd_data(dev
, 4, steps_tmp
/ 2,
665 0x02, rngmask
, 0x00);
667 if (CR_RANGE(cmd
->chanlist
[0]) > 0)
668 rngmask
= 0xff - 0x04;
672 /* do the second part of the delay */
675 usbduxfast_cmd_data(dev
, 5, steps_tmp
- steps_tmp
/ 2,
676 0x00, (0xff - 0x02) & rngmask
, 0x00);
678 usbduxfast_cmd_data(dev
, 6, 0x01, 0x00, rngmask
, 0x00);
682 if (CR_RANGE(cmd
->chanlist
[0]) > 0)
683 rngmask
= 0xff - 0x04;
687 if (cmd
->start_src
== TRIG_EXT
) {
689 * we loop here until ready has been set
692 /* branch back to state 0 */
693 /* deceision state w/o data */
696 usbduxfast_cmd_data(dev
, 0, 0x01, 0x01,
697 (0xff - 0x02) & rngmask
, 0x00);
700 * we just proceed to state 1
703 /* 30us reset pulse */
705 usbduxfast_cmd_data(dev
, 0, 0xff, 0x00,
706 (0xff - 0x02) & rngmask
, 0x00);
709 /* commit data to the FIFO */
711 usbduxfast_cmd_data(dev
, 1, 0x01, 0x02, rngmask
, 0x00);
713 /* we have 2 states with duration 1 */
716 /* do the first part of the delay */
717 usbduxfast_cmd_data(dev
, 2, steps
/ 2,
718 0x00, 0xfe & rngmask
, 0x00);
720 /* and the second part */
721 usbduxfast_cmd_data(dev
, 3, steps
- steps
/ 2,
722 0x00, rngmask
, 0x00);
724 /* branch back to state 1 */
725 /* deceision state w/o data */
727 usbduxfast_cmd_data(dev
, 4, 0x09, 0x01, rngmask
, 0xff);
732 /* 0 means that the AD commands are sent */
733 ret
= usbduxfast_send_cmd(dev
, SENDADCOMMANDS
);
737 if ((cmd
->start_src
== TRIG_NOW
) || (cmd
->start_src
== TRIG_EXT
)) {
738 /* enable this acquisition operation */
739 devpriv
->ai_cmd_running
= 1;
740 ret
= usbduxfast_submit_urb(dev
);
742 devpriv
->ai_cmd_running
= 0;
743 /* fixme: unlink here?? */
746 s
->async
->inttrig
= NULL
;
747 } else { /* TRIG_INT */
748 s
->async
->inttrig
= usbduxfast_ai_inttrig
;
752 mutex_unlock(&devpriv
->mut
);
758 * Mode 0 is used to get a single conversion on demand.
760 static int usbduxfast_ai_insn_read(struct comedi_device
*dev
,
761 struct comedi_subdevice
*s
,
762 struct comedi_insn
*insn
,
765 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
766 struct usbduxfast_private
*devpriv
= dev
->private;
767 unsigned int chan
= CR_CHAN(insn
->chanspec
);
768 unsigned int range
= CR_RANGE(insn
->chanspec
);
769 u8 rngmask
= range
? (0xff - 0x04) : 0xff;
770 int i
, j
, n
, actual_length
;
773 mutex_lock(&devpriv
->mut
);
775 if (devpriv
->ai_cmd_running
) {
776 dev_err(dev
->class_dev
,
777 "ai_insn_read not possible, async cmd is running\n");
778 mutex_unlock(&devpriv
->mut
);
782 /* set command for the first channel */
784 /* commit data to the FIFO */
786 usbduxfast_cmd_data(dev
, 0, 0x01, 0x02, rngmask
, 0x00);
788 /* do the first part of the delay */
789 usbduxfast_cmd_data(dev
, 1, 0x0c, 0x00, 0xfe & rngmask
, 0x00);
790 usbduxfast_cmd_data(dev
, 2, 0x01, 0x00, 0xfe & rngmask
, 0x00);
791 usbduxfast_cmd_data(dev
, 3, 0x01, 0x00, 0xfe & rngmask
, 0x00);
792 usbduxfast_cmd_data(dev
, 4, 0x01, 0x00, 0xfe & rngmask
, 0x00);
795 usbduxfast_cmd_data(dev
, 5, 0x0c, 0x00, rngmask
, 0x00);
796 usbduxfast_cmd_data(dev
, 6, 0x01, 0x00, rngmask
, 0x00);
798 ret
= usbduxfast_send_cmd(dev
, SENDADCOMMANDS
);
800 mutex_unlock(&devpriv
->mut
);
804 for (i
= 0; i
< PACKETS_TO_IGNORE
; i
++) {
805 ret
= usb_bulk_msg(usb
, usb_rcvbulkpipe(usb
, BULKINEP
),
806 devpriv
->inbuf
, SIZEINBUF
,
807 &actual_length
, 10000);
809 dev_err(dev
->class_dev
, "insn timeout, no data\n");
810 mutex_unlock(&devpriv
->mut
);
815 for (i
= 0; i
< insn
->n
;) {
816 ret
= usb_bulk_msg(usb
, usb_rcvbulkpipe(usb
, BULKINEP
),
817 devpriv
->inbuf
, SIZEINBUF
,
818 &actual_length
, 10000);
820 dev_err(dev
->class_dev
, "insn data error: %d\n", ret
);
821 mutex_unlock(&devpriv
->mut
);
824 n
= actual_length
/ sizeof(u16
);
826 dev_err(dev
->class_dev
, "insn data packet corrupted\n");
827 mutex_unlock(&devpriv
->mut
);
830 for (j
= chan
; (j
< n
) && (i
< insn
->n
); j
= j
+ 16) {
831 data
[i
] = ((u16
*)(devpriv
->inbuf
))[j
];
836 mutex_unlock(&devpriv
->mut
);
841 static int usbduxfast_upload_firmware(struct comedi_device
*dev
,
842 const u8
*data
, size_t size
,
843 unsigned long context
)
845 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
853 if (size
> FIRMWARE_MAX_LEN
) {
854 dev_err(dev
->class_dev
, "firmware binary too large for FX2\n");
858 /* we generate a local buffer for the firmware */
859 buf
= kmemdup(data
, size
, GFP_KERNEL
);
863 /* we need a malloc'ed buffer for usb_control_msg() */
864 tmp
= kmalloc(1, GFP_KERNEL
);
870 /* stop the current firmware on the device */
871 *tmp
= 1; /* 7f92 to one */
872 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
873 USBDUXFASTSUB_FIRMWARE
,
875 USBDUXFASTSUB_CPUCS
, 0x0000,
879 dev_err(dev
->class_dev
, "can not stop firmware\n");
883 /* upload the new firmware to the device */
884 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
885 USBDUXFASTSUB_FIRMWARE
,
891 dev_err(dev
->class_dev
, "firmware upload failed\n");
895 /* start the new firmware on the device */
896 *tmp
= 0; /* 7f92 to zero */
897 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
898 USBDUXFASTSUB_FIRMWARE
,
900 USBDUXFASTSUB_CPUCS
, 0x0000,
904 dev_err(dev
->class_dev
, "can not start firmware\n");
912 static int usbduxfast_auto_attach(struct comedi_device
*dev
,
913 unsigned long context_unused
)
915 struct usb_interface
*intf
= comedi_to_usb_interface(dev
);
916 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
917 struct usbduxfast_private
*devpriv
;
918 struct comedi_subdevice
*s
;
921 if (usb
->speed
!= USB_SPEED_HIGH
) {
922 dev_err(dev
->class_dev
,
923 "This driver needs USB 2.0 to operate. Aborting...\n");
927 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
931 mutex_init(&devpriv
->mut
);
932 usb_set_intfdata(intf
, devpriv
);
934 devpriv
->duxbuf
= kmalloc(SIZEOFDUXBUF
, GFP_KERNEL
);
935 if (!devpriv
->duxbuf
)
938 ret
= usb_set_interface(usb
,
939 intf
->altsetting
->desc
.bInterfaceNumber
, 1);
941 dev_err(dev
->class_dev
,
942 "could not switch to alternate setting 1\n");
946 devpriv
->urb
= usb_alloc_urb(0, GFP_KERNEL
);
950 devpriv
->inbuf
= kmalloc(SIZEINBUF
, GFP_KERNEL
);
954 ret
= comedi_load_firmware(dev
, &usb
->dev
, FIRMWARE
,
955 usbduxfast_upload_firmware
, 0);
959 ret
= comedi_alloc_subdevices(dev
, 1);
963 /* Analog Input subdevice */
964 s
= &dev
->subdevices
[0];
965 dev
->read_subdev
= s
;
966 s
->type
= COMEDI_SUBD_AI
;
967 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
| SDF_CMD_READ
;
969 s
->maxdata
= 0x1000; /* 12-bit + 1 overflow bit */
970 s
->range_table
= &range_usbduxfast_ai_range
;
971 s
->insn_read
= usbduxfast_ai_insn_read
;
972 s
->len_chanlist
= s
->n_chan
;
973 s
->do_cmdtest
= usbduxfast_ai_cmdtest
;
974 s
->do_cmd
= usbduxfast_ai_cmd
;
975 s
->cancel
= usbduxfast_ai_cancel
;
980 static void usbduxfast_detach(struct comedi_device
*dev
)
982 struct usb_interface
*intf
= comedi_to_usb_interface(dev
);
983 struct usbduxfast_private
*devpriv
= dev
->private;
988 mutex_lock(&devpriv
->mut
);
990 usb_set_intfdata(intf
, NULL
);
993 /* waits until a running transfer is over */
994 usb_kill_urb(devpriv
->urb
);
996 kfree(devpriv
->inbuf
);
997 usb_free_urb(devpriv
->urb
);
1000 kfree(devpriv
->duxbuf
);
1002 mutex_unlock(&devpriv
->mut
);
1004 mutex_destroy(&devpriv
->mut
);
1007 static struct comedi_driver usbduxfast_driver
= {
1008 .driver_name
= "usbduxfast",
1009 .module
= THIS_MODULE
,
1010 .auto_attach
= usbduxfast_auto_attach
,
1011 .detach
= usbduxfast_detach
,
1014 static int usbduxfast_usb_probe(struct usb_interface
*intf
,
1015 const struct usb_device_id
*id
)
1017 return comedi_usb_auto_config(intf
, &usbduxfast_driver
, 0);
1020 static const struct usb_device_id usbduxfast_usb_table
[] = {
1021 /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
1022 { USB_DEVICE(0x13d8, 0x0010) }, /* real ID */
1023 { USB_DEVICE(0x13d8, 0x0011) }, /* real ID */
1026 MODULE_DEVICE_TABLE(usb
, usbduxfast_usb_table
);
1028 static struct usb_driver usbduxfast_usb_driver
= {
1029 .name
= "usbduxfast",
1030 .probe
= usbduxfast_usb_probe
,
1031 .disconnect
= comedi_usb_auto_unconfig
,
1032 .id_table
= usbduxfast_usb_table
,
1034 module_comedi_usb_driver(usbduxfast_driver
, usbduxfast_usb_driver
);
1036 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1037 MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com");
1038 MODULE_LICENSE("GPL");
1039 MODULE_FIRMWARE(FIRMWARE
);