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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
38 #include <linux/kernel.h>
39 #include <linux/module.h>
40 #include <linux/init.h>
41 #include <linux/slab.h>
42 #include <linux/input.h>
43 #include <linux/usb.h>
44 #include <linux/fcntl.h>
45 #include <linux/compiler.h>
46 #include "comedi_fc.h"
47 #include "../comedidev.h"
50 * timeout for the USB-transfer
55 * constants for "firmware" upload and download
57 #define FIRMWARE "usbduxfast_firmware.bin"
58 #define FIRMWARE_MAX_LEN 0x2000
59 #define USBDUXFASTSUB_FIRMWARE 0xA0
60 #define VENDOR_DIR_IN 0xC0
61 #define VENDOR_DIR_OUT 0x40
64 * internal addresses of the 8051 processor
66 #define USBDUXFASTSUB_CPUCS 0xE600
69 * max lenghth of the transfer-buffer for software upload
74 * input endpoint number
79 * endpoint for the A/D channellist: bulk OUT
81 #define CHANNELLISTEP 4
86 #define NUMCHANNELS 32
89 * size of the waveform descriptor
94 * size of one A/D value
96 #define SIZEADIN (sizeof(int16_t))
99 * size of the input-buffer IN BYTES
101 #define SIZEINBUF 512
106 #define SIZEINSNBUF 512
109 * size of the buffer for the dux commands in bytes
111 #define SIZEOFDUXBUF 256
114 * number of in-URBs which receive the data: min=5
116 #define NUMOFINBUFFERSHIGH 10
119 * min delay steps for more than one channel
120 * basically when the mux gives up ;-)
122 * steps at 30MHz in the FX2
124 #define MIN_SAMPLING_PERIOD 9
127 * max number of 1/30MHz delay steps
129 #define MAX_SAMPLING_PERIOD 500
132 * number of received packets to ignore before we start handing data
133 * over to comedi, it's quad buffering and we have to ignore 4 packets
135 #define PACKETS_TO_IGNORE 4
140 static const struct comedi_lrange range_usbduxfast_ai_range = {
141 2, {BIP_RANGE(0.75), BIP_RANGE(0.5)}
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 short int ai_continous; /* continous acquisition */
156 long int ai_sample_count; /* number of samples to acquire */
157 int ignore; /* counter which ignores the first
159 struct semaphore sem;
163 * bulk transfers to usbduxfast
165 #define SENDADCOMMANDS 0
166 #define SENDINITEP6 1
168 static int usbduxfast_send_cmd(struct comedi_device *dev, int cmd_type)
170 struct usb_device *usb = comedi_to_usb_dev(dev);
171 struct usbduxfast_private *devpriv = dev->private;
175 devpriv->duxbuf[0] = cmd_type;
177 ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, CHANNELLISTEP),
178 devpriv->duxbuf, SIZEOFDUXBUF,
181 dev_err(dev->class_dev,
182 "could not transmit command to the usb-device, err=%d\n",
187 static void usbduxfast_cmd_data(struct comedi_device *dev, int index,
188 uint8_t len, uint8_t op, uint8_t out,
191 struct usbduxfast_private *devpriv = dev->private;
193 /* Set the GPIF bytes, the first byte is the command byte */
194 devpriv->duxbuf[1 + 0x00 + index] = len;
195 devpriv->duxbuf[1 + 0x08 + index] = op;
196 devpriv->duxbuf[1 + 0x10 + index] = out;
197 devpriv->duxbuf[1 + 0x18 + index] = log;
200 static int usbduxfast_ai_stop(struct comedi_device *dev, int do_unlink)
202 struct usbduxfast_private *devpriv = dev->private;
205 devpriv->ai_cmd_running = 0;
207 if (do_unlink && devpriv->urb) {
208 /* kill the running transfer */
209 usb_kill_urb(devpriv->urb);
215 static int usbduxfast_ai_cancel(struct comedi_device *dev,
216 struct comedi_subdevice *s)
218 struct usbduxfast_private *devpriv = dev->private;
225 ret = usbduxfast_ai_stop(dev, 1);
233 * interrupt service routine
235 static void usbduxfast_ai_interrupt(struct urb *urb)
237 struct comedi_device *dev = urb->context;
238 struct comedi_subdevice *s = dev->read_subdev;
239 struct comedi_async *async = s->async;
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 pr_err("non-zero urb status received in ai intr context: %d\n",
278 async->events |= COMEDI_CB_EOA;
279 async->events |= COMEDI_CB_ERROR;
280 comedi_event(dev, s);
281 usbduxfast_ai_stop(dev, 0);
285 if (!devpriv->ignore) {
286 if (!devpriv->ai_continous) {
287 /* not continuous, fixed number of samples */
288 n = urb->actual_length / sizeof(uint16_t);
289 if (unlikely(devpriv->ai_sample_count < n)) {
290 unsigned int num_bytes;
292 /* partial sample received */
293 num_bytes = devpriv->ai_sample_count *
295 cfc_write_array_to_buffer(s,
296 urb->transfer_buffer,
298 usbduxfast_ai_stop(dev, 0);
299 /* tell comedi that the acquistion is over */
300 async->events |= COMEDI_CB_EOA;
301 comedi_event(dev, s);
304 devpriv->ai_sample_count -= n;
306 /* write the full buffer to comedi */
307 err = cfc_write_array_to_buffer(s, urb->transfer_buffer,
309 if (unlikely(err == 0)) {
310 /* buffer overflow */
311 usbduxfast_ai_stop(dev, 0);
315 /* tell comedi that data is there */
316 comedi_event(dev, s);
318 /* ignore this packet */
323 * command is still running
324 * resubmit urb for BULK transfer
328 err = usb_submit_urb(urb, GFP_ATOMIC);
330 dev_err(dev->class_dev,
331 "urb resubm failed: %d", err);
332 async->events |= COMEDI_CB_EOA;
333 async->events |= COMEDI_CB_ERROR;
334 comedi_event(dev, s);
335 usbduxfast_ai_stop(dev, 0);
339 static int usbduxfast_submit_urb(struct comedi_device *dev)
341 struct usb_device *usb = comedi_to_usb_dev(dev);
342 struct usbduxfast_private *devpriv = dev->private;
348 usb_fill_bulk_urb(devpriv->urb, usb, usb_rcvbulkpipe(usb, BULKINEP),
349 devpriv->inbuf, SIZEINBUF,
350 usbduxfast_ai_interrupt, dev);
352 ret = usb_submit_urb(devpriv->urb, GFP_ATOMIC);
354 dev_err(dev->class_dev, "usb_submit_urb error %d\n", ret);
360 static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
361 struct comedi_subdevice *s,
362 struct comedi_cmd *cmd)
366 int min_sample_period;
368 /* Step 1 : check if triggers are trivially valid */
370 err |= cfc_check_trigger_src(&cmd->start_src,
371 TRIG_NOW | TRIG_EXT | TRIG_INT);
372 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
373 TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
374 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
375 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
376 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
381 /* Step 2a : make sure trigger sources are unique */
383 err |= cfc_check_trigger_is_unique(cmd->start_src);
384 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
385 err |= cfc_check_trigger_is_unique(cmd->convert_src);
386 err |= cfc_check_trigger_is_unique(cmd->stop_src);
388 /* Step 2b : and mutually compatible */
390 /* can't have external stop and start triggers at once */
391 if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
397 /* Step 3: check if arguments are trivially valid */
399 if (cmd->start_src == TRIG_NOW)
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);
425 if (cmd->scan_begin_src == TRIG_TIMER)
429 switch (cmd->stop_src) {
431 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
434 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
437 * TRIG_EXT doesn't care since it doesn't trigger
438 * off a numbered channel
447 /* step 4: fix up any arguments */
453 static int usbduxfast_ai_inttrig(struct comedi_device *dev,
454 struct comedi_subdevice *s,
455 unsigned int trignum)
457 struct usbduxfast_private *devpriv = dev->private;
466 dev_err(dev->class_dev, "invalid trignum\n");
470 if (!devpriv->ai_cmd_running) {
471 devpriv->ai_cmd_running = 1;
472 ret = usbduxfast_submit_urb(dev);
474 dev_err(dev->class_dev, "urbSubmit: err=%d\n", ret);
475 devpriv->ai_cmd_running = 0;
479 s->async->inttrig = NULL;
481 dev_err(dev->class_dev, "ai is already running\n");
487 static int usbduxfast_ai_cmd(struct comedi_device *dev,
488 struct comedi_subdevice *s)
490 struct usbduxfast_private *devpriv = dev->private;
491 struct comedi_cmd *cmd = &s->async->cmd;
492 unsigned int chan, gain, rngmask = 0xff;
495 long steps, steps_tmp;
501 if (devpriv->ai_cmd_running) {
502 dev_err(dev->class_dev, "ai_cmd not possible\n");
506 /* set current channel of the running acquisition to zero */
507 s->async->cur_chan = 0;
510 * ignore the first buffers from the device if there
511 * is an error condition
513 devpriv->ignore = PACKETS_TO_IGNORE;
515 if (cmd->chanlist_len > 0) {
516 gain = CR_RANGE(cmd->chanlist[0]);
517 for (i = 0; i < cmd->chanlist_len; ++i) {
518 chan = CR_CHAN(cmd->chanlist[i]);
520 dev_err(dev->class_dev,
521 "channels are not consecutive\n");
525 if ((gain != CR_RANGE(cmd->chanlist[i]))
526 && (cmd->chanlist_len > 3)) {
527 dev_err(dev->class_dev,
528 "gain must be the same for all channels\n");
532 if (i >= NUMCHANNELS) {
533 dev_err(dev->class_dev, "chanlist too long\n");
539 if (cmd->scan_begin_src == TRIG_TIMER) {
540 dev_err(dev->class_dev,
541 "scan_begin_src==TRIG_TIMER not valid\n");
545 if (cmd->convert_src == TRIG_TIMER)
546 steps = (cmd->convert_arg * 30) / 1000;
548 if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
549 dev_err(dev->class_dev,
550 "steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n",
551 steps, cmd->scan_begin_arg);
555 if (steps > MAX_SAMPLING_PERIOD) {
556 dev_err(dev->class_dev, "sampling rate too low\n");
560 if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
561 && (cmd->chanlist_len != 16)) {
562 dev_err(dev->class_dev,
563 "TRIG_EXT only with 1 or 16 channels possible\n");
568 switch (cmd->chanlist_len) {
574 if (CR_RANGE(cmd->chanlist[0]) > 0)
575 rngmask = 0xff - 0x04;
580 * for external trigger: looping in this state until
581 * the RDY0 pin becomes zero
584 /* we loop here until ready has been set */
585 if (cmd->start_src == TRIG_EXT) {
586 /* branch back to state 0 */
587 /* deceision state w/o data */
589 usbduxfast_cmd_data(dev, 0, 0x01, 0x01, rngmask, 0x00);
590 } else { /* we just proceed to state 1 */
591 usbduxfast_cmd_data(dev, 0, 0x01, 0x00, rngmask, 0x00);
594 if (steps < MIN_SAMPLING_PERIOD) {
595 /* for fast single channel aqu without mux */
598 * we just stay here at state 1 and rexecute
599 * the same state this gives us 30MHz sampling
603 /* branch back to state 1 */
604 /* deceision state with data */
606 usbduxfast_cmd_data(dev, 1,
607 0x89, 0x03, rngmask, 0xff);
610 * we loop through two states: data and delay
615 usbduxfast_cmd_data(dev, 1, steps - 1,
616 0x02, rngmask, 0x00);
618 /* branch back to state 1 */
619 /* deceision state w/o data */
621 usbduxfast_cmd_data(dev, 2,
622 0x09, 0x01, rngmask, 0xff);
626 * we loop through 3 states: 2x delay and 1x data
627 * this gives a min sampling rate of 60kHz
630 /* we have 1 state with duration 1 */
633 /* do the first part of the delay */
634 usbduxfast_cmd_data(dev, 1,
635 steps / 2, 0x00, rngmask, 0x00);
637 /* and the second part */
638 usbduxfast_cmd_data(dev, 2, steps - steps / 2,
639 0x00, rngmask, 0x00);
641 /* get the data and branch back */
643 /* branch back to state 1 */
644 /* deceision state w data */
646 usbduxfast_cmd_data(dev, 3,
647 0x09, 0x03, rngmask, 0xff);
654 * commit data to the FIFO
657 if (CR_RANGE(cmd->chanlist[0]) > 0)
658 rngmask = 0xff - 0x04;
663 usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
665 /* we have 1 state with duration 1: state 0 */
666 steps_tmp = steps - 1;
668 if (CR_RANGE(cmd->chanlist[1]) > 0)
669 rngmask = 0xff - 0x04;
673 /* do the first part of the delay */
675 usbduxfast_cmd_data(dev, 1, steps_tmp / 2,
676 0x00, 0xfe & rngmask, 0x00);
678 /* and the second part */
679 usbduxfast_cmd_data(dev, 2, steps_tmp - steps_tmp / 2,
680 0x00, rngmask, 0x00);
683 usbduxfast_cmd_data(dev, 3, 0x01, 0x02, rngmask, 0x00);
686 * we have 2 states with duration 1: step 6 and
689 steps_tmp = steps - 2;
691 if (CR_RANGE(cmd->chanlist[0]) > 0)
692 rngmask = 0xff - 0x04;
696 /* do the first part of the delay */
698 usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
699 0x00, (0xff - 0x02) & rngmask, 0x00);
701 /* and the second part */
702 usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
703 0x00, rngmask, 0x00);
705 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
712 for (j = 0; j < 1; j++) {
715 if (CR_RANGE(cmd->chanlist[j]) > 0)
716 rngmask = 0xff - 0x04;
720 * commit data to the FIFO and do the first part
725 usbduxfast_cmd_data(dev, index, steps / 2,
726 0x02, rngmask, 0x00);
728 if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
729 rngmask = 0xff - 0x04;
733 /* do the second part of the delay */
736 usbduxfast_cmd_data(dev, index + 1, steps - steps / 2,
737 0x00, 0xfe & rngmask, 0x00);
740 /* 2 steps with duration 1: the idele step and step 6: */
741 steps_tmp = steps - 2;
743 /* commit data to the FIFO and do the first part of the delay */
745 usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
746 0x02, rngmask, 0x00);
748 if (CR_RANGE(cmd->chanlist[0]) > 0)
749 rngmask = 0xff - 0x04;
753 /* do the second part of the delay */
756 usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
757 0x00, (0xff - 0x02) & rngmask, 0x00);
759 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
762 if (CR_RANGE(cmd->chanlist[0]) > 0)
763 rngmask = 0xff - 0x04;
767 if (cmd->start_src == TRIG_EXT) {
769 * we loop here until ready has been set
772 /* branch back to state 0 */
773 /* deceision state w/o data */
776 usbduxfast_cmd_data(dev, 0, 0x01, 0x01,
777 (0xff - 0x02) & rngmask, 0x00);
780 * we just proceed to state 1
783 /* 30us reset pulse */
785 usbduxfast_cmd_data(dev, 0, 0xff, 0x00,
786 (0xff - 0x02) & rngmask, 0x00);
789 /* commit data to the FIFO */
791 usbduxfast_cmd_data(dev, 1, 0x01, 0x02, rngmask, 0x00);
793 /* we have 2 states with duration 1 */
796 /* do the first part of the delay */
797 usbduxfast_cmd_data(dev, 2, steps / 2,
798 0x00, 0xfe & rngmask, 0x00);
800 /* and the second part */
801 usbduxfast_cmd_data(dev, 3, steps - steps / 2,
802 0x00, rngmask, 0x00);
804 /* branch back to state 1 */
805 /* deceision state w/o data */
807 usbduxfast_cmd_data(dev, 4, 0x09, 0x01, rngmask, 0xff);
812 dev_err(dev->class_dev, "unsupported combination of channels\n");
817 /* 0 means that the AD commands are sent */
818 result = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
823 if (cmd->stop_src == TRIG_COUNT) {
824 devpriv->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg;
825 if (devpriv->ai_sample_count < 1) {
826 dev_err(dev->class_dev,
827 "(cmd->stop_arg)*(cmd->scan_end_arg)<1, aborting\n");
831 devpriv->ai_continous = 0;
833 /* continous acquisition */
834 devpriv->ai_continous = 1;
835 devpriv->ai_sample_count = 0;
838 if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
839 /* enable this acquisition operation */
840 devpriv->ai_cmd_running = 1;
841 ret = usbduxfast_submit_urb(dev);
843 devpriv->ai_cmd_running = 0;
844 /* fixme: unlink here?? */
848 s->async->inttrig = NULL;
852 * don't enable the acquision operation
853 * wait for an internal signal
855 s->async->inttrig = usbduxfast_ai_inttrig;
863 * Mode 0 is used to get a single conversion on demand.
865 static int usbduxfast_ai_insn_read(struct comedi_device *dev,
866 struct comedi_subdevice *s,
867 struct comedi_insn *insn,
870 struct usb_device *usb = comedi_to_usb_dev(dev);
871 struct usbduxfast_private *devpriv = dev->private;
872 unsigned int chan = CR_CHAN(insn->chanspec);
873 unsigned int range = CR_RANGE(insn->chanspec);
874 uint8_t rngmask = range ? (0xff - 0x04) : 0xff;
875 int i, j, n, actual_length;
880 if (devpriv->ai_cmd_running) {
881 dev_err(dev->class_dev,
882 "ai_insn_read not possible, async cmd is running\n");
887 /* set command for the first channel */
889 /* commit data to the FIFO */
891 usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
893 /* do the first part of the delay */
894 usbduxfast_cmd_data(dev, 1, 0x0c, 0x00, 0xfe & rngmask, 0x00);
895 usbduxfast_cmd_data(dev, 2, 0x01, 0x00, 0xfe & rngmask, 0x00);
896 usbduxfast_cmd_data(dev, 3, 0x01, 0x00, 0xfe & rngmask, 0x00);
897 usbduxfast_cmd_data(dev, 4, 0x01, 0x00, 0xfe & rngmask, 0x00);
900 usbduxfast_cmd_data(dev, 5, 0x0c, 0x00, rngmask, 0x00);
901 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
903 ret = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
909 for (i = 0; i < PACKETS_TO_IGNORE; i++) {
910 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
911 devpriv->inbuf, SIZEINBUF,
912 &actual_length, 10000);
914 dev_err(dev->class_dev, "insn timeout, no data\n");
920 for (i = 0; i < insn->n;) {
921 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
922 devpriv->inbuf, SIZEINBUF,
923 &actual_length, 10000);
925 dev_err(dev->class_dev, "insn data error: %d\n", ret);
929 n = actual_length / sizeof(uint16_t);
931 dev_err(dev->class_dev, "insn data packet corrupted\n");
935 for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
936 data[i] = ((uint16_t *) (devpriv->inbuf))[j];
946 static int usbduxfast_attach_common(struct comedi_device *dev)
948 struct usbduxfast_private *devpriv = dev->private;
949 struct comedi_subdevice *s;
954 ret = comedi_alloc_subdevices(dev, 1);
960 /* Analog Input subdevice */
961 s = &dev->subdevices[0];
962 dev->read_subdev = s;
963 s->type = COMEDI_SUBD_AI;
964 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
966 s->len_chanlist = 16;
967 s->insn_read = usbduxfast_ai_insn_read;
968 s->do_cmdtest = usbduxfast_ai_cmdtest;
969 s->do_cmd = usbduxfast_ai_cmd;
970 s->cancel = usbduxfast_ai_cancel;
972 s->range_table = &range_usbduxfast_ai_range;
979 static int usbduxfast_upload_firmware(struct comedi_device *dev,
980 const u8 *data, size_t size,
981 unsigned long context)
983 struct usb_device *usb = comedi_to_usb_dev(dev);
991 if (size > FIRMWARE_MAX_LEN) {
992 dev_err(dev->class_dev, "firmware binary too large for FX2\n");
996 /* we generate a local buffer for the firmware */
997 buf = kmemdup(data, size, GFP_KERNEL);
1001 /* we need a malloc'ed buffer for usb_control_msg() */
1002 tmp = kmalloc(1, GFP_KERNEL);
1008 /* stop the current firmware on the device */
1009 *tmp = 1; /* 7f92 to one */
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 stop firmware\n");
1021 /* upload the new firmware to the device */
1022 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1023 USBDUXFASTSUB_FIRMWARE,
1029 dev_err(dev->class_dev, "firmware upload failed\n");
1033 /* start the new firmware on the device */
1034 *tmp = 0; /* 7f92 to zero */
1035 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1036 USBDUXFASTSUB_FIRMWARE,
1038 USBDUXFASTSUB_CPUCS, 0x0000,
1042 dev_err(dev->class_dev, "can not start firmware\n");
1050 static int usbduxfast_auto_attach(struct comedi_device *dev,
1051 unsigned long context_unused)
1053 struct usb_interface *intf = comedi_to_usb_interface(dev);
1054 struct usb_device *usb = comedi_to_usb_dev(dev);
1055 struct usbduxfast_private *devpriv;
1058 if (usb->speed != USB_SPEED_HIGH) {
1059 dev_err(dev->class_dev,
1060 "This driver needs USB 2.0 to operate. Aborting...\n");
1064 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1068 sema_init(&devpriv->sem, 1);
1069 usb_set_intfdata(intf, devpriv);
1071 devpriv->duxbuf = kmalloc(SIZEOFDUXBUF, GFP_KERNEL);
1072 if (!devpriv->duxbuf)
1075 ret = usb_set_interface(usb,
1076 intf->altsetting->desc.bInterfaceNumber, 1);
1078 dev_err(dev->class_dev,
1079 "could not switch to alternate setting 1\n");
1083 devpriv->urb = usb_alloc_urb(0, GFP_KERNEL);
1084 if (!devpriv->urb) {
1085 dev_err(dev->class_dev, "Could not alloc. urb\n");
1089 devpriv->inbuf = kmalloc(SIZEINBUF, GFP_KERNEL);
1090 if (!devpriv->inbuf)
1093 ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1094 usbduxfast_upload_firmware, 0);
1098 return usbduxfast_attach_common(dev);
1101 static void usbduxfast_detach(struct comedi_device *dev)
1103 struct usb_interface *intf = comedi_to_usb_interface(dev);
1104 struct usbduxfast_private *devpriv = dev->private;
1109 down(&devpriv->sem);
1111 usb_set_intfdata(intf, NULL);
1114 /* waits until a running transfer is over */
1115 usb_kill_urb(devpriv->urb);
1117 kfree(devpriv->inbuf);
1118 devpriv->inbuf = NULL;
1120 usb_free_urb(devpriv->urb);
1121 devpriv->urb = NULL;
1124 kfree(devpriv->duxbuf);
1125 devpriv->duxbuf = NULL;
1127 devpriv->ai_cmd_running = 0;
1132 static struct comedi_driver usbduxfast_driver = {
1133 .driver_name = "usbduxfast",
1134 .module = THIS_MODULE,
1135 .auto_attach = usbduxfast_auto_attach,
1136 .detach = usbduxfast_detach,
1139 static int usbduxfast_usb_probe(struct usb_interface *intf,
1140 const struct usb_device_id *id)
1142 return comedi_usb_auto_config(intf, &usbduxfast_driver, 0);
1145 static const struct usb_device_id usbduxfast_usb_table[] = {
1146 /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
1147 { USB_DEVICE(0x13d8, 0x0010) }, /* real ID */
1148 { USB_DEVICE(0x13d8, 0x0011) }, /* real ID */
1151 MODULE_DEVICE_TABLE(usb, usbduxfast_usb_table);
1153 static struct usb_driver usbduxfast_usb_driver = {
1154 .name = "usbduxfast",
1155 .probe = usbduxfast_usb_probe,
1156 .disconnect = comedi_usb_auto_unconfig,
1157 .id_table = usbduxfast_usb_table,
1159 module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver);
1161 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1162 MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com");
1163 MODULE_LICENSE("GPL");
1164 MODULE_FIRMWARE(FIRMWARE);