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.
18 * Description: University of Stirling USB DAQ & INCITE Technology Limited
19 * Devices: (ITL) USB-DUX [usbduxsigma]
20 * Author: Bernd Porr <BerndPorr@f2s.com>
26 * I must give credit here to Chris Baugher who
27 * wrote the driver for AT-MIO-16d. I used some parts of this
28 * driver. I also must give credits to David Brownell
29 * who supported me with the USB development.
31 * Note: the raw data from the A/D converter is 24 bit big endian
32 * anything else is little endian to/from the dux board
36 * 0.1: initial version
37 * 0.2: all basic functions implemented, digital I/O only for one port
38 * 0.3: proper vendor ID and driver name
39 * 0.4: fixed D/A voltage range
40 * 0.5: various bug fixes, health check at startup
41 * 0.6: corrected wrong input range
44 #include <linux/kernel.h>
45 #include <linux/module.h>
46 #include <linux/slab.h>
47 #include <linux/input.h>
48 #include <linux/usb.h>
49 #include <linux/fcntl.h>
50 #include <linux/compiler.h>
51 #include <asm/unaligned.h>
53 #include "comedi_fc.h"
54 #include "../comedidev.h"
56 /* timeout for the USB-transfer in ms*/
57 #define BULK_TIMEOUT 1000
59 /* constants for "firmware" upload and download */
60 #define FIRMWARE "usbduxsigma_firmware.bin"
61 #define FIRMWARE_MAX_LEN 0x4000
62 #define USBDUXSUB_FIRMWARE 0xa0
63 #define VENDOR_DIR_IN 0xc0
64 #define VENDOR_DIR_OUT 0x40
66 /* internal addresses of the 8051 processor */
67 #define USBDUXSUB_CPUCS 0xE600
69 /* 300Hz max frequ under PWM */
70 #define MIN_PWM_PERIOD ((long)(1E9/300))
72 /* Default PWM frequency */
73 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
75 /* Number of channels (16 AD and offset)*/
76 #define NUMCHANNELS 16
78 /* Size of one A/D value */
79 #define SIZEADIN ((sizeof(uint32_t)))
82 * Size of the async input-buffer IN BYTES, the DIO state is transmitted
85 #define SIZEINBUF (((NUMCHANNELS+1)*SIZEADIN))
88 #define SIZEINSNBUF 16
90 /* Number of DA channels */
91 #define NUMOUTCHANNELS 8
93 /* size of one value for the D/A converter: channel and value */
94 #define SIZEDAOUT ((sizeof(uint8_t)+sizeof(uint16_t)))
97 * Size of the output-buffer in bytes
98 * Actually only the first 4 triplets are used but for the
99 * high speed mode we need to pad it to 8 (microframes).
101 #define SIZEOUTBUF ((8*SIZEDAOUT))
104 * Size of the buffer for the dux commands: just now max size is determined
105 * by the analogue out + command byte + panic bytes...
107 #define SIZEOFDUXBUFFER ((8*SIZEDAOUT+2))
109 /* Number of in-URBs which receive the data: min=2 */
110 #define NUMOFINBUFFERSFULL 5
112 /* Number of out-URBs which send the data: min=2 */
113 #define NUMOFOUTBUFFERSFULL 5
115 /* Number of in-URBs which receive the data: min=5 */
116 /* must have more buffers due to buggy USB ctr */
117 #define NUMOFINBUFFERSHIGH 10
119 /* Number of out-URBs which send the data: min=5 */
120 /* must have more buffers due to buggy USB ctr */
121 #define NUMOFOUTBUFFERSHIGH 10
123 /* number of retries to get the right dux command */
126 /* bulk transfer commands to usbduxsigma */
127 #define USBBUXSIGMA_AD_CMD 0
128 #define USBDUXSIGMA_DA_CMD 1
129 #define USBDUXSIGMA_DIO_CFG_CMD 2
130 #define USBDUXSIGMA_DIO_BITS_CMD 3
131 #define USBDUXSIGMA_SINGLE_AD_CMD 4
132 #define USBDUXSIGMA_PWM_ON_CMD 7
133 #define USBDUXSIGMA_PWM_OFF_CMD 8
135 static const struct comedi_lrange usbduxsigma_ai_range
= {
137 BIP_RANGE(2.5 * 0x800000 / 0x780000 / 2.0)
141 struct usbduxsigma_private
{
142 /* actual number of in-buffers */
144 /* actual number of out-buffers */
146 /* ISO-transfer handling: buffers */
147 struct urb
**ai_urbs
;
148 struct urb
**ao_urbs
;
149 /* pwm-transfer handling */
152 unsigned int pwm_period
;
153 /* PWM internal delay for the GPIF in the FX2 */
155 /* size of the PWM buffer which holds the bit pattern */
157 /* input buffer for the ISO-transfer */
159 /* input buffer for single insn */
162 unsigned high_speed
:1;
163 unsigned ai_cmd_running
:1;
164 unsigned ao_cmd_running
:1;
165 unsigned pwm_cmd_running
:1;
167 /* number of samples to acquire */
170 /* time between samples in units of the timer */
171 unsigned int ai_timer
;
172 unsigned int ao_timer
;
173 /* counter between acquisitions */
174 unsigned int ai_counter
;
175 unsigned int ao_counter
;
176 /* interval in frames/uframes */
177 unsigned int ai_interval
;
179 uint8_t *dux_commands
;
180 struct semaphore sem
;
183 static void usbduxsigma_unlink_urbs(struct urb
**urbs
, int num_urbs
)
187 for (i
= 0; i
< num_urbs
; i
++)
188 usb_kill_urb(urbs
[i
]);
191 static void usbduxsigma_ai_stop(struct comedi_device
*dev
, int do_unlink
)
193 struct usbduxsigma_private
*devpriv
= dev
->private;
195 if (do_unlink
&& devpriv
->ai_urbs
)
196 usbduxsigma_unlink_urbs(devpriv
->ai_urbs
, devpriv
->n_ai_urbs
);
198 devpriv
->ai_cmd_running
= 0;
201 static int usbduxsigma_ai_cancel(struct comedi_device
*dev
,
202 struct comedi_subdevice
*s
)
204 struct usbduxsigma_private
*devpriv
= dev
->private;
207 /* unlink only if it is really running */
208 usbduxsigma_ai_stop(dev
, devpriv
->ai_cmd_running
);
214 static void usbduxsigma_ai_urb_complete(struct urb
*urb
)
216 struct comedi_device
*dev
= urb
->context
;
217 struct usbduxsigma_private
*devpriv
= dev
->private;
218 struct comedi_subdevice
*s
= dev
->read_subdev
;
219 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
220 unsigned int dio_state
;
225 /* first we test if something unusual has just happened */
226 switch (urb
->status
) {
228 /* copy the result in the transfer buffer */
229 memcpy(devpriv
->in_buf
, urb
->transfer_buffer
, SIZEINBUF
);
233 * error in the ISOchronous data
234 * we don't copy the data into the transfer buffer
235 * and recycle the last data byte
237 dev_dbg(dev
->class_dev
, "CRC error in ISO IN stream\n");
245 /* happens after an unlink command */
246 if (devpriv
->ai_cmd_running
) {
247 usbduxsigma_ai_stop(dev
, 0); /* w/o unlink */
248 /* we are still running a command, tell comedi */
249 s
->async
->events
|= (COMEDI_CB_EOA
| COMEDI_CB_ERROR
);
250 comedi_event(dev
, s
);
256 * a real error on the bus
257 * pass error to comedi if we are really running a command
259 if (devpriv
->ai_cmd_running
) {
260 dev_err(dev
->class_dev
,
261 "%s: non-zero urb status (%d)\n",
262 __func__
, urb
->status
);
263 usbduxsigma_ai_stop(dev
, 0); /* w/o unlink */
264 s
->async
->events
|= (COMEDI_CB_EOA
| COMEDI_CB_ERROR
);
265 comedi_event(dev
, s
);
270 if (unlikely(!devpriv
->ai_cmd_running
))
273 urb
->dev
= comedi_to_usb_dev(dev
);
275 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
276 if (unlikely(ret
< 0)) {
277 dev_err(dev
->class_dev
, "%s: urb resubmit failed (%d)\n",
279 if (ret
== -EL2NSYNC
)
280 dev_err(dev
->class_dev
,
281 "buggy USB host controller or bug in IRQ handler\n");
282 usbduxsigma_ai_stop(dev
, 0); /* w/o unlink */
283 s
->async
->events
|= (COMEDI_CB_EOA
| COMEDI_CB_ERROR
);
284 comedi_event(dev
, s
);
288 /* get the state of the dio pins to allow external trigger */
289 dio_state
= be32_to_cpu(devpriv
->in_buf
[0]);
291 devpriv
->ai_counter
--;
292 if (likely(devpriv
->ai_counter
> 0))
295 /* timer zero, transfer measurements to comedi */
296 devpriv
->ai_counter
= devpriv
->ai_timer
;
298 if (cmd
->stop_src
== TRIG_COUNT
) {
299 /* not continuous, fixed number of samples */
300 devpriv
->ai_sample_count
--;
301 if (devpriv
->ai_sample_count
< 0) {
302 usbduxsigma_ai_stop(dev
, 0); /* w/o unlink */
303 /* acquistion is over, tell comedi */
304 s
->async
->events
|= COMEDI_CB_EOA
;
305 comedi_event(dev
, s
);
310 /* get the data from the USB bus and hand it over to comedi */
311 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
312 /* transfer data, note first byte is the DIO state */
313 val
= be32_to_cpu(devpriv
->in_buf
[i
+1]);
314 val
&= 0x00ffffff; /* strip status byte */
315 val
^= 0x00800000; /* convert to unsigned */
317 ret
= cfc_write_array_to_buffer(s
, &val
, sizeof(uint32_t));
318 if (unlikely(ret
== 0)) {
319 /* buffer overflow */
320 usbduxsigma_ai_stop(dev
, 0); /* w/o unlink */
324 /* tell comedi that data is there */
325 s
->async
->events
|= (COMEDI_CB_BLOCK
| COMEDI_CB_EOS
);
326 comedi_event(dev
, s
);
329 static void usbduxsigma_ao_stop(struct comedi_device
*dev
, int do_unlink
)
331 struct usbduxsigma_private
*devpriv
= dev
->private;
333 if (do_unlink
&& devpriv
->ao_urbs
)
334 usbduxsigma_unlink_urbs(devpriv
->ao_urbs
, devpriv
->n_ao_urbs
);
336 devpriv
->ao_cmd_running
= 0;
339 static int usbduxsigma_ao_cancel(struct comedi_device
*dev
,
340 struct comedi_subdevice
*s
)
342 struct usbduxsigma_private
*devpriv
= dev
->private;
345 /* unlink only if it is really running */
346 usbduxsigma_ao_stop(dev
, devpriv
->ao_cmd_running
);
352 static void usbduxsigma_ao_urb_complete(struct urb
*urb
)
354 struct comedi_device
*dev
= urb
->context
;
355 struct usbduxsigma_private
*devpriv
= dev
->private;
356 struct comedi_subdevice
*s
= dev
->write_subdev
;
357 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
362 switch (urb
->status
) {
371 /* happens after an unlink command */
372 if (devpriv
->ao_cmd_running
) {
373 usbduxsigma_ao_stop(dev
, 0); /* w/o unlink */
374 s
->async
->events
|= COMEDI_CB_EOA
;
375 comedi_event(dev
, s
);
381 if (devpriv
->ao_cmd_running
) {
382 dev_err(dev
->class_dev
,
383 "%s: non-zero urb status (%d)\n",
384 __func__
, urb
->status
);
385 usbduxsigma_ao_stop(dev
, 0); /* w/o unlink */
386 s
->async
->events
|= (COMEDI_CB_ERROR
| COMEDI_CB_EOA
);
387 comedi_event(dev
, s
);
392 if (!devpriv
->ao_cmd_running
)
395 devpriv
->ao_counter
--;
396 if ((int)devpriv
->ao_counter
<= 0) {
397 /* timer zero, transfer from comedi */
398 devpriv
->ao_counter
= devpriv
->ao_timer
;
400 if (cmd
->stop_src
== TRIG_COUNT
) {
401 /* not continuous, fixed number of samples */
402 devpriv
->ao_sample_count
--;
403 if (devpriv
->ao_sample_count
< 0) {
404 usbduxsigma_ao_stop(dev
, 0); /* w/o unlink */
405 /* acquistion is over, tell comedi */
406 s
->async
->events
|= COMEDI_CB_EOA
;
407 comedi_event(dev
, s
);
412 /* transmit data to the USB bus */
413 datap
= urb
->transfer_buffer
;
414 *datap
++ = cmd
->chanlist_len
;
415 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
416 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
419 ret
= comedi_buf_get(s
, &val
);
421 dev_err(dev
->class_dev
, "buffer underflow\n");
422 s
->async
->events
|= (COMEDI_CB_EOA
|
427 s
->readback
[chan
] = val
;
429 s
->async
->events
|= COMEDI_CB_BLOCK
;
430 comedi_event(dev
, s
);
434 urb
->transfer_buffer_length
= SIZEOUTBUF
;
435 urb
->dev
= comedi_to_usb_dev(dev
);
437 if (devpriv
->high_speed
)
438 urb
->interval
= 8; /* uframes */
440 urb
->interval
= 1; /* frames */
441 urb
->number_of_packets
= 1;
442 urb
->iso_frame_desc
[0].offset
= 0;
443 urb
->iso_frame_desc
[0].length
= SIZEOUTBUF
;
444 urb
->iso_frame_desc
[0].status
= 0;
445 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
447 dev_err(dev
->class_dev
,
448 "%s: urb resubmit failed (%d)\n",
450 if (ret
== -EL2NSYNC
)
451 dev_err(dev
->class_dev
,
452 "buggy USB host controller or bug in IRQ handler\n");
453 usbduxsigma_ao_stop(dev
, 0); /* w/o unlink */
454 s
->async
->events
|= (COMEDI_CB_EOA
| COMEDI_CB_ERROR
);
455 comedi_event(dev
, s
);
459 static int usbduxsigma_submit_urbs(struct comedi_device
*dev
,
460 struct urb
**urbs
, int num_urbs
,
463 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
464 struct usbduxsigma_private
*devpriv
= dev
->private;
469 /* Submit all URBs and start the transfer on the bus */
470 for (i
= 0; i
< num_urbs
; i
++) {
473 /* in case of a resubmission after an unlink... */
475 urb
->interval
= devpriv
->ai_interval
;
479 urb
->transfer_flags
= URB_ISO_ASAP
;
481 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
488 static int usbduxsigma_chans_to_interval(int num_chan
)
497 static int usbduxsigma_ai_cmdtest(struct comedi_device
*dev
,
498 struct comedi_subdevice
*s
,
499 struct comedi_cmd
*cmd
)
501 struct usbduxsigma_private
*devpriv
= dev
->private;
502 int high_speed
= devpriv
->high_speed
;
503 int interval
= usbduxsigma_chans_to_interval(cmd
->chanlist_len
);
506 /* Step 1 : check if triggers are trivially valid */
508 err
|= cfc_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_INT
);
509 err
|= cfc_check_trigger_src(&cmd
->scan_begin_src
, TRIG_TIMER
);
510 err
|= cfc_check_trigger_src(&cmd
->convert_src
, TRIG_NOW
);
511 err
|= cfc_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
512 err
|= cfc_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
517 /* Step 2a : make sure trigger sources are unique */
519 err
|= cfc_check_trigger_is_unique(cmd
->start_src
);
520 err
|= cfc_check_trigger_is_unique(cmd
->stop_src
);
522 /* Step 2b : and mutually compatible */
527 /* Step 3: check if arguments are trivially valid */
529 err
|= cfc_check_trigger_arg_is(&cmd
->start_arg
, 0);
531 if (cmd
->scan_begin_src
== TRIG_FOLLOW
) /* internal trigger */
532 err
|= cfc_check_trigger_arg_is(&cmd
->scan_begin_arg
, 0);
534 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
539 * In high speed mode microframes are possible.
540 * However, during one microframe we can roughly
541 * sample two channels. Thus, the more channels
542 * are in the channel list the more time we need.
544 err
|= cfc_check_trigger_arg_min(&cmd
->scan_begin_arg
,
545 (1000000 / 8 * interval
));
547 tmp
= (cmd
->scan_begin_arg
/ 125000) * 125000;
550 /* 1kHz scans every USB frame */
551 err
|= cfc_check_trigger_arg_min(&cmd
->scan_begin_arg
,
554 tmp
= (cmd
->scan_begin_arg
/ 1000000) * 1000000;
556 err
|= cfc_check_trigger_arg_is(&cmd
->scan_begin_arg
, tmp
);
559 err
|= cfc_check_trigger_arg_is(&cmd
->scan_end_arg
, cmd
->chanlist_len
);
561 if (cmd
->stop_src
== TRIG_COUNT
)
562 err
|= cfc_check_trigger_arg_min(&cmd
->stop_arg
, 1);
564 err
|= cfc_check_trigger_arg_is(&cmd
->stop_arg
, 0);
569 /* Step 4: fix up any arguments */
573 * every 2 channels get a time window of 125us. Thus, if we
574 * sample all 16 channels we need 1ms. If we sample only one
575 * channel we need only 125us
577 devpriv
->ai_interval
= interval
;
578 devpriv
->ai_timer
= cmd
->scan_begin_arg
/ (125000 * interval
);
580 /* interval always 1ms */
581 devpriv
->ai_interval
= 1;
582 devpriv
->ai_timer
= cmd
->scan_begin_arg
/ 1000000;
584 if (devpriv
->ai_timer
< 1)
587 if (cmd
->stop_src
== TRIG_COUNT
) {
588 /* data arrives as one packet */
589 devpriv
->ai_sample_count
= cmd
->stop_arg
;
591 /* continuous acquisition */
592 devpriv
->ai_sample_count
= 0;
602 * creates the ADC command for the MAX1271
603 * range is the range value from comedi
605 static void create_adc_command(unsigned int chan
,
610 (*muxsg0
) = (*muxsg0
) | (1 << chan
);
612 (*muxsg1
) = (*muxsg1
) | (1 << (chan
-8));
615 static int usbbuxsigma_send_cmd(struct comedi_device
*dev
, int cmd_type
)
617 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
618 struct usbduxsigma_private
*devpriv
= dev
->private;
621 devpriv
->dux_commands
[0] = cmd_type
;
623 return usb_bulk_msg(usb
, usb_sndbulkpipe(usb
, 1),
624 devpriv
->dux_commands
, SIZEOFDUXBUFFER
,
625 &nsent
, BULK_TIMEOUT
);
628 static int usbduxsigma_receive_cmd(struct comedi_device
*dev
, int command
)
630 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
631 struct usbduxsigma_private
*devpriv
= dev
->private;
636 for (i
= 0; i
< RETRIES
; i
++) {
637 ret
= usb_bulk_msg(usb
, usb_rcvbulkpipe(usb
, 8),
638 devpriv
->insn_buf
, SIZEINSNBUF
,
639 &nrec
, BULK_TIMEOUT
);
643 if (devpriv
->insn_buf
[0] == command
)
647 * This is only reached if the data has been requested a
648 * couple of times and the command was not received.
653 static int usbduxsigma_ai_inttrig(struct comedi_device
*dev
,
654 struct comedi_subdevice
*s
,
655 unsigned int trig_num
)
657 struct usbduxsigma_private
*devpriv
= dev
->private;
658 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
661 if (trig_num
!= cmd
->start_arg
)
665 if (!devpriv
->ai_cmd_running
) {
666 devpriv
->ai_cmd_running
= 1;
667 ret
= usbduxsigma_submit_urbs(dev
, devpriv
->ai_urbs
,
668 devpriv
->n_ai_urbs
, 1);
670 devpriv
->ai_cmd_running
= 0;
674 s
->async
->inttrig
= NULL
;
681 static int usbduxsigma_ai_cmd(struct comedi_device
*dev
,
682 struct comedi_subdevice
*s
)
684 struct usbduxsigma_private
*devpriv
= dev
->private;
685 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
686 unsigned int len
= cmd
->chanlist_len
;
695 /* set current channel of the running acquisition to zero */
696 s
->async
->cur_chan
= 0;
697 for (i
= 0; i
< len
; i
++) {
698 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
700 create_adc_command(chan
, &muxsg0
, &muxsg1
);
703 devpriv
->dux_commands
[1] = len
; /* num channels per time step */
704 devpriv
->dux_commands
[2] = 0x12; /* CONFIG0 */
705 devpriv
->dux_commands
[3] = 0x03; /* CONFIG1: 23kHz sample, delay 0us */
706 devpriv
->dux_commands
[4] = 0x00; /* CONFIG3: diff. channels off */
707 devpriv
->dux_commands
[5] = muxsg0
;
708 devpriv
->dux_commands
[6] = muxsg1
;
709 devpriv
->dux_commands
[7] = sysred
;
711 ret
= usbbuxsigma_send_cmd(dev
, USBBUXSIGMA_AD_CMD
);
717 devpriv
->ai_counter
= devpriv
->ai_timer
;
719 if (cmd
->start_src
== TRIG_NOW
) {
720 /* enable this acquisition operation */
721 devpriv
->ai_cmd_running
= 1;
722 ret
= usbduxsigma_submit_urbs(dev
, devpriv
->ai_urbs
,
723 devpriv
->n_ai_urbs
, 1);
725 devpriv
->ai_cmd_running
= 0;
729 s
->async
->inttrig
= NULL
;
730 } else { /* TRIG_INT */
731 s
->async
->inttrig
= usbduxsigma_ai_inttrig
;
739 static int usbduxsigma_ai_insn_read(struct comedi_device
*dev
,
740 struct comedi_subdevice
*s
,
741 struct comedi_insn
*insn
,
744 struct usbduxsigma_private
*devpriv
= dev
->private;
745 unsigned int chan
= CR_CHAN(insn
->chanspec
);
753 if (devpriv
->ai_cmd_running
) {
758 create_adc_command(chan
, &muxsg0
, &muxsg1
);
760 /* Mode 0 is used to get a single conversion on demand */
761 devpriv
->dux_commands
[1] = 0x16; /* CONFIG0: chopper on */
762 devpriv
->dux_commands
[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
763 devpriv
->dux_commands
[3] = 0x00; /* CONFIG3: diff. channels off */
764 devpriv
->dux_commands
[4] = muxsg0
;
765 devpriv
->dux_commands
[5] = muxsg1
;
766 devpriv
->dux_commands
[6] = sysred
;
769 ret
= usbbuxsigma_send_cmd(dev
, USBDUXSIGMA_SINGLE_AD_CMD
);
775 for (i
= 0; i
< insn
->n
; i
++) {
778 ret
= usbduxsigma_receive_cmd(dev
, USBDUXSIGMA_SINGLE_AD_CMD
);
784 /* 32 bits big endian from the A/D converter */
785 val
= be32_to_cpu(get_unaligned((__be32
786 *)(devpriv
->insn_buf
+ 1)));
787 val
&= 0x00ffffff; /* strip status byte */
788 val
^= 0x00800000; /* convert to unsigned */
797 static int usbduxsigma_ao_insn_read(struct comedi_device
*dev
,
798 struct comedi_subdevice
*s
,
799 struct comedi_insn
*insn
,
802 struct usbduxsigma_private
*devpriv
= dev
->private;
806 ret
= comedi_readback_insn_read(dev
, s
, insn
, data
);
812 static int usbduxsigma_ao_insn_write(struct comedi_device
*dev
,
813 struct comedi_subdevice
*s
,
814 struct comedi_insn
*insn
,
817 struct usbduxsigma_private
*devpriv
= dev
->private;
818 unsigned int chan
= CR_CHAN(insn
->chanspec
);
823 if (devpriv
->ao_cmd_running
) {
828 for (i
= 0; i
< insn
->n
; i
++) {
829 devpriv
->dux_commands
[1] = 1; /* num channels */
830 devpriv
->dux_commands
[2] = data
[i
]; /* value */
831 devpriv
->dux_commands
[3] = chan
; /* channel number */
832 ret
= usbbuxsigma_send_cmd(dev
, USBDUXSIGMA_DA_CMD
);
837 s
->readback
[chan
] = data
[i
];
844 static int usbduxsigma_ao_inttrig(struct comedi_device
*dev
,
845 struct comedi_subdevice
*s
,
846 unsigned int trig_num
)
848 struct usbduxsigma_private
*devpriv
= dev
->private;
849 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
852 if (trig_num
!= cmd
->start_arg
)
856 if (!devpriv
->ao_cmd_running
) {
857 devpriv
->ao_cmd_running
= 1;
858 ret
= usbduxsigma_submit_urbs(dev
, devpriv
->ao_urbs
,
859 devpriv
->n_ao_urbs
, 0);
861 devpriv
->ao_cmd_running
= 0;
865 s
->async
->inttrig
= NULL
;
872 static int usbduxsigma_ao_cmdtest(struct comedi_device
*dev
,
873 struct comedi_subdevice
*s
,
874 struct comedi_cmd
*cmd
)
876 struct usbduxsigma_private
*devpriv
= dev
->private;
881 /* high speed conversions are not used yet */
882 high_speed
= 0; /* (devpriv->high_speed) */
884 /* Step 1 : check if triggers are trivially valid */
886 err
|= cfc_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_INT
);
890 * start immediately a new scan
891 * the sampling rate is set by the coversion rate
895 /* start a new scan (output at once) with a timer */
898 err
|= cfc_check_trigger_src(&cmd
->scan_begin_src
, flags
);
900 err
|= cfc_check_trigger_src(&cmd
->convert_src
, TRIG_NOW
);
901 err
|= cfc_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
902 err
|= cfc_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
909 /* Step 2a : make sure trigger sources are unique */
911 err
|= cfc_check_trigger_is_unique(cmd
->start_src
);
912 err
|= cfc_check_trigger_is_unique(cmd
->stop_src
);
914 /* Step 2b : and mutually compatible */
919 /* Step 3: check if arguments are trivially valid */
921 err
|= cfc_check_trigger_arg_is(&cmd
->start_arg
, 0);
923 if (cmd
->scan_begin_src
== TRIG_FOLLOW
) /* internal trigger */
924 err
|= cfc_check_trigger_arg_is(&cmd
->scan_begin_arg
, 0);
926 if (cmd
->scan_begin_src
== TRIG_TIMER
)
927 err
|= cfc_check_trigger_arg_min(&cmd
->scan_begin_arg
,
930 /* not used now, is for later use */
931 if (cmd
->convert_src
== TRIG_TIMER
)
932 err
|= cfc_check_trigger_arg_min(&cmd
->convert_arg
, 125000);
934 err
|= cfc_check_trigger_arg_is(&cmd
->scan_end_arg
, cmd
->chanlist_len
);
936 if (cmd
->stop_src
== TRIG_COUNT
)
937 err
|= cfc_check_trigger_arg_min(&cmd
->stop_arg
, 1);
939 err
|= cfc_check_trigger_arg_is(&cmd
->stop_arg
, 0);
944 /* Step 4: fix up any arguments */
946 /* we count in timer steps */
948 /* timing of the conversion itself: every 125 us */
949 devpriv
->ao_timer
= cmd
->convert_arg
/ 125000;
952 * timing of the scan: every 1ms
953 * we get all channels at once
955 devpriv
->ao_timer
= cmd
->scan_begin_arg
/ 1000000;
957 if (devpriv
->ao_timer
< 1)
960 if (cmd
->stop_src
== TRIG_COUNT
) {
961 /* not continuous, use counter */
963 /* high speed also scans everything at once */
964 devpriv
->ao_sample_count
= cmd
->stop_arg
*
968 * There's no scan as the scan has been
969 * handled inside the FX2. Data arrives as
972 devpriv
->ao_sample_count
= cmd
->stop_arg
;
975 /* continuous acquisition */
976 devpriv
->ao_sample_count
= 0;
985 static int usbduxsigma_ao_cmd(struct comedi_device
*dev
,
986 struct comedi_subdevice
*s
)
988 struct usbduxsigma_private
*devpriv
= dev
->private;
989 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
994 /* set current channel of the running acquisition to zero */
995 s
->async
->cur_chan
= 0;
997 devpriv
->ao_counter
= devpriv
->ao_timer
;
999 if (cmd
->start_src
== TRIG_NOW
) {
1000 /* enable this acquisition operation */
1001 devpriv
->ao_cmd_running
= 1;
1002 ret
= usbduxsigma_submit_urbs(dev
, devpriv
->ao_urbs
,
1003 devpriv
->n_ao_urbs
, 0);
1005 devpriv
->ao_cmd_running
= 0;
1009 s
->async
->inttrig
= NULL
;
1010 } else { /* TRIG_INT */
1011 s
->async
->inttrig
= usbduxsigma_ao_inttrig
;
1019 static int usbduxsigma_dio_insn_config(struct comedi_device
*dev
,
1020 struct comedi_subdevice
*s
,
1021 struct comedi_insn
*insn
,
1026 ret
= comedi_dio_insn_config(dev
, s
, insn
, data
, 0);
1031 * We don't tell the firmware here as it would take 8 frames
1032 * to submit the information. We do it in the (*insn_bits).
1037 static int usbduxsigma_dio_insn_bits(struct comedi_device
*dev
,
1038 struct comedi_subdevice
*s
,
1039 struct comedi_insn
*insn
,
1042 struct usbduxsigma_private
*devpriv
= dev
->private;
1045 down(&devpriv
->sem
);
1047 comedi_dio_update_state(s
, data
);
1049 /* Always update the hardware. See the (*insn_config). */
1050 devpriv
->dux_commands
[1] = s
->io_bits
& 0xff;
1051 devpriv
->dux_commands
[4] = s
->state
& 0xff;
1052 devpriv
->dux_commands
[2] = (s
->io_bits
>> 8) & 0xff;
1053 devpriv
->dux_commands
[5] = (s
->state
>> 8) & 0xff;
1054 devpriv
->dux_commands
[3] = (s
->io_bits
>> 16) & 0xff;
1055 devpriv
->dux_commands
[6] = (s
->state
>> 16) & 0xff;
1057 ret
= usbbuxsigma_send_cmd(dev
, USBDUXSIGMA_DIO_BITS_CMD
);
1060 ret
= usbduxsigma_receive_cmd(dev
, USBDUXSIGMA_DIO_BITS_CMD
);
1064 s
->state
= devpriv
->insn_buf
[1] |
1065 (devpriv
->insn_buf
[2] << 8) |
1066 (devpriv
->insn_buf
[3] << 16);
1077 static void usbduxsigma_pwm_stop(struct comedi_device
*dev
, int do_unlink
)
1079 struct usbduxsigma_private
*devpriv
= dev
->private;
1082 if (devpriv
->pwm_urb
)
1083 usb_kill_urb(devpriv
->pwm_urb
);
1086 devpriv
->pwm_cmd_running
= 0;
1089 static int usbduxsigma_pwm_cancel(struct comedi_device
*dev
,
1090 struct comedi_subdevice
*s
)
1092 struct usbduxsigma_private
*devpriv
= dev
->private;
1094 /* unlink only if it is really running */
1095 usbduxsigma_pwm_stop(dev
, devpriv
->pwm_cmd_running
);
1097 return usbbuxsigma_send_cmd(dev
, USBDUXSIGMA_PWM_OFF_CMD
);
1100 static void usbduxsigma_pwm_urb_complete(struct urb
*urb
)
1102 struct comedi_device
*dev
= urb
->context
;
1103 struct usbduxsigma_private
*devpriv
= dev
->private;
1106 switch (urb
->status
) {
1115 /* happens after an unlink command */
1116 if (devpriv
->pwm_cmd_running
)
1117 usbduxsigma_pwm_stop(dev
, 0); /* w/o unlink */
1122 if (devpriv
->pwm_cmd_running
) {
1123 dev_err(dev
->class_dev
,
1124 "%s: non-zero urb status (%d)\n",
1125 __func__
, urb
->status
);
1126 usbduxsigma_pwm_stop(dev
, 0); /* w/o unlink */
1131 if (!devpriv
->pwm_cmd_running
)
1134 urb
->transfer_buffer_length
= devpriv
->pwm_buf_sz
;
1135 urb
->dev
= comedi_to_usb_dev(dev
);
1137 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
1139 dev_err(dev
->class_dev
, "%s: urb resubmit failed (%d)\n",
1141 if (ret
== -EL2NSYNC
)
1142 dev_err(dev
->class_dev
,
1143 "buggy USB host controller or bug in IRQ handler\n");
1144 usbduxsigma_pwm_stop(dev
, 0); /* w/o unlink */
1148 static int usbduxsigma_submit_pwm_urb(struct comedi_device
*dev
)
1150 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
1151 struct usbduxsigma_private
*devpriv
= dev
->private;
1152 struct urb
*urb
= devpriv
->pwm_urb
;
1154 /* in case of a resubmission after an unlink... */
1155 usb_fill_bulk_urb(urb
, usb
, usb_sndbulkpipe(usb
, 4),
1156 urb
->transfer_buffer
, devpriv
->pwm_buf_sz
,
1157 usbduxsigma_pwm_urb_complete
, dev
);
1159 return usb_submit_urb(urb
, GFP_ATOMIC
);
1162 static int usbduxsigma_pwm_period(struct comedi_device
*dev
,
1163 struct comedi_subdevice
*s
,
1164 unsigned int period
)
1166 struct usbduxsigma_private
*devpriv
= dev
->private;
1169 if (period
< MIN_PWM_PERIOD
)
1172 fx2delay
= (period
/ (6 * 512 * 1000 / 33)) - 6;
1176 devpriv
->pwm_delay
= fx2delay
;
1177 devpriv
->pwm_period
= period
;
1181 static int usbduxsigma_pwm_start(struct comedi_device
*dev
,
1182 struct comedi_subdevice
*s
)
1184 struct usbduxsigma_private
*devpriv
= dev
->private;
1187 if (devpriv
->pwm_cmd_running
)
1190 devpriv
->dux_commands
[1] = devpriv
->pwm_delay
;
1191 ret
= usbbuxsigma_send_cmd(dev
, USBDUXSIGMA_PWM_ON_CMD
);
1195 memset(devpriv
->pwm_urb
->transfer_buffer
, 0, devpriv
->pwm_buf_sz
);
1197 devpriv
->pwm_cmd_running
= 1;
1198 ret
= usbduxsigma_submit_pwm_urb(dev
);
1200 devpriv
->pwm_cmd_running
= 0;
1207 static void usbduxsigma_pwm_pattern(struct comedi_device
*dev
,
1208 struct comedi_subdevice
*s
,
1213 struct usbduxsigma_private
*devpriv
= dev
->private;
1214 char pwm_mask
= (1 << chan
); /* DIO bit for the PWM data */
1215 char sgn_mask
= (16 << chan
); /* DIO bit for the sign */
1216 char *buf
= (char *)(devpriv
->pwm_urb
->transfer_buffer
);
1217 int szbuf
= devpriv
->pwm_buf_sz
;
1220 for (i
= 0; i
< szbuf
; i
++) {
1234 static int usbduxsigma_pwm_write(struct comedi_device
*dev
,
1235 struct comedi_subdevice
*s
,
1236 struct comedi_insn
*insn
,
1239 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1242 * It doesn't make sense to support more than one value here
1243 * because it would just overwrite the PWM buffer.
1249 * The sign is set via a special INSN only, this gives us 8 bits
1250 * for normal operation, sign is 0 by default.
1252 usbduxsigma_pwm_pattern(dev
, s
, chan
, data
[0], 0);
1257 static int usbduxsigma_pwm_config(struct comedi_device
*dev
,
1258 struct comedi_subdevice
*s
,
1259 struct comedi_insn
*insn
,
1262 struct usbduxsigma_private
*devpriv
= dev
->private;
1263 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1266 case INSN_CONFIG_ARM
:
1268 * if not zero the PWM is limited to a certain time which is
1269 * not supported here
1273 return usbduxsigma_pwm_start(dev
, s
);
1274 case INSN_CONFIG_DISARM
:
1275 return usbduxsigma_pwm_cancel(dev
, s
);
1276 case INSN_CONFIG_GET_PWM_STATUS
:
1277 data
[1] = devpriv
->pwm_cmd_running
;
1279 case INSN_CONFIG_PWM_SET_PERIOD
:
1280 return usbduxsigma_pwm_period(dev
, s
, data
[1]);
1281 case INSN_CONFIG_PWM_GET_PERIOD
:
1282 data
[1] = devpriv
->pwm_period
;
1284 case INSN_CONFIG_PWM_SET_H_BRIDGE
:
1287 * data[2] = sign (for a relay)
1289 usbduxsigma_pwm_pattern(dev
, s
, chan
, data
[1], (data
[2] != 0));
1291 case INSN_CONFIG_PWM_GET_H_BRIDGE
:
1292 /* values are not kept in this driver, nothing to return */
1298 static int usbduxsigma_getstatusinfo(struct comedi_device
*dev
, int chan
)
1300 struct usbduxsigma_private
*devpriv
= dev
->private;
1308 sysred
= 0; /* ADC zero */
1311 sysred
= 1; /* ADC offset */
1314 sysred
= 4; /* VCC */
1317 sysred
= 8; /* temperature */
1320 sysred
= 16; /* gain */
1323 sysred
= 32; /* ref */
1327 devpriv
->dux_commands
[1] = 0x12; /* CONFIG0 */
1328 devpriv
->dux_commands
[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
1329 devpriv
->dux_commands
[3] = 0x00; /* CONFIG3: diff. channels off */
1330 devpriv
->dux_commands
[4] = 0;
1331 devpriv
->dux_commands
[5] = 0;
1332 devpriv
->dux_commands
[6] = sysred
;
1333 ret
= usbbuxsigma_send_cmd(dev
, USBDUXSIGMA_SINGLE_AD_CMD
);
1337 ret
= usbduxsigma_receive_cmd(dev
, USBDUXSIGMA_SINGLE_AD_CMD
);
1341 /* 32 bits big endian from the A/D converter */
1342 val
= be32_to_cpu(get_unaligned((__be32
*)(devpriv
->insn_buf
+ 1)));
1343 val
&= 0x00ffffff; /* strip status byte */
1344 val
^= 0x00800000; /* convert to unsigned */
1349 static int usbduxsigma_firmware_upload(struct comedi_device
*dev
,
1350 const u8
*data
, size_t size
,
1351 unsigned long context
)
1353 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
1361 if (size
> FIRMWARE_MAX_LEN
) {
1362 dev_err(dev
->class_dev
, "firmware binary too large for FX2\n");
1366 /* we generate a local buffer for the firmware */
1367 buf
= kmemdup(data
, size
, GFP_KERNEL
);
1371 /* we need a malloc'ed buffer for usb_control_msg() */
1372 tmp
= kmalloc(1, GFP_KERNEL
);
1378 /* stop the current firmware on the device */
1379 *tmp
= 1; /* 7f92 to one */
1380 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
1383 USBDUXSUB_CPUCS
, 0x0000,
1387 dev_err(dev
->class_dev
, "can not stop firmware\n");
1391 /* upload the new firmware to the device */
1392 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
1399 dev_err(dev
->class_dev
, "firmware upload failed\n");
1403 /* start the new firmware on the device */
1404 *tmp
= 0; /* 7f92 to zero */
1405 ret
= usb_control_msg(usb
, usb_sndctrlpipe(usb
, 0),
1408 USBDUXSUB_CPUCS
, 0x0000,
1412 dev_err(dev
->class_dev
, "can not start firmware\n");
1420 static int usbduxsigma_alloc_usb_buffers(struct comedi_device
*dev
)
1422 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
1423 struct usbduxsigma_private
*devpriv
= dev
->private;
1427 devpriv
->dux_commands
= kzalloc(SIZEOFDUXBUFFER
, GFP_KERNEL
);
1428 devpriv
->in_buf
= kzalloc(SIZEINBUF
, GFP_KERNEL
);
1429 devpriv
->insn_buf
= kzalloc(SIZEINSNBUF
, GFP_KERNEL
);
1430 devpriv
->ai_urbs
= kcalloc(devpriv
->n_ai_urbs
, sizeof(urb
), GFP_KERNEL
);
1431 devpriv
->ao_urbs
= kcalloc(devpriv
->n_ao_urbs
, sizeof(urb
), GFP_KERNEL
);
1432 if (!devpriv
->dux_commands
|| !devpriv
->in_buf
|| !devpriv
->insn_buf
||
1433 !devpriv
->ai_urbs
|| !devpriv
->ao_urbs
)
1436 for (i
= 0; i
< devpriv
->n_ai_urbs
; i
++) {
1437 /* one frame: 1ms */
1438 urb
= usb_alloc_urb(1, GFP_KERNEL
);
1441 devpriv
->ai_urbs
[i
] = urb
;
1443 /* will be filled later with a pointer to the comedi-device */
1444 /* and ONLY then the urb should be submitted */
1445 urb
->context
= NULL
;
1446 urb
->pipe
= usb_rcvisocpipe(usb
, 6);
1447 urb
->transfer_flags
= URB_ISO_ASAP
;
1448 urb
->transfer_buffer
= kzalloc(SIZEINBUF
, GFP_KERNEL
);
1449 if (!urb
->transfer_buffer
)
1451 urb
->complete
= usbduxsigma_ai_urb_complete
;
1452 urb
->number_of_packets
= 1;
1453 urb
->transfer_buffer_length
= SIZEINBUF
;
1454 urb
->iso_frame_desc
[0].offset
= 0;
1455 urb
->iso_frame_desc
[0].length
= SIZEINBUF
;
1458 for (i
= 0; i
< devpriv
->n_ao_urbs
; i
++) {
1459 /* one frame: 1ms */
1460 urb
= usb_alloc_urb(1, GFP_KERNEL
);
1463 devpriv
->ao_urbs
[i
] = urb
;
1465 /* will be filled later with a pointer to the comedi-device */
1466 /* and ONLY then the urb should be submitted */
1467 urb
->context
= NULL
;
1468 urb
->pipe
= usb_sndisocpipe(usb
, 2);
1469 urb
->transfer_flags
= URB_ISO_ASAP
;
1470 urb
->transfer_buffer
= kzalloc(SIZEOUTBUF
, GFP_KERNEL
);
1471 if (!urb
->transfer_buffer
)
1473 urb
->complete
= usbduxsigma_ao_urb_complete
;
1474 urb
->number_of_packets
= 1;
1475 urb
->transfer_buffer_length
= SIZEOUTBUF
;
1476 urb
->iso_frame_desc
[0].offset
= 0;
1477 urb
->iso_frame_desc
[0].length
= SIZEOUTBUF
;
1478 if (devpriv
->high_speed
)
1479 urb
->interval
= 8; /* uframes */
1481 urb
->interval
= 1; /* frames */
1484 if (devpriv
->pwm_buf_sz
) {
1485 urb
= usb_alloc_urb(0, GFP_KERNEL
);
1488 devpriv
->pwm_urb
= urb
;
1490 urb
->transfer_buffer
= kzalloc(devpriv
->pwm_buf_sz
,
1492 if (!urb
->transfer_buffer
)
1499 static void usbduxsigma_free_usb_buffers(struct comedi_device
*dev
)
1501 struct usbduxsigma_private
*devpriv
= dev
->private;
1505 urb
= devpriv
->pwm_urb
;
1507 kfree(urb
->transfer_buffer
);
1510 if (devpriv
->ao_urbs
) {
1511 for (i
= 0; i
< devpriv
->n_ao_urbs
; i
++) {
1512 urb
= devpriv
->ao_urbs
[i
];
1514 kfree(urb
->transfer_buffer
);
1518 kfree(devpriv
->ao_urbs
);
1520 if (devpriv
->ai_urbs
) {
1521 for (i
= 0; i
< devpriv
->n_ai_urbs
; i
++) {
1522 urb
= devpriv
->ai_urbs
[i
];
1524 kfree(urb
->transfer_buffer
);
1528 kfree(devpriv
->ai_urbs
);
1530 kfree(devpriv
->insn_buf
);
1531 kfree(devpriv
->in_buf
);
1532 kfree(devpriv
->dux_commands
);
1535 static int usbduxsigma_auto_attach(struct comedi_device
*dev
,
1536 unsigned long context_unused
)
1538 struct usb_interface
*intf
= comedi_to_usb_interface(dev
);
1539 struct usb_device
*usb
= comedi_to_usb_dev(dev
);
1540 struct usbduxsigma_private
*devpriv
;
1541 struct comedi_subdevice
*s
;
1545 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
1549 sema_init(&devpriv
->sem
, 1);
1551 usb_set_intfdata(intf
, devpriv
);
1553 devpriv
->high_speed
= (usb
->speed
== USB_SPEED_HIGH
);
1554 if (devpriv
->high_speed
) {
1555 devpriv
->n_ai_urbs
= NUMOFINBUFFERSHIGH
;
1556 devpriv
->n_ao_urbs
= NUMOFOUTBUFFERSHIGH
;
1557 devpriv
->pwm_buf_sz
= 512;
1559 devpriv
->n_ai_urbs
= NUMOFINBUFFERSFULL
;
1560 devpriv
->n_ao_urbs
= NUMOFOUTBUFFERSFULL
;
1563 ret
= usbduxsigma_alloc_usb_buffers(dev
);
1567 /* setting to alternate setting 3: enabling iso ep and bulk ep. */
1568 ret
= usb_set_interface(usb
, intf
->altsetting
->desc
.bInterfaceNumber
,
1571 dev_err(dev
->class_dev
,
1572 "could not set alternate setting 3 in high speed\n");
1576 ret
= comedi_load_firmware(dev
, &usb
->dev
, FIRMWARE
,
1577 usbduxsigma_firmware_upload
, 0);
1581 ret
= comedi_alloc_subdevices(dev
, (devpriv
->high_speed
) ? 4 : 3);
1585 /* Analog Input subdevice */
1586 s
= &dev
->subdevices
[0];
1587 dev
->read_subdev
= s
;
1588 s
->type
= COMEDI_SUBD_AI
;
1589 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
| SDF_CMD_READ
| SDF_LSAMPL
;
1590 s
->n_chan
= NUMCHANNELS
;
1591 s
->len_chanlist
= NUMCHANNELS
;
1592 s
->maxdata
= 0x00ffffff;
1593 s
->range_table
= &usbduxsigma_ai_range
;
1594 s
->insn_read
= usbduxsigma_ai_insn_read
;
1595 s
->do_cmdtest
= usbduxsigma_ai_cmdtest
;
1596 s
->do_cmd
= usbduxsigma_ai_cmd
;
1597 s
->cancel
= usbduxsigma_ai_cancel
;
1599 /* Analog Output subdevice */
1600 s
= &dev
->subdevices
[1];
1601 dev
->write_subdev
= s
;
1602 s
->type
= COMEDI_SUBD_AO
;
1603 s
->subdev_flags
= SDF_WRITABLE
| SDF_GROUND
| SDF_CMD_WRITE
;
1605 s
->len_chanlist
= s
->n_chan
;
1606 s
->maxdata
= 0x00ff;
1607 s
->range_table
= &range_unipolar2_5
;
1608 s
->insn_write
= usbduxsigma_ao_insn_write
;
1609 s
->insn_read
= usbduxsigma_ao_insn_read
;
1610 s
->do_cmdtest
= usbduxsigma_ao_cmdtest
;
1611 s
->do_cmd
= usbduxsigma_ao_cmd
;
1612 s
->cancel
= usbduxsigma_ao_cancel
;
1614 ret
= comedi_alloc_subdev_readback(s
);
1618 /* Digital I/O subdevice */
1619 s
= &dev
->subdevices
[2];
1620 s
->type
= COMEDI_SUBD_DIO
;
1621 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
1624 s
->range_table
= &range_digital
;
1625 s
->insn_bits
= usbduxsigma_dio_insn_bits
;
1626 s
->insn_config
= usbduxsigma_dio_insn_config
;
1628 if (devpriv
->high_speed
) {
1629 /* Timer / pwm subdevice */
1630 s
= &dev
->subdevices
[3];
1631 s
->type
= COMEDI_SUBD_PWM
;
1632 s
->subdev_flags
= SDF_WRITABLE
| SDF_PWM_HBRIDGE
;
1634 s
->maxdata
= devpriv
->pwm_buf_sz
;
1635 s
->insn_write
= usbduxsigma_pwm_write
;
1636 s
->insn_config
= usbduxsigma_pwm_config
;
1638 usbduxsigma_pwm_period(dev
, s
, PWM_DEFAULT_PERIOD
);
1641 offset
= usbduxsigma_getstatusinfo(dev
, 0);
1643 dev_err(dev
->class_dev
,
1644 "Communication to USBDUXSIGMA failed! Check firmware and cabling.\n");
1648 dev_info(dev
->class_dev
, "ADC_zero = %x\n", offset
);
1653 static void usbduxsigma_detach(struct comedi_device
*dev
)
1655 struct usb_interface
*intf
= comedi_to_usb_interface(dev
);
1656 struct usbduxsigma_private
*devpriv
= dev
->private;
1658 usb_set_intfdata(intf
, NULL
);
1663 down(&devpriv
->sem
);
1665 /* force unlink all urbs */
1666 usbduxsigma_ai_stop(dev
, 1);
1667 usbduxsigma_ao_stop(dev
, 1);
1668 usbduxsigma_pwm_stop(dev
, 1);
1670 usbduxsigma_free_usb_buffers(dev
);
1675 static struct comedi_driver usbduxsigma_driver
= {
1676 .driver_name
= "usbduxsigma",
1677 .module
= THIS_MODULE
,
1678 .auto_attach
= usbduxsigma_auto_attach
,
1679 .detach
= usbduxsigma_detach
,
1682 static int usbduxsigma_usb_probe(struct usb_interface
*intf
,
1683 const struct usb_device_id
*id
)
1685 return comedi_usb_auto_config(intf
, &usbduxsigma_driver
, 0);
1688 static const struct usb_device_id usbduxsigma_usb_table
[] = {
1689 { USB_DEVICE(0x13d8, 0x0020) },
1690 { USB_DEVICE(0x13d8, 0x0021) },
1691 { USB_DEVICE(0x13d8, 0x0022) },
1694 MODULE_DEVICE_TABLE(usb
, usbduxsigma_usb_table
);
1696 static struct usb_driver usbduxsigma_usb_driver
= {
1697 .name
= "usbduxsigma",
1698 .probe
= usbduxsigma_usb_probe
,
1699 .disconnect
= comedi_usb_auto_unconfig
,
1700 .id_table
= usbduxsigma_usb_table
,
1702 module_comedi_usb_driver(usbduxsigma_driver
, usbduxsigma_usb_driver
);
1704 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1705 MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com");
1706 MODULE_LICENSE("GPL");
1707 MODULE_FIRMWARE(FIRMWARE
);