2 * Copyright (C) 2004 Bernd Porr, Bernd.Porr@f2s.com
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.
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 * 0.9: Dropping the first data packet which seems to be from the last transfer.
26 * Buffer overflows in the FX2 are handed over to comedi.
27 * 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
28 * Added insn command basically for testing. Sample rate is
30 * 0.99: Ian Abbott pointed out a bug which has been corrected. Thanks!
31 * 0.99a: added external trigger.
32 * 1.00: added firmware kernel request to the driver which fixed
33 * udev coldplug problem
36 #include <linux/kernel.h>
37 #include <linux/module.h>
38 #include <linux/slab.h>
39 #include <linux/input.h>
40 #include <linux/usb.h>
41 #include <linux/fcntl.h>
42 #include <linux/compiler.h>
43 #include "comedi_fc.h"
44 #include "../comedidev.h"
47 * timeout for the USB-transfer
52 * constants for "firmware" upload and download
54 #define FIRMWARE "usbduxfast_firmware.bin"
55 #define FIRMWARE_MAX_LEN 0x2000
56 #define USBDUXFASTSUB_FIRMWARE 0xA0
57 #define VENDOR_DIR_IN 0xC0
58 #define VENDOR_DIR_OUT 0x40
61 * internal addresses of the 8051 processor
63 #define USBDUXFASTSUB_CPUCS 0xE600
66 * max lenghth of the transfer-buffer for software upload
71 * input endpoint number
76 * endpoint for the A/D channellist: bulk OUT
78 #define CHANNELLISTEP 4
83 #define NUMCHANNELS 32
86 * size of the waveform descriptor
91 * size of one A/D value
93 #define SIZEADIN (sizeof(int16_t))
96 * size of the input-buffer IN BYTES
103 #define SIZEINSNBUF 512
106 * size of the buffer for the dux commands in bytes
108 #define SIZEOFDUXBUF 256
111 * number of in-URBs which receive the data: min=5
113 #define NUMOFINBUFFERSHIGH 10
116 * min delay steps for more than one channel
117 * basically when the mux gives up ;-)
119 * steps at 30MHz in the FX2
121 #define MIN_SAMPLING_PERIOD 9
124 * max number of 1/30MHz delay steps
126 #define MAX_SAMPLING_PERIOD 500
129 * number of received packets to ignore before we start handing data
130 * over to comedi, it's quad buffering and we have to ignore 4 packets
132 #define PACKETS_TO_IGNORE 4
137 static const struct comedi_lrange range_usbduxfast_ai_range = {
145 * private structure of one subdevice
147 * this is the structure which holds all the data of this driver
148 * one sub device just now: A/D
150 struct usbduxfast_private {
151 struct urb *urb; /* BULK-transfer handling: urb */
154 short int ai_cmd_running; /* asynchronous command is running */
155 long int ai_sample_count; /* number of samples to acquire */
156 int ignore; /* counter which ignores the first
158 struct semaphore sem;
162 * bulk transfers to usbduxfast
164 #define SENDADCOMMANDS 0
165 #define SENDINITEP6 1
167 static int usbduxfast_send_cmd(struct comedi_device *dev, int cmd_type)
169 struct usb_device *usb = comedi_to_usb_dev(dev);
170 struct usbduxfast_private *devpriv = dev->private;
174 devpriv->duxbuf[0] = cmd_type;
176 ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, CHANNELLISTEP),
177 devpriv->duxbuf, SIZEOFDUXBUF,
180 dev_err(dev->class_dev,
181 "could not transmit command to the usb-device, err=%d\n",
186 static void usbduxfast_cmd_data(struct comedi_device *dev, int index,
187 uint8_t len, uint8_t op, uint8_t out,
190 struct usbduxfast_private *devpriv = dev->private;
192 /* Set the GPIF bytes, the first byte is the command byte */
193 devpriv->duxbuf[1 + 0x00 + index] = len;
194 devpriv->duxbuf[1 + 0x08 + index] = op;
195 devpriv->duxbuf[1 + 0x10 + index] = out;
196 devpriv->duxbuf[1 + 0x18 + index] = log;
199 static int usbduxfast_ai_stop(struct comedi_device *dev, int do_unlink)
201 struct usbduxfast_private *devpriv = dev->private;
204 devpriv->ai_cmd_running = 0;
206 if (do_unlink && devpriv->urb) {
207 /* kill the running transfer */
208 usb_kill_urb(devpriv->urb);
214 static int usbduxfast_ai_cancel(struct comedi_device *dev,
215 struct comedi_subdevice *s)
217 struct usbduxfast_private *devpriv = dev->private;
224 ret = usbduxfast_ai_stop(dev, 1);
232 * interrupt service routine
234 static void usbduxfast_ai_interrupt(struct urb *urb)
236 struct comedi_device *dev = urb->context;
237 struct comedi_subdevice *s = dev->read_subdev;
238 struct comedi_async *async = s->async;
239 struct comedi_cmd *cmd = &async->cmd;
240 struct usb_device *usb = comedi_to_usb_dev(dev);
241 struct usbduxfast_private *devpriv = dev->private;
244 /* are we running a command? */
245 if (unlikely(!devpriv->ai_cmd_running)) {
247 * not running a command
248 * do not continue execution if no asynchronous command
249 * is running in particular not resubmit
254 /* first we test if something unusual has just happened */
255 switch (urb->status) {
260 * happens after an unlink command or when the device
267 /* tell this comedi */
268 async->events |= COMEDI_CB_EOA;
269 async->events |= COMEDI_CB_ERROR;
270 comedi_event(dev, s);
271 /* stop the transfer w/o unlink */
272 usbduxfast_ai_stop(dev, 0);
276 dev_err(dev->class_dev,
277 "non-zero urb status received in ai intr context: %d\n",
279 async->events |= COMEDI_CB_EOA;
280 async->events |= COMEDI_CB_ERROR;
281 comedi_event(dev, s);
282 usbduxfast_ai_stop(dev, 0);
286 if (!devpriv->ignore) {
287 if (cmd->stop_src == TRIG_COUNT) {
288 /* not continuous, fixed number of samples */
289 n = urb->actual_length / sizeof(uint16_t);
290 if (unlikely(devpriv->ai_sample_count < n)) {
291 unsigned int num_bytes;
293 /* partial sample received */
294 num_bytes = devpriv->ai_sample_count *
296 cfc_write_array_to_buffer(s,
297 urb->transfer_buffer,
299 usbduxfast_ai_stop(dev, 0);
300 /* tell comedi that the acquistion is over */
301 async->events |= COMEDI_CB_EOA;
302 comedi_event(dev, s);
305 devpriv->ai_sample_count -= n;
307 /* write the full buffer to comedi */
308 err = cfc_write_array_to_buffer(s, urb->transfer_buffer,
310 if (unlikely(err == 0)) {
311 /* buffer overflow */
312 usbduxfast_ai_stop(dev, 0);
316 /* tell comedi that data is there */
317 comedi_event(dev, s);
319 /* ignore this packet */
324 * command is still running
325 * resubmit urb for BULK transfer
329 err = usb_submit_urb(urb, GFP_ATOMIC);
331 dev_err(dev->class_dev,
332 "urb resubm failed: %d", err);
333 async->events |= COMEDI_CB_EOA;
334 async->events |= COMEDI_CB_ERROR;
335 comedi_event(dev, s);
336 usbduxfast_ai_stop(dev, 0);
340 static int usbduxfast_submit_urb(struct comedi_device *dev)
342 struct usb_device *usb = comedi_to_usb_dev(dev);
343 struct usbduxfast_private *devpriv = dev->private;
349 usb_fill_bulk_urb(devpriv->urb, usb, usb_rcvbulkpipe(usb, BULKINEP),
350 devpriv->inbuf, SIZEINBUF,
351 usbduxfast_ai_interrupt, dev);
353 ret = usb_submit_urb(devpriv->urb, GFP_ATOMIC);
355 dev_err(dev->class_dev, "usb_submit_urb error %d\n", ret);
361 static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
362 struct comedi_subdevice *s,
363 struct comedi_cmd *cmd)
367 int min_sample_period;
369 /* Step 1 : check if triggers are trivially valid */
371 err |= cfc_check_trigger_src(&cmd->start_src,
372 TRIG_NOW | TRIG_EXT | TRIG_INT);
373 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
374 TRIG_FOLLOW | TRIG_EXT);
375 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
376 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
377 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
382 /* Step 2a : make sure trigger sources are unique */
384 err |= cfc_check_trigger_is_unique(cmd->start_src);
385 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
386 err |= cfc_check_trigger_is_unique(cmd->convert_src);
387 err |= cfc_check_trigger_is_unique(cmd->stop_src);
389 /* Step 2b : and mutually compatible */
391 /* can't have external stop and start triggers at once */
392 if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
398 /* Step 3: check if arguments are trivially valid */
400 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
402 if (!cmd->chanlist_len)
405 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
407 if (cmd->chanlist_len == 1)
408 min_sample_period = 1;
410 min_sample_period = MIN_SAMPLING_PERIOD;
412 if (cmd->convert_src == TRIG_TIMER) {
413 steps = cmd->convert_arg * 30;
414 if (steps < (min_sample_period * 1000))
415 steps = min_sample_period * 1000;
417 if (steps > (MAX_SAMPLING_PERIOD * 1000))
418 steps = MAX_SAMPLING_PERIOD * 1000;
422 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, tmp);
426 switch (cmd->stop_src) {
428 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
431 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
434 * TRIG_EXT doesn't care since it doesn't trigger
435 * off a numbered channel
444 /* step 4: fix up any arguments */
450 static int usbduxfast_ai_inttrig(struct comedi_device *dev,
451 struct comedi_subdevice *s,
452 unsigned int trig_num)
454 struct usbduxfast_private *devpriv = dev->private;
455 struct comedi_cmd *cmd = &s->async->cmd;
461 if (trig_num != cmd->start_arg)
466 if (!devpriv->ai_cmd_running) {
467 devpriv->ai_cmd_running = 1;
468 ret = usbduxfast_submit_urb(dev);
470 dev_err(dev->class_dev, "urbSubmit: err=%d\n", ret);
471 devpriv->ai_cmd_running = 0;
475 s->async->inttrig = NULL;
477 dev_err(dev->class_dev, "ai is already running\n");
483 static int usbduxfast_ai_cmd(struct comedi_device *dev,
484 struct comedi_subdevice *s)
486 struct usbduxfast_private *devpriv = dev->private;
487 struct comedi_cmd *cmd = &s->async->cmd;
488 unsigned int chan, gain, rngmask = 0xff;
491 long steps, steps_tmp;
497 if (devpriv->ai_cmd_running) {
498 dev_err(dev->class_dev, "ai_cmd not possible\n");
502 /* set current channel of the running acquisition to zero */
503 s->async->cur_chan = 0;
506 * ignore the first buffers from the device if there
507 * is an error condition
509 devpriv->ignore = PACKETS_TO_IGNORE;
511 gain = CR_RANGE(cmd->chanlist[0]);
512 for (i = 0; i < cmd->chanlist_len; ++i) {
513 chan = CR_CHAN(cmd->chanlist[i]);
515 dev_err(dev->class_dev,
516 "channels are not consecutive\n");
520 if ((gain != CR_RANGE(cmd->chanlist[i]))
521 && (cmd->chanlist_len > 3)) {
522 dev_err(dev->class_dev,
523 "gain must be the same for all channels\n");
527 if (i >= NUMCHANNELS) {
528 dev_err(dev->class_dev, "chanlist too long\n");
533 if (cmd->convert_src == TRIG_TIMER)
534 steps = (cmd->convert_arg * 30) / 1000;
536 if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
537 dev_err(dev->class_dev,
538 "steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n",
539 steps, cmd->scan_begin_arg);
543 if (steps > MAX_SAMPLING_PERIOD) {
544 dev_err(dev->class_dev, "sampling rate too low\n");
548 if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
549 && (cmd->chanlist_len != 16)) {
550 dev_err(dev->class_dev,
551 "TRIG_EXT only with 1 or 16 channels possible\n");
556 switch (cmd->chanlist_len) {
562 if (CR_RANGE(cmd->chanlist[0]) > 0)
563 rngmask = 0xff - 0x04;
568 * for external trigger: looping in this state until
569 * the RDY0 pin becomes zero
572 /* we loop here until ready has been set */
573 if (cmd->start_src == TRIG_EXT) {
574 /* branch back to state 0 */
575 /* deceision state w/o data */
577 usbduxfast_cmd_data(dev, 0, 0x01, 0x01, rngmask, 0x00);
578 } else { /* we just proceed to state 1 */
579 usbduxfast_cmd_data(dev, 0, 0x01, 0x00, rngmask, 0x00);
582 if (steps < MIN_SAMPLING_PERIOD) {
583 /* for fast single channel aqu without mux */
586 * we just stay here at state 1 and rexecute
587 * the same state this gives us 30MHz sampling
591 /* branch back to state 1 */
592 /* deceision state with data */
594 usbduxfast_cmd_data(dev, 1,
595 0x89, 0x03, rngmask, 0xff);
598 * we loop through two states: data and delay
603 usbduxfast_cmd_data(dev, 1, steps - 1,
604 0x02, rngmask, 0x00);
606 /* branch back to state 1 */
607 /* deceision state w/o data */
609 usbduxfast_cmd_data(dev, 2,
610 0x09, 0x01, rngmask, 0xff);
614 * we loop through 3 states: 2x delay and 1x data
615 * this gives a min sampling rate of 60kHz
618 /* we have 1 state with duration 1 */
621 /* do the first part of the delay */
622 usbduxfast_cmd_data(dev, 1,
623 steps / 2, 0x00, rngmask, 0x00);
625 /* and the second part */
626 usbduxfast_cmd_data(dev, 2, steps - steps / 2,
627 0x00, rngmask, 0x00);
629 /* get the data and branch back */
631 /* branch back to state 1 */
632 /* deceision state w data */
634 usbduxfast_cmd_data(dev, 3,
635 0x09, 0x03, rngmask, 0xff);
642 * commit data to the FIFO
645 if (CR_RANGE(cmd->chanlist[0]) > 0)
646 rngmask = 0xff - 0x04;
651 usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
653 /* we have 1 state with duration 1: state 0 */
654 steps_tmp = steps - 1;
656 if (CR_RANGE(cmd->chanlist[1]) > 0)
657 rngmask = 0xff - 0x04;
661 /* do the first part of the delay */
663 usbduxfast_cmd_data(dev, 1, steps_tmp / 2,
664 0x00, 0xfe & rngmask, 0x00);
666 /* and the second part */
667 usbduxfast_cmd_data(dev, 2, steps_tmp - steps_tmp / 2,
668 0x00, rngmask, 0x00);
671 usbduxfast_cmd_data(dev, 3, 0x01, 0x02, rngmask, 0x00);
674 * we have 2 states with duration 1: step 6 and
677 steps_tmp = steps - 2;
679 if (CR_RANGE(cmd->chanlist[0]) > 0)
680 rngmask = 0xff - 0x04;
684 /* do the first part of the delay */
686 usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
687 0x00, (0xff - 0x02) & rngmask, 0x00);
689 /* and the second part */
690 usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
691 0x00, rngmask, 0x00);
693 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
700 for (j = 0; j < 1; j++) {
703 if (CR_RANGE(cmd->chanlist[j]) > 0)
704 rngmask = 0xff - 0x04;
708 * commit data to the FIFO and do the first part
713 usbduxfast_cmd_data(dev, index, steps / 2,
714 0x02, rngmask, 0x00);
716 if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
717 rngmask = 0xff - 0x04;
721 /* do the second part of the delay */
724 usbduxfast_cmd_data(dev, index + 1, steps - steps / 2,
725 0x00, 0xfe & rngmask, 0x00);
728 /* 2 steps with duration 1: the idele step and step 6: */
729 steps_tmp = steps - 2;
731 /* commit data to the FIFO and do the first part of the delay */
733 usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
734 0x02, rngmask, 0x00);
736 if (CR_RANGE(cmd->chanlist[0]) > 0)
737 rngmask = 0xff - 0x04;
741 /* do the second part of the delay */
744 usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
745 0x00, (0xff - 0x02) & rngmask, 0x00);
747 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
751 if (CR_RANGE(cmd->chanlist[0]) > 0)
752 rngmask = 0xff - 0x04;
756 if (cmd->start_src == TRIG_EXT) {
758 * we loop here until ready has been set
761 /* branch back to state 0 */
762 /* deceision state w/o data */
765 usbduxfast_cmd_data(dev, 0, 0x01, 0x01,
766 (0xff - 0x02) & rngmask, 0x00);
769 * we just proceed to state 1
772 /* 30us reset pulse */
774 usbduxfast_cmd_data(dev, 0, 0xff, 0x00,
775 (0xff - 0x02) & rngmask, 0x00);
778 /* commit data to the FIFO */
780 usbduxfast_cmd_data(dev, 1, 0x01, 0x02, rngmask, 0x00);
782 /* we have 2 states with duration 1 */
785 /* do the first part of the delay */
786 usbduxfast_cmd_data(dev, 2, steps / 2,
787 0x00, 0xfe & rngmask, 0x00);
789 /* and the second part */
790 usbduxfast_cmd_data(dev, 3, steps - steps / 2,
791 0x00, rngmask, 0x00);
793 /* branch back to state 1 */
794 /* deceision state w/o data */
796 usbduxfast_cmd_data(dev, 4, 0x09, 0x01, rngmask, 0xff);
801 dev_err(dev->class_dev, "unsupported combination of channels\n");
806 /* 0 means that the AD commands are sent */
807 result = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
813 if (cmd->stop_src == TRIG_COUNT)
814 devpriv->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg;
816 devpriv->ai_sample_count = 0;
818 if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
819 /* enable this acquisition operation */
820 devpriv->ai_cmd_running = 1;
821 ret = usbduxfast_submit_urb(dev);
823 devpriv->ai_cmd_running = 0;
824 /* fixme: unlink here?? */
828 s->async->inttrig = NULL;
829 } else { /* TRIG_INT */
830 s->async->inttrig = usbduxfast_ai_inttrig;
838 * Mode 0 is used to get a single conversion on demand.
840 static int usbduxfast_ai_insn_read(struct comedi_device *dev,
841 struct comedi_subdevice *s,
842 struct comedi_insn *insn,
845 struct usb_device *usb = comedi_to_usb_dev(dev);
846 struct usbduxfast_private *devpriv = dev->private;
847 unsigned int chan = CR_CHAN(insn->chanspec);
848 unsigned int range = CR_RANGE(insn->chanspec);
849 uint8_t rngmask = range ? (0xff - 0x04) : 0xff;
850 int i, j, n, actual_length;
855 if (devpriv->ai_cmd_running) {
856 dev_err(dev->class_dev,
857 "ai_insn_read not possible, async cmd is running\n");
862 /* set command for the first channel */
864 /* commit data to the FIFO */
866 usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
868 /* do the first part of the delay */
869 usbduxfast_cmd_data(dev, 1, 0x0c, 0x00, 0xfe & rngmask, 0x00);
870 usbduxfast_cmd_data(dev, 2, 0x01, 0x00, 0xfe & rngmask, 0x00);
871 usbduxfast_cmd_data(dev, 3, 0x01, 0x00, 0xfe & rngmask, 0x00);
872 usbduxfast_cmd_data(dev, 4, 0x01, 0x00, 0xfe & rngmask, 0x00);
875 usbduxfast_cmd_data(dev, 5, 0x0c, 0x00, rngmask, 0x00);
876 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
878 ret = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
884 for (i = 0; i < PACKETS_TO_IGNORE; i++) {
885 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
886 devpriv->inbuf, SIZEINBUF,
887 &actual_length, 10000);
889 dev_err(dev->class_dev, "insn timeout, no data\n");
895 for (i = 0; i < insn->n;) {
896 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
897 devpriv->inbuf, SIZEINBUF,
898 &actual_length, 10000);
900 dev_err(dev->class_dev, "insn data error: %d\n", ret);
904 n = actual_length / sizeof(uint16_t);
906 dev_err(dev->class_dev, "insn data packet corrupted\n");
910 for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
911 data[i] = ((uint16_t *) (devpriv->inbuf))[j];
921 static int usbduxfast_attach_common(struct comedi_device *dev)
923 struct usbduxfast_private *devpriv = dev->private;
924 struct comedi_subdevice *s;
929 ret = comedi_alloc_subdevices(dev, 1);
935 /* Analog Input subdevice */
936 s = &dev->subdevices[0];
937 dev->read_subdev = s;
938 s->type = COMEDI_SUBD_AI;
939 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
941 s->len_chanlist = 16;
942 s->insn_read = usbduxfast_ai_insn_read;
943 s->do_cmdtest = usbduxfast_ai_cmdtest;
944 s->do_cmd = usbduxfast_ai_cmd;
945 s->cancel = usbduxfast_ai_cancel;
947 s->range_table = &range_usbduxfast_ai_range;
954 static int usbduxfast_upload_firmware(struct comedi_device *dev,
955 const u8 *data, size_t size,
956 unsigned long context)
958 struct usb_device *usb = comedi_to_usb_dev(dev);
966 if (size > FIRMWARE_MAX_LEN) {
967 dev_err(dev->class_dev, "firmware binary too large for FX2\n");
971 /* we generate a local buffer for the firmware */
972 buf = kmemdup(data, size, GFP_KERNEL);
976 /* we need a malloc'ed buffer for usb_control_msg() */
977 tmp = kmalloc(1, GFP_KERNEL);
983 /* stop the current firmware on the device */
984 *tmp = 1; /* 7f92 to one */
985 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
986 USBDUXFASTSUB_FIRMWARE,
988 USBDUXFASTSUB_CPUCS, 0x0000,
992 dev_err(dev->class_dev, "can not stop firmware\n");
996 /* upload the new firmware to the device */
997 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
998 USBDUXFASTSUB_FIRMWARE,
1004 dev_err(dev->class_dev, "firmware upload failed\n");
1008 /* start the new firmware on the device */
1009 *tmp = 0; /* 7f92 to zero */
1010 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1011 USBDUXFASTSUB_FIRMWARE,
1013 USBDUXFASTSUB_CPUCS, 0x0000,
1017 dev_err(dev->class_dev, "can not start firmware\n");
1025 static int usbduxfast_auto_attach(struct comedi_device *dev,
1026 unsigned long context_unused)
1028 struct usb_interface *intf = comedi_to_usb_interface(dev);
1029 struct usb_device *usb = comedi_to_usb_dev(dev);
1030 struct usbduxfast_private *devpriv;
1033 if (usb->speed != USB_SPEED_HIGH) {
1034 dev_err(dev->class_dev,
1035 "This driver needs USB 2.0 to operate. Aborting...\n");
1039 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1043 sema_init(&devpriv->sem, 1);
1044 usb_set_intfdata(intf, devpriv);
1046 devpriv->duxbuf = kmalloc(SIZEOFDUXBUF, GFP_KERNEL);
1047 if (!devpriv->duxbuf)
1050 ret = usb_set_interface(usb,
1051 intf->altsetting->desc.bInterfaceNumber, 1);
1053 dev_err(dev->class_dev,
1054 "could not switch to alternate setting 1\n");
1058 devpriv->urb = usb_alloc_urb(0, GFP_KERNEL);
1059 if (!devpriv->urb) {
1060 dev_err(dev->class_dev, "Could not alloc. urb\n");
1064 devpriv->inbuf = kmalloc(SIZEINBUF, GFP_KERNEL);
1065 if (!devpriv->inbuf)
1068 ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1069 usbduxfast_upload_firmware, 0);
1073 return usbduxfast_attach_common(dev);
1076 static void usbduxfast_detach(struct comedi_device *dev)
1078 struct usb_interface *intf = comedi_to_usb_interface(dev);
1079 struct usbduxfast_private *devpriv = dev->private;
1084 down(&devpriv->sem);
1086 usb_set_intfdata(intf, NULL);
1089 /* waits until a running transfer is over */
1090 usb_kill_urb(devpriv->urb);
1092 kfree(devpriv->inbuf);
1093 devpriv->inbuf = NULL;
1095 usb_free_urb(devpriv->urb);
1096 devpriv->urb = NULL;
1099 kfree(devpriv->duxbuf);
1100 devpriv->duxbuf = NULL;
1102 devpriv->ai_cmd_running = 0;
1107 static struct comedi_driver usbduxfast_driver = {
1108 .driver_name = "usbduxfast",
1109 .module = THIS_MODULE,
1110 .auto_attach = usbduxfast_auto_attach,
1111 .detach = usbduxfast_detach,
1114 static int usbduxfast_usb_probe(struct usb_interface *intf,
1115 const struct usb_device_id *id)
1117 return comedi_usb_auto_config(intf, &usbduxfast_driver, 0);
1120 static const struct usb_device_id usbduxfast_usb_table[] = {
1121 /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
1122 { USB_DEVICE(0x13d8, 0x0010) }, /* real ID */
1123 { USB_DEVICE(0x13d8, 0x0011) }, /* real ID */
1126 MODULE_DEVICE_TABLE(usb, usbduxfast_usb_table);
1128 static struct usb_driver usbduxfast_usb_driver = {
1129 .name = "usbduxfast",
1130 .probe = usbduxfast_usb_probe,
1131 .disconnect = comedi_usb_auto_unconfig,
1132 .id_table = usbduxfast_usb_table,
1134 module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver);
1136 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1137 MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com");
1138 MODULE_LICENSE("GPL");
1139 MODULE_FIRMWARE(FIRMWARE);