2 comedi/drivers/usbdux.c
3 Copyright (C) 2011 Bernd Porr, Bernd.Porr@f2s.com
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
17 Description: University of Stirling USB DAQ & INCITE Technology Limited
18 Devices: [ITL] USB-DUX (usbduxsigma.o)
19 Author: Bernd Porr <BerndPorr@f2s.com>
24 * I must give credit here to Chris Baugher who
25 * wrote the driver for AT-MIO-16d. I used some parts of this
26 * driver. I also must give credits to David Brownell
27 * who supported me with the USB development.
29 * Note: the raw data from the A/D converter is 24 bit big endian
30 * anything else is little endian to/from the dux board
34 * 0.1: initial version
35 * 0.2: all basic functions implemented, digital I/O only for one port
36 * 0.3: proper vendor ID and driver name
37 * 0.4: fixed D/A voltage range
38 * 0.5: various bug fixes, health check at startup
39 * 0.6: corrected wrong input range
42 #include <linux/kernel.h>
43 #include <linux/module.h>
44 #include <linux/init.h>
45 #include <linux/slab.h>
46 #include <linux/input.h>
47 #include <linux/usb.h>
48 #include <linux/fcntl.h>
49 #include <linux/compiler.h>
51 #include "comedi_fc.h"
52 #include "../comedidev.h"
54 /* timeout for the USB-transfer in ms*/
55 #define BULK_TIMEOUT 1000
57 /* constants for "firmware" upload and download */
58 #define FIRMWARE "usbduxsigma_firmware.bin"
59 #define FIRMWARE_MAX_LEN 0x4000
60 #define USBDUXSUB_FIRMWARE 0xa0
61 #define VENDOR_DIR_IN 0xc0
62 #define VENDOR_DIR_OUT 0x40
64 /* internal addresses of the 8051 processor */
65 #define USBDUXSUB_CPUCS 0xE600
68 #define USBDUXSIGMA_CMD_OUT_EP 1 /* command output */
69 #define USBDUXSIGMA_ISO_OUT_EP 2 /* analog output ISO/IRQ */
70 #define USBDUXSIGMA_PWM_OUT_EP 4 /* pwm output */
71 #define USBDUXSIGMA_ISO_IN_EP 6 /* analog input ISO/IRQ */
72 #define USBDUXSIGMA_CMD_IN_EP 8 /* command input */
74 /* 300Hz max frequ under PWM */
75 #define MIN_PWM_PERIOD ((long)(1E9/300))
77 /* Default PWM frequency */
78 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
80 /* Number of channels (16 AD and offset)*/
81 #define NUMCHANNELS 16
83 #define USBDUXSIGMA_NUM_AO_CHAN 4
85 /* Size of one A/D value */
86 #define SIZEADIN ((sizeof(int32_t)))
89 * Size of the async input-buffer IN BYTES, the DIO state is transmitted
92 #define SIZEINBUF (((NUMCHANNELS+1)*SIZEADIN))
95 #define SIZEINSNBUF 16
97 /* Number of DA channels */
98 #define NUMOUTCHANNELS 8
100 /* size of one value for the D/A converter: channel and value */
101 #define SIZEDAOUT ((sizeof(uint8_t)+sizeof(int16_t)))
104 * Size of the output-buffer in bytes
105 * Actually only the first 4 triplets are used but for the
106 * high speed mode we need to pad it to 8 (microframes).
108 #define SIZEOUTBUF ((8*SIZEDAOUT))
111 * Size of the buffer for the dux commands: just now max size is determined
112 * by the analogue out + command byte + panic bytes...
114 #define SIZEOFDUXBUFFER ((8*SIZEDAOUT+2))
116 /* Number of in-URBs which receive the data: min=2 */
117 #define NUMOFINBUFFERSFULL 5
119 /* Number of out-URBs which send the data: min=2 */
120 #define NUMOFOUTBUFFERSFULL 5
122 /* Number of in-URBs which receive the data: min=5 */
123 /* must have more buffers due to buggy USB ctr */
124 #define NUMOFINBUFFERSHIGH 10
126 /* Number of out-URBs which send the data: min=5 */
127 /* must have more buffers due to buggy USB ctr */
128 #define NUMOFOUTBUFFERSHIGH 10
130 /* number of retries to get the right dux command */
133 /* bulk transfer commands to usbduxsigma */
134 #define USBBUXSIGMA_AD_CMD 0
135 #define USBDUXSIGMA_DA_CMD 1
136 #define USBDUXSIGMA_DIO_CFG_CMD 2
137 #define USBDUXSIGMA_DIO_BITS_CMD 3
138 #define USBDUXSIGMA_SINGLE_AD_CMD 4
139 #define USBDUXSIGMA_PWM_ON_CMD 7
140 #define USBDUXSIGMA_PWM_OFF_CMD 8
142 static const struct comedi_lrange usbduxsigma_ai_range = {
144 BIP_RANGE(2.65 / 2.0)
148 struct usbduxsigma_private {
149 /* actual number of in-buffers */
151 /* actual number of out-buffers */
153 /* ISO-transfer handling: buffers */
154 struct urb **ai_urbs;
155 struct urb **ao_urbs;
156 /* pwm-transfer handling */
159 unsigned int pwm_period;
160 /* PWM internal delay for the GPIF in the FX2 */
162 /* size of the PWM buffer which holds the bit pattern */
164 /* input buffer for the ISO-transfer */
166 /* input buffer for single insn */
169 unsigned int ao_readback[USBDUXSIGMA_NUM_AO_CHAN];
171 unsigned high_speed:1;
172 unsigned ai_cmd_running:1;
173 unsigned ai_continuous:1;
174 unsigned ao_cmd_running:1;
175 unsigned ao_continuous:1;
176 unsigned pwm_cmd_running:1;
178 /* number of samples to acquire */
181 /* time between samples in units of the timer */
182 unsigned int ai_timer;
183 unsigned int ao_timer;
184 /* counter between acquisitions */
185 unsigned int ai_counter;
186 unsigned int ao_counter;
187 /* interval in frames/uframes */
188 unsigned int ai_interval;
190 uint8_t *dac_commands;
192 uint8_t *dux_commands;
193 struct semaphore sem;
196 static void usbduxsigma_ai_stop(struct comedi_device *dev, int do_unlink)
198 struct usbduxsigma_private *devpriv = dev->private;
203 for (i = 0; i < devpriv->n_ai_urbs; i++) {
204 if (devpriv->ai_urbs[i])
205 usb_kill_urb(devpriv->ai_urbs[i]);
209 devpriv->ai_cmd_running = 0;
212 static int usbduxsigma_ai_cancel(struct comedi_device *dev,
213 struct comedi_subdevice *s)
215 struct usbduxsigma_private *devpriv = dev->private;
218 /* unlink only if it is really running */
219 usbduxsigma_ai_stop(dev, devpriv->ai_cmd_running);
225 static void usbduxsigma_ai_urb_complete(struct urb *urb)
227 struct comedi_device *dev = urb->context;
228 struct usbduxsigma_private *devpriv = dev->private;
229 struct comedi_subdevice *s = dev->read_subdev;
230 unsigned int dio_state;
235 /* first we test if something unusual has just happened */
236 switch (urb->status) {
238 /* copy the result in the transfer buffer */
239 memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF);
243 * error in the ISOchronous data
244 * we don't copy the data into the transfer buffer
245 * and recycle the last data byte
247 dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
255 /* happens after an unlink command */
256 if (devpriv->ai_cmd_running) {
257 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
258 /* we are still running a command, tell comedi */
259 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
260 comedi_event(dev, s);
266 * a real error on the bus
267 * pass error to comedi if we are really running a command
269 if (devpriv->ai_cmd_running) {
270 dev_err(dev->class_dev,
271 "%s: non-zero urb status (%d)\n",
272 __func__, urb->status);
273 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
274 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
275 comedi_event(dev, s);
280 if (unlikely(!devpriv->ai_cmd_running))
283 urb->dev = comedi_to_usb_dev(dev);
285 ret = usb_submit_urb(urb, GFP_ATOMIC);
286 if (unlikely(ret < 0)) {
287 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
289 if (ret == -EL2NSYNC)
290 dev_err(dev->class_dev,
291 "buggy USB host controller or bug in IRQ handler\n");
292 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
293 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
294 comedi_event(dev, s);
298 /* get the state of the dio pins to allow external trigger */
299 dio_state = be32_to_cpu(devpriv->in_buf[0]);
301 devpriv->ai_counter--;
302 if (likely(devpriv->ai_counter > 0))
305 /* timer zero, transfer measurements to comedi */
306 devpriv->ai_counter = devpriv->ai_timer;
308 if (!devpriv->ai_continuous) {
309 /* not continuous, fixed number of samples */
310 devpriv->ai_sample_count--;
311 if (devpriv->ai_sample_count < 0) {
312 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
313 /* acquistion is over, tell comedi */
314 s->async->events |= COMEDI_CB_EOA;
315 comedi_event(dev, s);
320 /* get the data from the USB bus and hand it over to comedi */
321 for (i = 0; i < s->async->cmd.chanlist_len; i++) {
322 /* transfer data, note first byte is the DIO state */
323 val = be32_to_cpu(devpriv->in_buf[i+1]);
324 val &= 0x00ffffff; /* strip status byte */
325 val ^= 0x00800000; /* convert to unsigned */
327 ret = cfc_write_array_to_buffer(s, &val, sizeof(uint32_t));
328 if (unlikely(ret == 0)) {
329 /* buffer overflow */
330 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
334 /* tell comedi that data is there */
335 s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
336 comedi_event(dev, s);
339 static void usbduxsigma_ao_stop(struct comedi_device *dev, int do_unlink)
341 struct usbduxsigma_private *devpriv = dev->private;
346 for (i = 0; i < devpriv->n_ao_urbs; i++) {
347 if (devpriv->ao_urbs[i])
348 usb_kill_urb(devpriv->ao_urbs[i]);
352 devpriv->ao_cmd_running = 0;
355 static int usbduxsigma_ao_cancel(struct comedi_device *dev,
356 struct comedi_subdevice *s)
358 struct usbduxsigma_private *devpriv = dev->private;
361 /* unlink only if it is really running */
362 usbduxsigma_ao_stop(dev, devpriv->ao_cmd_running);
368 static void usbduxsigma_ao_urb_complete(struct urb *urb)
370 struct comedi_device *dev = urb->context;
371 struct usbduxsigma_private *devpriv = dev->private;
372 struct comedi_subdevice *s = dev->write_subdev;
378 switch (urb->status) {
387 /* happens after an unlink command */
388 if (devpriv->ao_cmd_running) {
389 usbduxsigma_ao_stop(dev, 0); /* w/o unlink */
390 s->async->events |= COMEDI_CB_EOA;
391 comedi_event(dev, s);
397 if (devpriv->ao_cmd_running) {
398 dev_err(dev->class_dev,
399 "%s: non-zero urb status (%d)\n",
400 __func__, urb->status);
401 usbduxsigma_ao_stop(dev, 0); /* w/o unlink */
402 s->async->events |= (COMEDI_CB_ERROR | COMEDI_CB_EOA);
403 comedi_event(dev, s);
408 if (!devpriv->ao_cmd_running)
411 devpriv->ao_counter--;
412 if ((int)devpriv->ao_counter <= 0) {
413 /* timer zero, transfer from comedi */
414 devpriv->ao_counter = devpriv->ao_timer;
416 if (!devpriv->ao_continuous) {
417 /* not continuous, fixed number of samples */
418 devpriv->ao_sample_count--;
419 if (devpriv->ao_sample_count < 0) {
420 usbduxsigma_ao_stop(dev, 0); /* w/o unlink */
421 /* acquistion is over, tell comedi */
422 s->async->events |= COMEDI_CB_EOA;
423 comedi_event(dev, s);
428 /* transmit data to the USB bus */
429 datap = urb->transfer_buffer;
430 len = s->async->cmd.chanlist_len;
432 for (i = 0; i < len; i++) {
433 unsigned int chan = devpriv->dac_commands[i];
436 ret = comedi_buf_get(s->async, &val);
438 dev_err(dev->class_dev, "buffer underflow\n");
439 s->async->events |= (COMEDI_CB_EOA |
444 devpriv->ao_readback[chan] = val;
446 s->async->events |= COMEDI_CB_BLOCK;
447 comedi_event(dev, s);
451 urb->transfer_buffer_length = SIZEOUTBUF;
452 urb->dev = comedi_to_usb_dev(dev);
454 if (devpriv->high_speed)
455 urb->interval = 8; /* uframes */
457 urb->interval = 1; /* frames */
458 urb->number_of_packets = 1;
459 urb->iso_frame_desc[0].offset = 0;
460 urb->iso_frame_desc[0].length = SIZEOUTBUF;
461 urb->iso_frame_desc[0].status = 0;
462 ret = usb_submit_urb(urb, GFP_ATOMIC);
464 dev_err(dev->class_dev,
465 "%s: urb resubmit failed (%d)\n",
468 dev_err(dev->class_dev,
469 "buggy USB host controller or bug in IRQ handler\n");
470 usbduxsigma_ao_stop(dev, 0); /* w/o unlink */
471 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
472 comedi_event(dev, s);
476 static int usbduxsigma_submit_urbs(struct comedi_device *dev,
477 struct urb **urbs, int num_urbs,
480 struct usb_device *usb = comedi_to_usb_dev(dev);
481 struct usbduxsigma_private *devpriv = dev->private;
486 /* Submit all URBs and start the transfer on the bus */
487 for (i = 0; i < num_urbs; i++) {
490 /* in case of a resubmission after an unlink... */
492 urb->interval = devpriv->ai_interval;
496 urb->transfer_flags = URB_ISO_ASAP;
498 ret = usb_submit_urb(urb, GFP_ATOMIC);
505 static int usbduxsigma_chans_to_interval(int num_chan)
514 static int usbduxsigma_ai_cmdtest(struct comedi_device *dev,
515 struct comedi_subdevice *s,
516 struct comedi_cmd *cmd)
518 struct usbduxsigma_private *devpriv = dev->private;
519 int high_speed = devpriv->high_speed;
520 int interval = usbduxsigma_chans_to_interval(cmd->chanlist_len);
523 /* Step 1 : check if triggers are trivially valid */
525 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
526 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
527 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
528 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
529 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
534 /* Step 2a : make sure trigger sources are unique */
536 err |= cfc_check_trigger_is_unique(cmd->start_src);
537 err |= cfc_check_trigger_is_unique(cmd->stop_src);
539 /* Step 2b : and mutually compatible */
544 /* Step 3: check if arguments are trivially valid */
546 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
548 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
549 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
551 if (cmd->scan_begin_src == TRIG_TIMER) {
556 * In high speed mode microframes are possible.
557 * However, during one microframe we can roughly
558 * sample two channels. Thus, the more channels
559 * are in the channel list the more time we need.
561 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
562 (1000000 / 8 * interval));
564 tmp = (cmd->scan_begin_arg / 125000) * 125000;
567 /* 1kHz scans every USB frame */
568 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
571 tmp = (cmd->scan_begin_arg / 1000000) * 1000000;
573 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, tmp);
576 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
578 if (cmd->stop_src == TRIG_COUNT) {
579 /* any count is allowed */
582 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
588 /* Step 4: fix up any arguments */
592 * every 2 channels get a time window of 125us. Thus, if we
593 * sample all 16 channels we need 1ms. If we sample only one
594 * channel we need only 125us
596 devpriv->ai_interval = interval;
597 devpriv->ai_timer = cmd->scan_begin_arg / (125000 * interval);
599 /* interval always 1ms */
600 devpriv->ai_interval = 1;
601 devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
603 if (devpriv->ai_timer < 1)
606 if (cmd->stop_src == TRIG_COUNT) {
607 /* data arrives as one packet */
608 devpriv->ai_sample_count = cmd->stop_arg;
609 devpriv->ai_continuous = 0;
611 /* continuous acquisition */
612 devpriv->ai_continuous = 1;
613 devpriv->ai_sample_count = 0;
623 * creates the ADC command for the MAX1271
624 * range is the range value from comedi
626 static void create_adc_command(unsigned int chan,
631 (*muxsg0) = (*muxsg0) | (1 << chan);
633 (*muxsg1) = (*muxsg1) | (1 << (chan-8));
636 static int usbbuxsigma_send_cmd(struct comedi_device *dev, int cmd_type)
638 struct usb_device *usb = comedi_to_usb_dev(dev);
639 struct usbduxsigma_private *devpriv = dev->private;
642 devpriv->dux_commands[0] = cmd_type;
644 return usb_bulk_msg(usb, usb_sndbulkpipe(usb, USBDUXSIGMA_CMD_OUT_EP),
645 devpriv->dux_commands, SIZEOFDUXBUFFER,
646 &nsent, BULK_TIMEOUT);
649 static int usbduxsigma_receive_cmd(struct comedi_device *dev, int command)
651 struct usb_device *usb = comedi_to_usb_dev(dev);
652 struct usbduxsigma_private *devpriv = dev->private;
657 for (i = 0; i < RETRIES; i++) {
658 ret = usb_bulk_msg(usb,
659 usb_rcvbulkpipe(usb, USBDUXSIGMA_CMD_IN_EP),
660 devpriv->insn_buf, SIZEINSNBUF,
661 &nrec, BULK_TIMEOUT);
665 if (devpriv->insn_buf[0] == command)
669 * This is only reached if the data has been requested a
670 * couple of times and the command was not received.
675 static int usbduxsigma_ai_inttrig(struct comedi_device *dev,
676 struct comedi_subdevice *s,
677 unsigned int trignum)
679 struct usbduxsigma_private *devpriv = dev->private;
686 if (!devpriv->ai_cmd_running) {
687 ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
688 devpriv->n_ai_urbs, 1);
693 devpriv->ai_cmd_running = 1;
694 s->async->inttrig = NULL;
701 static int usbduxsigma_ai_cmd(struct comedi_device *dev,
702 struct comedi_subdevice *s)
704 struct usbduxsigma_private *devpriv = dev->private;
705 struct comedi_cmd *cmd = &s->async->cmd;
706 unsigned int len = cmd->chanlist_len;
715 /* set current channel of the running acquisition to zero */
716 s->async->cur_chan = 0;
717 for (i = 0; i < len; i++) {
718 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
720 create_adc_command(chan, &muxsg0, &muxsg1);
723 devpriv->dux_commands[1] = len; /* num channels per time step */
724 devpriv->dux_commands[2] = 0x12; /* CONFIG0 */
725 devpriv->dux_commands[3] = 0x03; /* CONFIG1: 23kHz sample, delay 0us */
726 devpriv->dux_commands[4] = 0x00; /* CONFIG3: diff. channels off */
727 devpriv->dux_commands[5] = muxsg0;
728 devpriv->dux_commands[6] = muxsg1;
729 devpriv->dux_commands[7] = sysred;
731 ret = usbbuxsigma_send_cmd(dev, USBBUXSIGMA_AD_CMD);
737 devpriv->ai_counter = devpriv->ai_timer;
739 if (cmd->start_src == TRIG_NOW) {
740 /* enable this acquisition operation */
741 ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
742 devpriv->n_ai_urbs, 1);
747 s->async->inttrig = NULL;
748 devpriv->ai_cmd_running = 1;
749 } else { /* TRIG_INT */
750 /* wait for an internal signal and submit the urbs later */
751 s->async->inttrig = usbduxsigma_ai_inttrig;
759 static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
760 struct comedi_subdevice *s,
761 struct comedi_insn *insn,
764 struct usbduxsigma_private *devpriv = dev->private;
765 unsigned int chan = CR_CHAN(insn->chanspec);
773 if (devpriv->ai_cmd_running) {
778 create_adc_command(chan, &muxsg0, &muxsg1);
780 /* Mode 0 is used to get a single conversion on demand */
781 devpriv->dux_commands[1] = 0x16; /* CONFIG0: chopper on */
782 devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
783 devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
784 devpriv->dux_commands[4] = muxsg0;
785 devpriv->dux_commands[5] = muxsg1;
786 devpriv->dux_commands[6] = sysred;
789 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
795 for (i = 0; i < insn->n; i++) {
798 ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
804 /* 32 bits big endian from the A/D converter */
805 val = be32_to_cpu(*((int32_t *)((devpriv->insn_buf) + 1)));
806 val &= 0x00ffffff; /* strip status byte */
807 val ^= 0x00800000; /* convert to unsigned */
816 static int usbduxsigma_ao_insn_read(struct comedi_device *dev,
817 struct comedi_subdevice *s,
818 struct comedi_insn *insn,
821 struct usbduxsigma_private *devpriv = dev->private;
822 unsigned int chan = CR_CHAN(insn->chanspec);
826 for (i = 0; i < insn->n; i++)
827 data[i] = devpriv->ao_readback[chan];
833 static int usbduxsigma_ao_insn_write(struct comedi_device *dev,
834 struct comedi_subdevice *s,
835 struct comedi_insn *insn,
838 struct usbduxsigma_private *devpriv = dev->private;
839 unsigned int chan = CR_CHAN(insn->chanspec);
844 if (devpriv->ao_cmd_running) {
849 for (i = 0; i < insn->n; i++) {
850 devpriv->dux_commands[1] = 1; /* num channels */
851 devpriv->dux_commands[2] = data[i]; /* value */
852 devpriv->dux_commands[3] = chan; /* channel number */
853 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DA_CMD);
858 devpriv->ao_readback[chan] = data[i];
865 static int usbduxsigma_ao_inttrig(struct comedi_device *dev,
866 struct comedi_subdevice *s,
867 unsigned int trignum)
869 struct usbduxsigma_private *devpriv = dev->private;
876 if (!devpriv->ao_cmd_running) {
877 ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
878 devpriv->n_ao_urbs, 0);
883 devpriv->ao_cmd_running = 1;
884 s->async->inttrig = NULL;
891 static int usbduxsigma_ao_cmdtest(struct comedi_device *dev,
892 struct comedi_subdevice *s,
893 struct comedi_cmd *cmd)
895 struct usbduxsigma_private *devpriv = dev->private;
900 /* high speed conversions are not used yet */
901 high_speed = 0; /* (devpriv->high_speed) */
903 /* Step 1 : check if triggers are trivially valid */
905 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
909 * start immediately a new scan
910 * the sampling rate is set by the coversion rate
914 /* start a new scan (output at once) with a timer */
917 err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
919 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
920 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
921 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
928 /* Step 2a : make sure trigger sources are unique */
930 err |= cfc_check_trigger_is_unique(cmd->start_src);
931 err |= cfc_check_trigger_is_unique(cmd->stop_src);
933 /* Step 2b : and mutually compatible */
938 /* Step 3: check if arguments are trivially valid */
940 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
942 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
943 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
945 if (cmd->scan_begin_src == TRIG_TIMER)
946 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
949 /* not used now, is for later use */
950 if (cmd->convert_src == TRIG_TIMER)
951 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
953 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
955 if (cmd->stop_src == TRIG_COUNT) {
956 /* any count is allowed */
959 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
965 /* Step 4: fix up any arguments */
967 /* we count in timer steps */
969 /* timing of the conversion itself: every 125 us */
970 devpriv->ao_timer = cmd->convert_arg / 125000;
973 * timing of the scan: every 1ms
974 * we get all channels at once
976 devpriv->ao_timer = cmd->scan_begin_arg / 1000000;
978 if (devpriv->ao_timer < 1)
981 if (cmd->stop_src == TRIG_COUNT) {
982 /* not continuous, use counter */
984 /* high speed also scans everything at once */
985 devpriv->ao_sample_count = cmd->stop_arg *
989 * There's no scan as the scan has been
990 * handled inside the FX2. Data arrives as
993 devpriv->ao_sample_count = cmd->stop_arg;
995 devpriv->ao_continuous = 0;
997 /* continuous acquisition */
998 devpriv->ao_continuous = 1;
999 devpriv->ao_sample_count = 0;
1008 static int usbduxsigma_ao_cmd(struct comedi_device *dev,
1009 struct comedi_subdevice *s)
1011 struct usbduxsigma_private *devpriv = dev->private;
1012 struct comedi_cmd *cmd = &s->async->cmd;
1016 down(&devpriv->sem);
1018 /* set current channel of the running acquisition to zero */
1019 s->async->cur_chan = 0;
1020 for (i = 0; i < cmd->chanlist_len; ++i)
1021 devpriv->dac_commands[i] = CR_CHAN(cmd->chanlist[i]);
1023 devpriv->ao_counter = devpriv->ao_timer;
1025 if (cmd->start_src == TRIG_NOW) {
1026 /* enable this acquisition operation */
1027 ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
1028 devpriv->n_ao_urbs, 0);
1033 s->async->inttrig = NULL;
1034 devpriv->ao_cmd_running = 1;
1035 } else { /* TRIG_INT */
1036 /* wait for an internal signal and submit the urbs later */
1037 s->async->inttrig = usbduxsigma_ao_inttrig;
1045 static int usbduxsigma_dio_insn_config(struct comedi_device *dev,
1046 struct comedi_subdevice *s,
1047 struct comedi_insn *insn,
1050 unsigned int chan = CR_CHAN(insn->chanspec);
1051 unsigned int mask = 1 << chan;
1054 case INSN_CONFIG_DIO_OUTPUT:
1057 case INSN_CONFIG_DIO_INPUT:
1058 s->io_bits &= ~mask;
1060 case INSN_CONFIG_DIO_QUERY:
1061 data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
1069 * We don't tell the firmware here as it would take 8 frames
1070 * to submit the information. We do it in the (*insn_bits).
1075 static int usbduxsigma_dio_insn_bits(struct comedi_device *dev,
1076 struct comedi_subdevice *s,
1077 struct comedi_insn *insn,
1080 struct usbduxsigma_private *devpriv = dev->private;
1081 unsigned int mask = data[0];
1082 unsigned int bits = data[1];
1085 down(&devpriv->sem);
1088 s->state |= (bits & mask);
1090 devpriv->dux_commands[1] = s->io_bits & 0xff;
1091 devpriv->dux_commands[4] = s->state & 0xff;
1092 devpriv->dux_commands[2] = (s->io_bits >> 8) & 0xff;
1093 devpriv->dux_commands[5] = (s->state >> 8) & 0xff;
1094 devpriv->dux_commands[3] = (s->io_bits >> 16) & 0xff;
1095 devpriv->dux_commands[6] = (s->state >> 16) & 0xff;
1097 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
1100 ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
1104 s->state = devpriv->insn_buf[1] |
1105 (devpriv->insn_buf[2] << 8) |
1106 (devpriv->insn_buf[3] << 16);
1117 static void usbduxsigma_pwm_stop(struct comedi_device *dev, int do_unlink)
1119 struct usbduxsigma_private *devpriv = dev->private;
1122 if (devpriv->pwm_urb)
1123 usb_kill_urb(devpriv->pwm_urb);
1126 devpriv->pwm_cmd_running = 0;
1129 static int usbduxsigma_pwm_cancel(struct comedi_device *dev,
1130 struct comedi_subdevice *s)
1132 struct usbduxsigma_private *devpriv = dev->private;
1134 /* unlink only if it is really running */
1135 usbduxsigma_pwm_stop(dev, devpriv->pwm_cmd_running);
1137 return usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_OFF_CMD);
1140 static void usbduxsigma_pwm_urb_complete(struct urb *urb)
1142 struct comedi_device *dev = urb->context;
1143 struct usbduxsigma_private *devpriv = dev->private;
1146 switch (urb->status) {
1155 /* happens after an unlink command */
1156 if (devpriv->pwm_cmd_running)
1157 usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */
1162 if (devpriv->pwm_cmd_running) {
1163 dev_err(dev->class_dev,
1164 "%s: non-zero urb status (%d)\n",
1165 __func__, urb->status);
1166 usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */
1171 if (!devpriv->pwm_cmd_running)
1174 urb->transfer_buffer_length = devpriv->pwm_buf_sz;
1175 urb->dev = comedi_to_usb_dev(dev);
1177 ret = usb_submit_urb(urb, GFP_ATOMIC);
1179 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
1181 if (ret == EL2NSYNC)
1182 dev_err(dev->class_dev,
1183 "buggy USB host controller or bug in IRQ handler\n");
1184 usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */
1188 static int usbduxsigma_submit_pwm_urb(struct comedi_device *dev)
1190 struct usb_device *usb = comedi_to_usb_dev(dev);
1191 struct usbduxsigma_private *devpriv = dev->private;
1192 struct urb *urb = devpriv->pwm_urb;
1194 /* in case of a resubmission after an unlink... */
1195 usb_fill_bulk_urb(urb,
1196 usb, usb_sndbulkpipe(usb, USBDUXSIGMA_PWM_OUT_EP),
1197 urb->transfer_buffer, devpriv->pwm_buf_sz,
1198 usbduxsigma_pwm_urb_complete, dev);
1200 return usb_submit_urb(urb, GFP_ATOMIC);
1203 static int usbduxsigma_pwm_period(struct comedi_device *dev,
1204 struct comedi_subdevice *s,
1205 unsigned int period)
1207 struct usbduxsigma_private *devpriv = dev->private;
1210 if (period < MIN_PWM_PERIOD) {
1213 fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
1217 devpriv->pwm_delay = fx2delay;
1218 devpriv->pwm_period = period;
1222 static int usbduxsigma_pwm_start(struct comedi_device *dev,
1223 struct comedi_subdevice *s)
1225 struct usbduxsigma_private *devpriv = dev->private;
1228 if (devpriv->pwm_cmd_running)
1231 devpriv->dux_commands[1] = devpriv->pwm_delay;
1232 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_ON_CMD);
1236 memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);
1238 ret = usbduxsigma_submit_pwm_urb(dev);
1241 devpriv->pwm_cmd_running = 1;
1246 static int usbduxsigma_pwm_pattern(struct comedi_device *dev,
1247 struct comedi_subdevice *s,
1252 struct usbduxsigma_private *devpriv = dev->private;
1253 char pwm_mask = (1 << chan); /* DIO bit for the PWM data */
1254 char sgn_mask = (16 << chan); /* DIO bit for the sign */
1255 char *buf = (char *)(devpriv->pwm_urb->transfer_buffer);
1256 int szbuf = devpriv->pwm_buf_sz;
1259 for (i = 0; i < szbuf; i++) {
1274 static int usbduxsigma_pwm_write(struct comedi_device *dev,
1275 struct comedi_subdevice *s,
1276 struct comedi_insn *insn,
1279 unsigned int chan = CR_CHAN(insn->chanspec);
1282 * It doesn't make sense to support more than one value here
1283 * because it would just overwrite the PWM buffer.
1289 * The sign is set via a special INSN only, this gives us 8 bits
1290 * for normal operation, sign is 0 by default.
1292 return usbduxsigma_pwm_pattern(dev, s, chan, data[0], 0);
1295 static int usbduxsigma_pwm_config(struct comedi_device *dev,
1296 struct comedi_subdevice *s,
1297 struct comedi_insn *insn,
1300 struct usbduxsigma_private *devpriv = dev->private;
1301 unsigned int chan = CR_CHAN(insn->chanspec);
1304 case INSN_CONFIG_ARM:
1306 * if not zero the PWM is limited to a certain time which is
1307 * not supported here
1311 return usbduxsigma_pwm_start(dev, s);
1312 case INSN_CONFIG_DISARM:
1313 return usbduxsigma_pwm_cancel(dev, s);
1314 case INSN_CONFIG_GET_PWM_STATUS:
1315 data[1] = devpriv->pwm_cmd_running;
1317 case INSN_CONFIG_PWM_SET_PERIOD:
1318 return usbduxsigma_pwm_period(dev, s, data[1]);
1319 case INSN_CONFIG_PWM_GET_PERIOD:
1320 data[1] = devpriv->pwm_period;
1322 case INSN_CONFIG_PWM_SET_H_BRIDGE:
1325 * data[2] = sign (for a relay)
1327 return usbduxsigma_pwm_pattern(dev, s, chan,
1328 data[1], (data[2] != 0));
1329 case INSN_CONFIG_PWM_GET_H_BRIDGE:
1330 /* values are not kept in this driver, nothing to return */
1336 static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan)
1338 struct usbduxsigma_private *devpriv = dev->private;
1346 sysred = 0; /* ADC zero */
1349 sysred = 1; /* ADC offset */
1352 sysred = 4; /* VCC */
1355 sysred = 8; /* temperature */
1358 sysred = 16; /* gain */
1361 sysred = 32; /* ref */
1365 devpriv->dux_commands[1] = 0x12; /* CONFIG0 */
1366 devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
1367 devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
1368 devpriv->dux_commands[4] = 0;
1369 devpriv->dux_commands[5] = 0;
1370 devpriv->dux_commands[6] = sysred;
1371 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
1375 ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
1379 /* 32 bits big endian from the A/D converter */
1380 val = be32_to_cpu(*((int32_t *)((devpriv->insn_buf)+1)));
1381 val &= 0x00ffffff; /* strip status byte */
1382 val ^= 0x00800000; /* convert to unsigned */
1387 static int usbduxsigma_attach_common(struct comedi_device *dev)
1389 struct usbduxsigma_private *devpriv = dev->private;
1390 struct comedi_subdevice *s;
1395 down(&devpriv->sem);
1397 if (devpriv->high_speed)
1398 n_subdevs = 4; /* with pwm */
1400 n_subdevs = 3; /* without pwm */
1401 ret = comedi_alloc_subdevices(dev, n_subdevs);
1407 /* Analog Input subdevice */
1408 s = &dev->subdevices[0];
1409 dev->read_subdev = s;
1410 s->type = COMEDI_SUBD_AI;
1411 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ | SDF_LSAMPL;
1412 s->n_chan = NUMCHANNELS;
1413 s->len_chanlist = NUMCHANNELS;
1414 s->maxdata = 0x00ffffff;
1415 s->range_table = &usbduxsigma_ai_range;
1416 s->insn_read = usbduxsigma_ai_insn_read;
1417 s->do_cmdtest = usbduxsigma_ai_cmdtest;
1418 s->do_cmd = usbduxsigma_ai_cmd;
1419 s->cancel = usbduxsigma_ai_cancel;
1421 /* Analog Output subdevice */
1422 s = &dev->subdevices[1];
1423 dev->write_subdev = s;
1424 s->type = COMEDI_SUBD_AO;
1425 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1426 s->n_chan = USBDUXSIGMA_NUM_AO_CHAN;
1427 s->len_chanlist = s->n_chan;
1428 s->maxdata = 0x00ff;
1429 s->range_table = &range_unipolar2_5;
1430 s->insn_write = usbduxsigma_ao_insn_write;
1431 s->insn_read = usbduxsigma_ao_insn_read;
1432 s->do_cmdtest = usbduxsigma_ao_cmdtest;
1433 s->do_cmd = usbduxsigma_ao_cmd;
1434 s->cancel = usbduxsigma_ao_cancel;
1436 /* Digital I/O subdevice */
1437 s = &dev->subdevices[2];
1438 s->type = COMEDI_SUBD_DIO;
1439 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1442 s->range_table = &range_digital;
1443 s->insn_bits = usbduxsigma_dio_insn_bits;
1444 s->insn_config = usbduxsigma_dio_insn_config;
1446 if (devpriv->high_speed) {
1447 /* Timer / pwm subdevice */
1448 s = &dev->subdevices[3];
1449 s->type = COMEDI_SUBD_PWM;
1450 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1452 s->maxdata = devpriv->pwm_buf_sz;
1453 s->insn_write = usbduxsigma_pwm_write;
1454 s->insn_config = usbduxsigma_pwm_config;
1456 usbduxsigma_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1461 offset = usbduxsigma_getstatusinfo(dev, 0);
1463 dev_err(dev->class_dev,
1464 "Communication to USBDUXSIGMA failed! Check firmware and cabling\n");
1466 dev_info(dev->class_dev, "attached, ADC_zero = %x\n", offset);
1471 static int usbduxsigma_firmware_upload(struct comedi_device *dev,
1472 const u8 *data, size_t size,
1473 unsigned long context)
1475 struct usb_device *usb = comedi_to_usb_dev(dev);
1483 if (size > FIRMWARE_MAX_LEN) {
1484 dev_err(dev->class_dev, "firmware binary too large for FX2\n");
1488 /* we generate a local buffer for the firmware */
1489 buf = kmemdup(data, size, GFP_KERNEL);
1493 /* we need a malloc'ed buffer for usb_control_msg() */
1494 tmp = kmalloc(1, GFP_KERNEL);
1500 /* stop the current firmware on the device */
1501 *tmp = 1; /* 7f92 to one */
1502 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1505 USBDUXSUB_CPUCS, 0x0000,
1509 dev_err(dev->class_dev, "can not stop firmware\n");
1513 /* upload the new firmware to the device */
1514 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1521 dev_err(dev->class_dev, "firmware upload failed\n");
1525 /* start the new firmware on the device */
1526 *tmp = 0; /* 7f92 to zero */
1527 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1530 USBDUXSUB_CPUCS, 0x0000,
1534 dev_err(dev->class_dev, "can not start firmware\n");
1542 static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev)
1544 struct usb_device *usb = comedi_to_usb_dev(dev);
1545 struct usbduxsigma_private *devpriv = dev->private;
1549 devpriv->dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
1550 devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1551 devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL);
1552 devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1553 devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(*urb),
1555 devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(*urb),
1557 if (!devpriv->dac_commands || !devpriv->dux_commands ||
1558 !devpriv->in_buf || !devpriv->insn_buf ||
1559 !devpriv->ai_urbs || !devpriv->ao_urbs)
1562 for (i = 0; i < devpriv->n_ai_urbs; i++) {
1563 /* one frame: 1ms */
1564 urb = usb_alloc_urb(1, GFP_KERNEL);
1567 devpriv->ai_urbs[i] = urb;
1569 /* will be filled later with a pointer to the comedi-device */
1570 /* and ONLY then the urb should be submitted */
1571 urb->context = NULL;
1572 urb->pipe = usb_rcvisocpipe(usb, USBDUXSIGMA_ISO_IN_EP);
1573 urb->transfer_flags = URB_ISO_ASAP;
1574 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1575 if (!urb->transfer_buffer)
1577 urb->complete = usbduxsigma_ai_urb_complete;
1578 urb->number_of_packets = 1;
1579 urb->transfer_buffer_length = SIZEINBUF;
1580 urb->iso_frame_desc[0].offset = 0;
1581 urb->iso_frame_desc[0].length = SIZEINBUF;
1584 for (i = 0; i < devpriv->n_ao_urbs; i++) {
1585 /* one frame: 1ms */
1586 urb = usb_alloc_urb(1, GFP_KERNEL);
1589 devpriv->ao_urbs[i] = urb;
1591 /* will be filled later with a pointer to the comedi-device */
1592 /* and ONLY then the urb should be submitted */
1593 urb->context = NULL;
1594 urb->pipe = usb_sndisocpipe(usb, USBDUXSIGMA_ISO_OUT_EP);
1595 urb->transfer_flags = URB_ISO_ASAP;
1596 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1597 if (!urb->transfer_buffer)
1599 urb->complete = usbduxsigma_ao_urb_complete;
1600 urb->number_of_packets = 1;
1601 urb->transfer_buffer_length = SIZEOUTBUF;
1602 urb->iso_frame_desc[0].offset = 0;
1603 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1604 if (devpriv->high_speed)
1605 urb->interval = 8; /* uframes */
1607 urb->interval = 1; /* frames */
1610 if (devpriv->high_speed) {
1611 /* max bulk ep size in high speed */
1612 devpriv->pwm_buf_sz = 512;
1613 urb = usb_alloc_urb(0, GFP_KERNEL);
1616 devpriv->pwm_urb = urb;
1617 urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz, GFP_KERNEL);
1618 if (!urb->transfer_buffer)
1621 devpriv->pwm_urb = NULL;
1622 devpriv->pwm_buf_sz = 0;
1628 static void usbduxsigma_free_usb_buffers(struct comedi_device *dev)
1630 struct usbduxsigma_private *devpriv = dev->private;
1634 /* force unlink all urbs */
1635 usbduxsigma_ai_stop(dev, 1);
1636 usbduxsigma_ao_stop(dev, 1);
1637 usbduxsigma_pwm_stop(dev, 1);
1639 urb = devpriv->pwm_urb;
1641 kfree(urb->transfer_buffer);
1644 if (devpriv->ao_urbs) {
1645 for (i = 0; i < devpriv->n_ao_urbs; i++) {
1646 urb = devpriv->ao_urbs[i];
1648 kfree(urb->transfer_buffer);
1652 kfree(devpriv->ao_urbs);
1654 if (devpriv->ai_urbs) {
1655 for (i = 0; i < devpriv->n_ai_urbs; i++) {
1656 urb = devpriv->ai_urbs[i];
1658 kfree(urb->transfer_buffer);
1662 kfree(devpriv->ai_urbs);
1664 kfree(devpriv->insn_buf);
1665 kfree(devpriv->in_buf);
1666 kfree(devpriv->dux_commands);
1667 kfree(devpriv->dac_commands);
1670 static int usbduxsigma_auto_attach(struct comedi_device *dev,
1671 unsigned long context_unused)
1673 struct usb_interface *intf = comedi_to_usb_interface(dev);
1674 struct usb_device *usb = comedi_to_usb_dev(dev);
1675 struct usbduxsigma_private *devpriv;
1678 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1681 dev->private = devpriv;
1683 sema_init(&devpriv->sem, 1);
1684 usb_set_intfdata(intf, devpriv);
1686 ret = usb_set_interface(usb,
1687 intf->altsetting->desc.bInterfaceNumber, 3);
1689 dev_err(dev->class_dev,
1690 "could not set alternate setting 3 in high speed\n");
1694 /* test if it is high speed (USB 2.0) */
1695 devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1696 if (devpriv->high_speed) {
1697 devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH;
1698 devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH;
1700 devpriv->n_ai_urbs = NUMOFINBUFFERSFULL;
1701 devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL;
1704 ret = usbduxsigma_alloc_usb_buffers(dev);
1708 ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1709 usbduxsigma_firmware_upload, 0);
1713 return usbduxsigma_attach_common(dev);
1716 static void usbduxsigma_detach(struct comedi_device *dev)
1718 struct usb_interface *intf = comedi_to_usb_interface(dev);
1719 struct usbduxsigma_private *devpriv = dev->private;
1724 usb_set_intfdata(intf, NULL);
1726 down(&devpriv->sem);
1727 usbduxsigma_free_usb_buffers(dev);
1731 static struct comedi_driver usbduxsigma_driver = {
1732 .driver_name = "usbduxsigma",
1733 .module = THIS_MODULE,
1734 .auto_attach = usbduxsigma_auto_attach,
1735 .detach = usbduxsigma_detach,
1738 static int usbduxsigma_usb_probe(struct usb_interface *intf,
1739 const struct usb_device_id *id)
1741 return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0);
1744 static const struct usb_device_id usbduxsigma_usb_table[] = {
1745 { USB_DEVICE(0x13d8, 0x0020) },
1746 { USB_DEVICE(0x13d8, 0x0021) },
1747 { USB_DEVICE(0x13d8, 0x0022) },
1750 MODULE_DEVICE_TABLE(usb, usbduxsigma_usb_table);
1752 static struct usb_driver usbduxsigma_usb_driver = {
1753 .name = "usbduxsigma",
1754 .probe = usbduxsigma_usb_probe,
1755 .disconnect = comedi_usb_auto_unconfig,
1756 .id_table = usbduxsigma_usb_table,
1758 module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver);
1760 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1761 MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com");
1762 MODULE_LICENSE("GPL");
1763 MODULE_FIRMWARE(FIRMWARE);