2 * Copyright (C) 2004-2014 Bernd Porr, mail@berndporr.me.uk
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
17 * Description: University of Stirling USB DAQ & INCITE Technology Limited
18 * Devices: [ITL] USB-DUX-FAST (usbduxfast)
19 * Author: Bernd Porr <mail@berndporr.me.uk>
20 * Updated: 10 Oct 2014
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.9: Dropping the first data packet which seems to be from the last transfer.
35 * Buffer overflows in the FX2 are handed over to comedi.
36 * 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
37 * Added insn command basically for testing. Sample rate is
39 * 0.99: Ian Abbott pointed out a bug which has been corrected. Thanks!
40 * 0.99a: added external trigger.
41 * 1.00: added firmware kernel request to the driver which fixed
42 * udev coldplug problem
45 #include <linux/kernel.h>
46 #include <linux/module.h>
47 #include <linux/slab.h>
48 #include <linux/input.h>
49 #include <linux/fcntl.h>
50 #include <linux/compiler.h>
51 #include "../comedi_usb.h"
54 * timeout for the USB-transfer
59 * constants for "firmware" upload and download
61 #define FIRMWARE "usbduxfast_firmware.bin"
62 #define FIRMWARE_MAX_LEN 0x2000
63 #define USBDUXFASTSUB_FIRMWARE 0xA0
64 #define VENDOR_DIR_IN 0xC0
65 #define VENDOR_DIR_OUT 0x40
68 * internal addresses of the 8051 processor
70 #define USBDUXFASTSUB_CPUCS 0xE600
73 * max lenghth of the transfer-buffer for software upload
78 * input endpoint number
83 * endpoint for the A/D channellist: bulk OUT
85 #define CHANNELLISTEP 4
90 #define NUMCHANNELS 32
93 * size of the waveform descriptor
98 * size of one A/D value
100 #define SIZEADIN (sizeof(s16))
103 * size of the input-buffer IN BYTES
105 #define SIZEINBUF 512
110 #define SIZEINSNBUF 512
113 * size of the buffer for the dux commands in bytes
115 #define SIZEOFDUXBUF 256
118 * number of in-URBs which receive the data: min=5
120 #define NUMOFINBUFFERSHIGH 10
123 * min delay steps for more than one channel
124 * basically when the mux gives up ;-)
126 * steps at 30MHz in the FX2
128 #define MIN_SAMPLING_PERIOD 9
131 * max number of 1/30MHz delay steps
133 #define MAX_SAMPLING_PERIOD 500
136 * number of received packets to ignore before we start handing data
137 * over to comedi, it's quad buffering and we have to ignore 4 packets
139 #define PACKETS_TO_IGNORE 4
144 static const struct comedi_lrange range_usbduxfast_ai_range
= {
152 * private structure of one subdevice
154 * this is the structure which holds all the data of this driver
155 * one sub device just now: A/D
157 struct usbduxfast_private
{
158 struct urb
*urb
; /* BULK-transfer handling: urb */
161 short int ai_cmd_running
; /* asynchronous command is running */
162 int ignore
; /* counter which ignores the first buffers */
167 * bulk transfers to usbduxfast
169 #define SENDADCOMMANDS 0
170 #define SENDINITEP6 1
172 static int usbduxfast_send_cmd(struct comedi_device
*dev
, int cmd_type
)
174 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
175 struct usbduxfast_private
*devpriv
= dev
->private;
179 devpriv
->duxbuf
[0] = cmd_type
;
181 ret
= usb_bulk_msg(usb
, usb_sndbulkpipe(usb
, CHANNELLISTEP
),
182 devpriv
->duxbuf
, SIZEOFDUXBUF
,
185 dev_err(dev
->class_dev
,
186 "could not transmit command to the usb-device, err=%d\n",
191 static void usbduxfast_cmd_data(struct comedi_device
*dev
, int index
,
192 u8 len
, u8 op
, u8 out
, u8 log
)
194 struct usbduxfast_private
*devpriv
= dev
->private;
196 /* Set the GPIF bytes, the first byte is the command byte */
197 devpriv
->duxbuf
[1 + 0x00 + index
] = len
;
198 devpriv
->duxbuf
[1 + 0x08 + index
] = op
;
199 devpriv
->duxbuf
[1 + 0x10 + index
] = out
;
200 devpriv
->duxbuf
[1 + 0x18 + index
] = log
;
203 static int usbduxfast_ai_stop(struct comedi_device
*dev
, int do_unlink
)
205 struct usbduxfast_private
*devpriv
= dev
->private;
208 devpriv
->ai_cmd_running
= 0;
210 if (do_unlink
&& devpriv
->urb
) {
211 /* kill the running transfer */
212 usb_kill_urb(devpriv
->urb
);
218 static int usbduxfast_ai_cancel(struct comedi_device
*dev
,
219 struct comedi_subdevice
*s
)
221 struct usbduxfast_private
*devpriv
= dev
->private;
224 mutex_lock(&devpriv
->mut
);
225 ret
= usbduxfast_ai_stop(dev
, 1);
226 mutex_unlock(&devpriv
->mut
);
231 static void usbduxfast_ai_handle_urb(struct comedi_device
*dev
,
232 struct comedi_subdevice
*s
,
235 struct usbduxfast_private
*devpriv
= dev
->private;
236 struct comedi_async
*async
= s
->async
;
237 struct comedi_cmd
*cmd
= &async
->cmd
;
240 if (devpriv
->ignore
) {
243 unsigned int nsamples
;
245 nsamples
= comedi_bytes_to_samples(s
, urb
->actual_length
);
246 nsamples
= comedi_nsamples_left(s
, nsamples
);
247 comedi_buf_write_samples(s
, urb
->transfer_buffer
, nsamples
);
249 if (cmd
->stop_src
== TRIG_COUNT
&&
250 async
->scans_done
>= cmd
->stop_arg
)
251 async
->events
|= COMEDI_CB_EOA
;
254 /* if command is still running, resubmit urb for BULK transfer */
255 if (!(async
->events
& COMEDI_CB_CANCEL_MASK
)) {
256 urb
->dev
= comedi_to_usb_dev(dev
);
258 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
260 dev_err(dev
->class_dev
, "urb resubm failed: %d", ret
);
261 async
->events
|= COMEDI_CB_ERROR
;
266 static void usbduxfast_ai_interrupt(struct urb
*urb
)
268 struct comedi_device
*dev
= urb
->context
;
269 struct comedi_subdevice
*s
= dev
->read_subdev
;
270 struct comedi_async
*async
= s
->async
;
271 struct usbduxfast_private
*devpriv
= dev
->private;
273 /* exit if not running a command, do not resubmit urb */
274 if (!devpriv
->ai_cmd_running
)
277 switch (urb
->status
) {
279 usbduxfast_ai_handle_urb(dev
, s
, urb
);
286 /* after an unlink command, unplug, ... etc */
287 async
->events
|= COMEDI_CB_ERROR
;
292 dev_err(dev
->class_dev
,
293 "non-zero urb status received in ai intr context: %d\n",
295 async
->events
|= COMEDI_CB_ERROR
;
300 * comedi_handle_events() cannot be used in this driver. The (*cancel)
301 * operation would unlink the urb.
303 if (async
->events
& COMEDI_CB_CANCEL_MASK
)
304 usbduxfast_ai_stop(dev
, 0);
306 comedi_event(dev
, s
);
309 static int usbduxfast_submit_urb(struct comedi_device
*dev
)
311 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
312 struct usbduxfast_private
*devpriv
= dev
->private;
315 usb_fill_bulk_urb(devpriv
->urb
, usb
, usb_rcvbulkpipe(usb
, BULKINEP
),
316 devpriv
->inbuf
, SIZEINBUF
,
317 usbduxfast_ai_interrupt
, dev
);
319 ret
= usb_submit_urb(devpriv
->urb
, GFP_ATOMIC
);
321 dev_err(dev
->class_dev
, "usb_submit_urb error %d\n", ret
);
327 static int usbduxfast_ai_check_chanlist(struct comedi_device
*dev
,
328 struct comedi_subdevice
*s
,
329 struct comedi_cmd
*cmd
)
331 unsigned int gain0
= CR_RANGE(cmd
->chanlist
[0]);
334 if (cmd
->chanlist_len
> 3 && cmd
->chanlist_len
!= 16) {
335 dev_err(dev
->class_dev
, "unsupported combination of channels\n");
339 for (i
= 0; i
< cmd
->chanlist_len
; ++i
) {
340 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
341 unsigned int gain
= CR_RANGE(cmd
->chanlist
[i
]);
344 dev_err(dev
->class_dev
,
345 "channels are not consecutive\n");
348 if (gain
!= gain0
&& cmd
->chanlist_len
> 3) {
349 dev_err(dev
->class_dev
,
350 "gain must be the same for all channels\n");
357 static int usbduxfast_ai_cmdtest(struct comedi_device
*dev
,
358 struct comedi_subdevice
*s
,
359 struct comedi_cmd
*cmd
)
365 /* Step 1 : check if triggers are trivially valid */
367 err
|= comedi_check_trigger_src(&cmd
->start_src
,
368 TRIG_NOW
| TRIG_EXT
| TRIG_INT
);
369 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
, TRIG_FOLLOW
);
370 err
|= comedi_check_trigger_src(&cmd
->convert_src
, TRIG_TIMER
);
371 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
372 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
377 /* Step 2a : make sure trigger sources are unique */
379 err
|= comedi_check_trigger_is_unique(cmd
->start_src
);
380 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
382 /* Step 2b : and mutually compatible */
387 /* Step 3: check if arguments are trivially valid */
389 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
391 if (!cmd
->chanlist_len
)
394 /* external start trigger is only valid for 1 or 16 channels */
395 if (cmd
->start_src
== TRIG_EXT
&&
396 cmd
->chanlist_len
!= 1 && cmd
->chanlist_len
!= 16)
399 err
|= comedi_check_trigger_arg_is(&cmd
->scan_end_arg
,
403 * Validate the conversion timing:
404 * for 1 channel the timing in 30MHz "steps" is:
405 * steps <= MAX_SAMPLING_PERIOD
406 * for all other chanlist_len it is:
407 * MIN_SAMPLING_PERIOD <= steps <= MAX_SAMPLING_PERIOD
409 steps
= (cmd
->convert_arg
* 30) / 1000;
410 if (cmd
->chanlist_len
!= 1)
411 err
|= comedi_check_trigger_arg_min(&steps
,
412 MIN_SAMPLING_PERIOD
);
413 err
|= comedi_check_trigger_arg_max(&steps
, MAX_SAMPLING_PERIOD
);
414 arg
= (steps
* 1000) / 30;
415 err
|= comedi_check_trigger_arg_is(&cmd
->convert_arg
, arg
);
417 if (cmd
->stop_src
== TRIG_COUNT
)
418 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
420 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
425 /* Step 4: fix up any arguments */
427 /* Step 5: check channel list if it exists */
428 if (cmd
->chanlist
&& cmd
->chanlist_len
> 0)
429 err
|= usbduxfast_ai_check_chanlist(dev
, s
, cmd
);
436 static int usbduxfast_ai_inttrig(struct comedi_device
*dev
,
437 struct comedi_subdevice
*s
,
438 unsigned int trig_num
)
440 struct usbduxfast_private
*devpriv
= dev
->private;
441 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
444 if (trig_num
!= cmd
->start_arg
)
447 mutex_lock(&devpriv
->mut
);
449 if (!devpriv
->ai_cmd_running
) {
450 devpriv
->ai_cmd_running
= 1;
451 ret
= usbduxfast_submit_urb(dev
);
453 dev_err(dev
->class_dev
, "urbSubmit: err=%d\n", ret
);
454 devpriv
->ai_cmd_running
= 0;
455 mutex_unlock(&devpriv
->mut
);
458 s
->async
->inttrig
= NULL
;
460 dev_err(dev
->class_dev
, "ai is already running\n");
462 mutex_unlock(&devpriv
->mut
);
466 static int usbduxfast_ai_cmd(struct comedi_device
*dev
,
467 struct comedi_subdevice
*s
)
469 struct usbduxfast_private
*devpriv
= dev
->private;
470 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
471 unsigned int rngmask
= 0xff;
473 long steps
, steps_tmp
;
475 mutex_lock(&devpriv
->mut
);
476 if (devpriv
->ai_cmd_running
) {
482 * ignore the first buffers from the device if there
483 * is an error condition
485 devpriv
->ignore
= PACKETS_TO_IGNORE
;
487 steps
= (cmd
->convert_arg
* 30) / 1000;
489 switch (cmd
->chanlist_len
) {
495 if (CR_RANGE(cmd
->chanlist
[0]) > 0)
496 rngmask
= 0xff - 0x04;
501 * for external trigger: looping in this state until
502 * the RDY0 pin becomes zero
505 /* we loop here until ready has been set */
506 if (cmd
->start_src
== TRIG_EXT
) {
507 /* branch back to state 0 */
508 /* deceision state w/o data */
510 usbduxfast_cmd_data(dev
, 0, 0x01, 0x01, rngmask
, 0x00);
511 } else { /* we just proceed to state 1 */
512 usbduxfast_cmd_data(dev
, 0, 0x01, 0x00, rngmask
, 0x00);
515 if (steps
< MIN_SAMPLING_PERIOD
) {
516 /* for fast single channel aqu without mux */
519 * we just stay here at state 1 and rexecute
520 * the same state this gives us 30MHz sampling
524 /* branch back to state 1 */
525 /* deceision state with data */
527 usbduxfast_cmd_data(dev
, 1,
528 0x89, 0x03, rngmask
, 0xff);
531 * we loop through two states: data and delay
536 usbduxfast_cmd_data(dev
, 1, steps
- 1,
537 0x02, rngmask
, 0x00);
539 /* branch back to state 1 */
540 /* deceision state w/o data */
542 usbduxfast_cmd_data(dev
, 2,
543 0x09, 0x01, rngmask
, 0xff);
547 * we loop through 3 states: 2x delay and 1x data
548 * this gives a min sampling rate of 60kHz
551 /* we have 1 state with duration 1 */
554 /* do the first part of the delay */
555 usbduxfast_cmd_data(dev
, 1,
556 steps
/ 2, 0x00, rngmask
, 0x00);
558 /* and the second part */
559 usbduxfast_cmd_data(dev
, 2, steps
- steps
/ 2,
560 0x00, rngmask
, 0x00);
562 /* get the data and branch back */
564 /* branch back to state 1 */
565 /* deceision state w data */
567 usbduxfast_cmd_data(dev
, 3,
568 0x09, 0x03, rngmask
, 0xff);
575 * commit data to the FIFO
578 if (CR_RANGE(cmd
->chanlist
[0]) > 0)
579 rngmask
= 0xff - 0x04;
584 usbduxfast_cmd_data(dev
, 0, 0x01, 0x02, rngmask
, 0x00);
586 /* we have 1 state with duration 1: state 0 */
587 steps_tmp
= steps
- 1;
589 if (CR_RANGE(cmd
->chanlist
[1]) > 0)
590 rngmask
= 0xff - 0x04;
594 /* do the first part of the delay */
596 usbduxfast_cmd_data(dev
, 1, steps_tmp
/ 2,
597 0x00, 0xfe & rngmask
, 0x00);
599 /* and the second part */
600 usbduxfast_cmd_data(dev
, 2, steps_tmp
- steps_tmp
/ 2,
601 0x00, rngmask
, 0x00);
604 usbduxfast_cmd_data(dev
, 3, 0x01, 0x02, rngmask
, 0x00);
607 * we have 2 states with duration 1: step 6 and
610 steps_tmp
= steps
- 2;
612 if (CR_RANGE(cmd
->chanlist
[0]) > 0)
613 rngmask
= 0xff - 0x04;
617 /* do the first part of the delay */
619 usbduxfast_cmd_data(dev
, 4, steps_tmp
/ 2,
620 0x00, (0xff - 0x02) & rngmask
, 0x00);
622 /* and the second part */
623 usbduxfast_cmd_data(dev
, 5, steps_tmp
- steps_tmp
/ 2,
624 0x00, rngmask
, 0x00);
626 usbduxfast_cmd_data(dev
, 6, 0x01, 0x00, rngmask
, 0x00);
633 for (j
= 0; j
< 1; j
++) {
636 if (CR_RANGE(cmd
->chanlist
[j
]) > 0)
637 rngmask
= 0xff - 0x04;
641 * commit data to the FIFO and do the first part
646 usbduxfast_cmd_data(dev
, index
, steps
/ 2,
647 0x02, rngmask
, 0x00);
649 if (CR_RANGE(cmd
->chanlist
[j
+ 1]) > 0)
650 rngmask
= 0xff - 0x04;
654 /* do the second part of the delay */
657 usbduxfast_cmd_data(dev
, index
+ 1, steps
- steps
/ 2,
658 0x00, 0xfe & rngmask
, 0x00);
661 /* 2 steps with duration 1: the idele step and step 6: */
662 steps_tmp
= steps
- 2;
664 /* commit data to the FIFO and do the first part of the delay */
666 usbduxfast_cmd_data(dev
, 4, steps_tmp
/ 2,
667 0x02, rngmask
, 0x00);
669 if (CR_RANGE(cmd
->chanlist
[0]) > 0)
670 rngmask
= 0xff - 0x04;
674 /* do the second part of the delay */
677 usbduxfast_cmd_data(dev
, 5, steps_tmp
- steps_tmp
/ 2,
678 0x00, (0xff - 0x02) & rngmask
, 0x00);
680 usbduxfast_cmd_data(dev
, 6, 0x01, 0x00, rngmask
, 0x00);
684 if (CR_RANGE(cmd
->chanlist
[0]) > 0)
685 rngmask
= 0xff - 0x04;
689 if (cmd
->start_src
== TRIG_EXT
) {
691 * we loop here until ready has been set
694 /* branch back to state 0 */
695 /* deceision state w/o data */
698 usbduxfast_cmd_data(dev
, 0, 0x01, 0x01,
699 (0xff - 0x02) & rngmask
, 0x00);
702 * we just proceed to state 1
705 /* 30us reset pulse */
707 usbduxfast_cmd_data(dev
, 0, 0xff, 0x00,
708 (0xff - 0x02) & rngmask
, 0x00);
711 /* commit data to the FIFO */
713 usbduxfast_cmd_data(dev
, 1, 0x01, 0x02, rngmask
, 0x00);
715 /* we have 2 states with duration 1 */
718 /* do the first part of the delay */
719 usbduxfast_cmd_data(dev
, 2, steps
/ 2,
720 0x00, 0xfe & rngmask
, 0x00);
722 /* and the second part */
723 usbduxfast_cmd_data(dev
, 3, steps
- steps
/ 2,
724 0x00, rngmask
, 0x00);
726 /* branch back to state 1 */
727 /* deceision state w/o data */
729 usbduxfast_cmd_data(dev
, 4, 0x09, 0x01, rngmask
, 0xff);
734 /* 0 means that the AD commands are sent */
735 ret
= usbduxfast_send_cmd(dev
, SENDADCOMMANDS
);
739 if ((cmd
->start_src
== TRIG_NOW
) || (cmd
->start_src
== TRIG_EXT
)) {
740 /* enable this acquisition operation */
741 devpriv
->ai_cmd_running
= 1;
742 ret
= usbduxfast_submit_urb(dev
);
744 devpriv
->ai_cmd_running
= 0;
745 /* fixme: unlink here?? */
748 s
->async
->inttrig
= NULL
;
749 } else { /* TRIG_INT */
750 s
->async
->inttrig
= usbduxfast_ai_inttrig
;
754 mutex_unlock(&devpriv
->mut
);
760 * Mode 0 is used to get a single conversion on demand.
762 static int usbduxfast_ai_insn_read(struct comedi_device
*dev
,
763 struct comedi_subdevice
*s
,
764 struct comedi_insn
*insn
,
767 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
768 struct usbduxfast_private
*devpriv
= dev
->private;
769 unsigned int chan
= CR_CHAN(insn
->chanspec
);
770 unsigned int range
= CR_RANGE(insn
->chanspec
);
771 u8 rngmask
= range
? (0xff - 0x04) : 0xff;
772 int i
, j
, n
, actual_length
;
775 mutex_lock(&devpriv
->mut
);
777 if (devpriv
->ai_cmd_running
) {
778 dev_err(dev
->class_dev
,
779 "ai_insn_read not possible, async cmd is running\n");
780 mutex_unlock(&devpriv
->mut
);
784 /* set command for the first channel */
786 /* commit data to the FIFO */
788 usbduxfast_cmd_data(dev
, 0, 0x01, 0x02, rngmask
, 0x00);
790 /* do the first part of the delay */
791 usbduxfast_cmd_data(dev
, 1, 0x0c, 0x00, 0xfe & rngmask
, 0x00);
792 usbduxfast_cmd_data(dev
, 2, 0x01, 0x00, 0xfe & rngmask
, 0x00);
793 usbduxfast_cmd_data(dev
, 3, 0x01, 0x00, 0xfe & rngmask
, 0x00);
794 usbduxfast_cmd_data(dev
, 4, 0x01, 0x00, 0xfe & rngmask
, 0x00);
797 usbduxfast_cmd_data(dev
, 5, 0x0c, 0x00, rngmask
, 0x00);
798 usbduxfast_cmd_data(dev
, 6, 0x01, 0x00, rngmask
, 0x00);
800 ret
= usbduxfast_send_cmd(dev
, SENDADCOMMANDS
);
802 mutex_unlock(&devpriv
->mut
);
806 for (i
= 0; i
< PACKETS_TO_IGNORE
; i
++) {
807 ret
= usb_bulk_msg(usb
, usb_rcvbulkpipe(usb
, BULKINEP
),
808 devpriv
->inbuf
, SIZEINBUF
,
809 &actual_length
, 10000);
811 dev_err(dev
->class_dev
, "insn timeout, no data\n");
812 mutex_unlock(&devpriv
->mut
);
817 for (i
= 0; i
< insn
->n
;) {
818 ret
= usb_bulk_msg(usb
, usb_rcvbulkpipe(usb
, BULKINEP
),
819 devpriv
->inbuf
, SIZEINBUF
,
820 &actual_length
, 10000);
822 dev_err(dev
->class_dev
, "insn data error: %d\n", ret
);
823 mutex_unlock(&devpriv
->mut
);
826 n
= actual_length
/ sizeof(u16
);
828 dev_err(dev
->class_dev
, "insn data packet corrupted\n");
829 mutex_unlock(&devpriv
->mut
);
832 for (j
= chan
; (j
< n
) && (i
< insn
->n
); j
= j
+ 16) {
833 data
[i
] = ((u16
*)(devpriv
->inbuf
))[j
];
838 mutex_unlock(&devpriv
->mut
);
843 static int usbduxfast_upload_firmware(struct comedi_device
*dev
,
844 const u8
*data
, size_t size
,
845 unsigned long context
)
847 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
855 if (size
> FIRMWARE_MAX_LEN
) {
856 dev_err(dev
->class_dev
, "firmware binary too large for FX2\n");
860 /* we generate a local buffer for the firmware */
861 buf
= kmemdup(data
, size
, GFP_KERNEL
);
865 /* we need a malloc'ed buffer for usb_control_msg() */
866 tmp
= kmalloc(1, GFP_KERNEL
);
872 /* stop the current firmware on the device */
873 *tmp
= 1; /* 7f92 to one */
874 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
875 USBDUXFASTSUB_FIRMWARE
,
877 USBDUXFASTSUB_CPUCS
, 0x0000,
881 dev_err(dev
->class_dev
, "can not stop firmware\n");
885 /* upload the new firmware to the device */
886 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
887 USBDUXFASTSUB_FIRMWARE
,
893 dev_err(dev
->class_dev
, "firmware upload failed\n");
897 /* start the new firmware on the device */
898 *tmp
= 0; /* 7f92 to zero */
899 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
900 USBDUXFASTSUB_FIRMWARE
,
902 USBDUXFASTSUB_CPUCS
, 0x0000,
906 dev_err(dev
->class_dev
, "can not start firmware\n");
914 static int usbduxfast_auto_attach(struct comedi_device
*dev
,
915 unsigned long context_unused
)
917 struct usb_interface
*intf
= comedi_to_usb_interface(dev
);
918 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
919 struct usbduxfast_private
*devpriv
;
920 struct comedi_subdevice
*s
;
923 if (usb
->speed
!= USB_SPEED_HIGH
) {
924 dev_err(dev
->class_dev
,
925 "This driver needs USB 2.0 to operate. Aborting...\n");
929 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
933 mutex_init(&devpriv
->mut
);
934 usb_set_intfdata(intf
, devpriv
);
936 devpriv
->duxbuf
= kmalloc(SIZEOFDUXBUF
, GFP_KERNEL
);
937 if (!devpriv
->duxbuf
)
940 ret
= usb_set_interface(usb
,
941 intf
->altsetting
->desc
.bInterfaceNumber
, 1);
943 dev_err(dev
->class_dev
,
944 "could not switch to alternate setting 1\n");
948 devpriv
->urb
= usb_alloc_urb(0, GFP_KERNEL
);
950 dev_err(dev
->class_dev
, "Could not alloc. urb\n");
954 devpriv
->inbuf
= kmalloc(SIZEINBUF
, GFP_KERNEL
);
958 ret
= comedi_load_firmware(dev
, &usb
->dev
, FIRMWARE
,
959 usbduxfast_upload_firmware
, 0);
963 ret
= comedi_alloc_subdevices(dev
, 1);
967 /* Analog Input subdevice */
968 s
= &dev
->subdevices
[0];
969 dev
->read_subdev
= s
;
970 s
->type
= COMEDI_SUBD_AI
;
971 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
| SDF_CMD_READ
;
973 s
->maxdata
= 0x1000; /* 12-bit + 1 overflow bit */
974 s
->range_table
= &range_usbduxfast_ai_range
;
975 s
->insn_read
= usbduxfast_ai_insn_read
;
976 s
->len_chanlist
= s
->n_chan
;
977 s
->do_cmdtest
= usbduxfast_ai_cmdtest
;
978 s
->do_cmd
= usbduxfast_ai_cmd
;
979 s
->cancel
= usbduxfast_ai_cancel
;
984 static void usbduxfast_detach(struct comedi_device
*dev
)
986 struct usb_interface
*intf
= comedi_to_usb_interface(dev
);
987 struct usbduxfast_private
*devpriv
= dev
->private;
992 mutex_lock(&devpriv
->mut
);
994 usb_set_intfdata(intf
, NULL
);
997 /* waits until a running transfer is over */
998 usb_kill_urb(devpriv
->urb
);
1000 kfree(devpriv
->inbuf
);
1001 usb_free_urb(devpriv
->urb
);
1004 kfree(devpriv
->duxbuf
);
1006 mutex_unlock(&devpriv
->mut
);
1009 static struct comedi_driver usbduxfast_driver
= {
1010 .driver_name
= "usbduxfast",
1011 .module
= THIS_MODULE
,
1012 .auto_attach
= usbduxfast_auto_attach
,
1013 .detach
= usbduxfast_detach
,
1016 static int usbduxfast_usb_probe(struct usb_interface
*intf
,
1017 const struct usb_device_id
*id
)
1019 return comedi_usb_auto_config(intf
, &usbduxfast_driver
, 0);
1022 static const struct usb_device_id usbduxfast_usb_table
[] = {
1023 /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
1024 { USB_DEVICE(0x13d8, 0x0010) }, /* real ID */
1025 { USB_DEVICE(0x13d8, 0x0011) }, /* real ID */
1028 MODULE_DEVICE_TABLE(usb
, usbduxfast_usb_table
);
1030 static struct usb_driver usbduxfast_usb_driver
= {
1031 .name
= "usbduxfast",
1032 .probe
= usbduxfast_usb_probe
,
1033 .disconnect
= comedi_usb_auto_unconfig
,
1034 .id_table
= usbduxfast_usb_table
,
1036 module_comedi_usb_driver(usbduxfast_driver
, usbduxfast_usb_driver
);
1038 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1039 MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com");
1040 MODULE_LICENSE("GPL");
1041 MODULE_FIRMWARE(FIRMWARE
);