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);
750 if (CR_RANGE(cmd->chanlist[0]) > 0)
751 rngmask = 0xff - 0x04;
755 if (cmd->start_src == TRIG_EXT) {
757 * we loop here until ready has been set
760 /* branch back to state 0 */
761 /* deceision state w/o data */
764 usbduxfast_cmd_data(dev, 0, 0x01, 0x01,
765 (0xff - 0x02) & rngmask, 0x00);
768 * we just proceed to state 1
771 /* 30us reset pulse */
773 usbduxfast_cmd_data(dev, 0, 0xff, 0x00,
774 (0xff - 0x02) & rngmask, 0x00);
777 /* commit data to the FIFO */
779 usbduxfast_cmd_data(dev, 1, 0x01, 0x02, rngmask, 0x00);
781 /* we have 2 states with duration 1 */
784 /* do the first part of the delay */
785 usbduxfast_cmd_data(dev, 2, steps / 2,
786 0x00, 0xfe & rngmask, 0x00);
788 /* and the second part */
789 usbduxfast_cmd_data(dev, 3, steps - steps / 2,
790 0x00, rngmask, 0x00);
792 /* branch back to state 1 */
793 /* deceision state w/o data */
795 usbduxfast_cmd_data(dev, 4, 0x09, 0x01, rngmask, 0xff);
800 dev_err(dev->class_dev, "unsupported combination of channels\n");
805 /* 0 means that the AD commands are sent */
806 result = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
812 if (cmd->stop_src == TRIG_COUNT)
813 devpriv->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg;
815 devpriv->ai_sample_count = 0;
817 if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
818 /* enable this acquisition operation */
819 devpriv->ai_cmd_running = 1;
820 ret = usbduxfast_submit_urb(dev);
822 devpriv->ai_cmd_running = 0;
823 /* fixme: unlink here?? */
827 s->async->inttrig = NULL;
828 } else { /* TRIG_INT */
829 s->async->inttrig = usbduxfast_ai_inttrig;
837 * Mode 0 is used to get a single conversion on demand.
839 static int usbduxfast_ai_insn_read(struct comedi_device *dev,
840 struct comedi_subdevice *s,
841 struct comedi_insn *insn,
844 struct usb_device *usb = comedi_to_usb_dev(dev);
845 struct usbduxfast_private *devpriv = dev->private;
846 unsigned int chan = CR_CHAN(insn->chanspec);
847 unsigned int range = CR_RANGE(insn->chanspec);
848 uint8_t rngmask = range ? (0xff - 0x04) : 0xff;
849 int i, j, n, actual_length;
854 if (devpriv->ai_cmd_running) {
855 dev_err(dev->class_dev,
856 "ai_insn_read not possible, async cmd is running\n");
861 /* set command for the first channel */
863 /* commit data to the FIFO */
865 usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
867 /* do the first part of the delay */
868 usbduxfast_cmd_data(dev, 1, 0x0c, 0x00, 0xfe & rngmask, 0x00);
869 usbduxfast_cmd_data(dev, 2, 0x01, 0x00, 0xfe & rngmask, 0x00);
870 usbduxfast_cmd_data(dev, 3, 0x01, 0x00, 0xfe & rngmask, 0x00);
871 usbduxfast_cmd_data(dev, 4, 0x01, 0x00, 0xfe & rngmask, 0x00);
874 usbduxfast_cmd_data(dev, 5, 0x0c, 0x00, rngmask, 0x00);
875 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
877 ret = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
883 for (i = 0; i < PACKETS_TO_IGNORE; i++) {
884 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
885 devpriv->inbuf, SIZEINBUF,
886 &actual_length, 10000);
888 dev_err(dev->class_dev, "insn timeout, no data\n");
894 for (i = 0; i < insn->n;) {
895 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
896 devpriv->inbuf, SIZEINBUF,
897 &actual_length, 10000);
899 dev_err(dev->class_dev, "insn data error: %d\n", ret);
903 n = actual_length / sizeof(uint16_t);
905 dev_err(dev->class_dev, "insn data packet corrupted\n");
909 for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
910 data[i] = ((uint16_t *) (devpriv->inbuf))[j];
920 static int usbduxfast_attach_common(struct comedi_device *dev)
922 struct usbduxfast_private *devpriv = dev->private;
923 struct comedi_subdevice *s;
928 ret = comedi_alloc_subdevices(dev, 1);
934 /* Analog Input subdevice */
935 s = &dev->subdevices[0];
936 dev->read_subdev = s;
937 s->type = COMEDI_SUBD_AI;
938 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
940 s->len_chanlist = 16;
941 s->insn_read = usbduxfast_ai_insn_read;
942 s->do_cmdtest = usbduxfast_ai_cmdtest;
943 s->do_cmd = usbduxfast_ai_cmd;
944 s->cancel = usbduxfast_ai_cancel;
946 s->range_table = &range_usbduxfast_ai_range;
953 static int usbduxfast_upload_firmware(struct comedi_device *dev,
954 const u8 *data, size_t size,
955 unsigned long context)
957 struct usb_device *usb = comedi_to_usb_dev(dev);
965 if (size > FIRMWARE_MAX_LEN) {
966 dev_err(dev->class_dev, "firmware binary too large for FX2\n");
970 /* we generate a local buffer for the firmware */
971 buf = kmemdup(data, size, GFP_KERNEL);
975 /* we need a malloc'ed buffer for usb_control_msg() */
976 tmp = kmalloc(1, GFP_KERNEL);
982 /* stop the current firmware on the device */
983 *tmp = 1; /* 7f92 to one */
984 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
985 USBDUXFASTSUB_FIRMWARE,
987 USBDUXFASTSUB_CPUCS, 0x0000,
991 dev_err(dev->class_dev, "can not stop firmware\n");
995 /* upload the new firmware to the device */
996 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
997 USBDUXFASTSUB_FIRMWARE,
1003 dev_err(dev->class_dev, "firmware upload failed\n");
1007 /* start the new firmware on the device */
1008 *tmp = 0; /* 7f92 to zero */
1009 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1010 USBDUXFASTSUB_FIRMWARE,
1012 USBDUXFASTSUB_CPUCS, 0x0000,
1016 dev_err(dev->class_dev, "can not start firmware\n");
1024 static int usbduxfast_auto_attach(struct comedi_device *dev,
1025 unsigned long context_unused)
1027 struct usb_interface *intf = comedi_to_usb_interface(dev);
1028 struct usb_device *usb = comedi_to_usb_dev(dev);
1029 struct usbduxfast_private *devpriv;
1032 if (usb->speed != USB_SPEED_HIGH) {
1033 dev_err(dev->class_dev,
1034 "This driver needs USB 2.0 to operate. Aborting...\n");
1038 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1042 sema_init(&devpriv->sem, 1);
1043 usb_set_intfdata(intf, devpriv);
1045 devpriv->duxbuf = kmalloc(SIZEOFDUXBUF, GFP_KERNEL);
1046 if (!devpriv->duxbuf)
1049 ret = usb_set_interface(usb,
1050 intf->altsetting->desc.bInterfaceNumber, 1);
1052 dev_err(dev->class_dev,
1053 "could not switch to alternate setting 1\n");
1057 devpriv->urb = usb_alloc_urb(0, GFP_KERNEL);
1058 if (!devpriv->urb) {
1059 dev_err(dev->class_dev, "Could not alloc. urb\n");
1063 devpriv->inbuf = kmalloc(SIZEINBUF, GFP_KERNEL);
1064 if (!devpriv->inbuf)
1067 ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1068 usbduxfast_upload_firmware, 0);
1072 return usbduxfast_attach_common(dev);
1075 static void usbduxfast_detach(struct comedi_device *dev)
1077 struct usb_interface *intf = comedi_to_usb_interface(dev);
1078 struct usbduxfast_private *devpriv = dev->private;
1083 down(&devpriv->sem);
1085 usb_set_intfdata(intf, NULL);
1088 /* waits until a running transfer is over */
1089 usb_kill_urb(devpriv->urb);
1091 kfree(devpriv->inbuf);
1092 devpriv->inbuf = NULL;
1094 usb_free_urb(devpriv->urb);
1095 devpriv->urb = NULL;
1098 kfree(devpriv->duxbuf);
1099 devpriv->duxbuf = NULL;
1101 devpriv->ai_cmd_running = 0;
1106 static struct comedi_driver usbduxfast_driver = {
1107 .driver_name = "usbduxfast",
1108 .module = THIS_MODULE,
1109 .auto_attach = usbduxfast_auto_attach,
1110 .detach = usbduxfast_detach,
1113 static int usbduxfast_usb_probe(struct usb_interface *intf,
1114 const struct usb_device_id *id)
1116 return comedi_usb_auto_config(intf, &usbduxfast_driver, 0);
1119 static const struct usb_device_id usbduxfast_usb_table[] = {
1120 /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
1121 { USB_DEVICE(0x13d8, 0x0010) }, /* real ID */
1122 { USB_DEVICE(0x13d8, 0x0011) }, /* real ID */
1125 MODULE_DEVICE_TABLE(usb, usbduxfast_usb_table);
1127 static struct usb_driver usbduxfast_usb_driver = {
1128 .name = "usbduxfast",
1129 .probe = usbduxfast_usb_probe,
1130 .disconnect = comedi_usb_auto_unconfig,
1131 .id_table = usbduxfast_usb_table,
1133 module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver);
1135 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1136 MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com");
1137 MODULE_LICENSE("GPL");
1138 MODULE_FIRMWARE(FIRMWARE);