2 comedi/drivers/usbdux.c
3 Copyright (C) 2003-2007 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 (usbdux.o)
19 Author: Bernd Porr <BerndPorr@f2s.com>
22 Configuration options:
23 You have to upload firmware with the -i option. The
24 firmware is usually installed under /usr/share/usb or
25 /usr/local/share/usb or /lib/firmware.
27 Connection scheme for the counter at the digital port:
28 0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1.
29 The sampling rate of the counter is approximately 500Hz.
31 Please note that under USB2.0 the length of the channel list determines
32 the max sampling rate. If you sample only one channel you get 8kHz
33 sampling rate. If you sample two channels you get 4kHz and so on.
36 * I must give credit here to Chris Baugher who
37 * wrote the driver for AT-MIO-16d. I used some parts of this
38 * driver. I also must give credits to David Brownell
39 * who supported me with the USB development.
45 * 0.94: D/A output should work now with any channel list combinations
46 * 0.95: .owner commented out for kernel vers below 2.4.19
47 * sanity checks in ai/ao_cmd
48 * 0.96: trying to get it working with 2.6, moved all memory alloc to comedi's
49 * attach final USB IDs
50 * moved memory allocation completely to the corresponding comedi
51 * functions firmware upload is by fxload and no longer by comedi (due to
53 * 0.97: USB IDs received, adjusted table
54 * 0.98: SMP, locking, memory alloc: moved all usb memory alloc
55 * to the usb subsystem and moved all comedi related memory
57 * | kernel | registration | usbdux-usb | usbdux-comedi | comedi |
58 * 0.99: USB 2.0: changed protocol to isochronous transfer
59 * IRQ transfer is too buggy and too risky in 2.0
60 * for the high speed ISO transfer is now a working version
62 * 0.99b: Increased the iso transfer buffer for high sp.to 10 buffers. Some VIA
63 * chipsets miss out IRQs. Deeper buffering is needed.
64 * 1.00: full USB 2.0 support for the A/D converter. Now: max 8kHz sampling
66 * Firmware vers 1.00 is needed for this.
67 * Two 16 bit up/down/reset counter with a sampling rate of 1kHz
68 * And loads of cleaning up, in particular streamlining the
70 * 1.1: moved EP4 transfers to EP1 to make space for a PWM output on EP4
71 * 1.2: added PWM support via EP4
72 * 2.0: PWM seems to be stable and is not interfering with the other functions
73 * 2.1: changed PWM API
74 * 2.2: added firmware kernel request to fix an udev problem
75 * 2.3: corrected a bug in bulk timeouts which were far too short
76 * 2.4: fixed a bug which causes the driver to hang when it ran out of data.
77 * Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it.
81 #include <linux/kernel.h>
82 #include <linux/module.h>
83 #include <linux/slab.h>
84 #include <linux/input.h>
85 #include <linux/usb.h>
86 #include <linux/fcntl.h>
87 #include <linux/compiler.h>
89 #include "../comedidev.h"
91 #include "comedi_fc.h"
93 /* constants for firmware upload and download */
94 #define USBDUX_FIRMWARE "usbdux_firmware.bin"
95 #define USBDUX_FIRMWARE_MAX_LEN 0x2000
96 #define USBDUX_FIRMWARE_CMD 0xa0
97 #define VENDOR_DIR_IN 0xc0
98 #define VENDOR_DIR_OUT 0x40
99 #define USBDUX_CPU_CS 0xe600
101 /* usbdux bulk transfer commands */
102 #define USBDUX_CMD_MULT_AI 0
103 #define USBDUX_CMD_AO 1
104 #define USBDUX_CMD_DIO_CFG 2
105 #define USBDUX_CMD_DIO_BITS 3
106 #define USBDUX_CMD_SINGLE_AI 4
107 #define USBDUX_CMD_TIMER_RD 5
108 #define USBDUX_CMD_TIMER_WR 6
109 #define USBDUX_CMD_PWM_ON 7
110 #define USBDUX_CMD_PWM_OFF 8
112 #define USBDUX_NUM_AO_CHAN 4
114 /* timeout for the USB-transfer in ms */
115 #define BULK_TIMEOUT 1000
117 /* 300Hz max frequ under PWM */
118 #define MIN_PWM_PERIOD ((long)(1E9/300))
120 /* Default PWM frequency */
121 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
123 /* Size of one A/D value */
124 #define SIZEADIN ((sizeof(uint16_t)))
127 * Size of the input-buffer IN BYTES
128 * Always multiple of 8 for 8 microframes which is needed in the highspeed mode
130 #define SIZEINBUF ((8*SIZEADIN))
133 #define SIZEINSNBUF 16
135 /* size of one value for the D/A converter: channel and value */
136 #define SIZEDAOUT ((sizeof(uint8_t)+sizeof(uint16_t)))
139 * Size of the output-buffer in bytes
140 * Actually only the first 4 triplets are used but for the
141 * high speed mode we need to pad it to 8 (microframes).
143 #define SIZEOUTBUF ((8*SIZEDAOUT))
146 * Size of the buffer for the dux commands: just now max size is determined
147 * by the analogue out + command byte + panic bytes...
149 #define SIZEOFDUXBUFFER ((8*SIZEDAOUT+2))
151 /* Number of in-URBs which receive the data: min=2 */
152 #define NUMOFINBUFFERSFULL 5
154 /* Number of out-URBs which send the data: min=2 */
155 #define NUMOFOUTBUFFERSFULL 5
157 /* Number of in-URBs which receive the data: min=5 */
158 /* must have more buffers due to buggy USB ctr */
159 #define NUMOFINBUFFERSHIGH 10
161 /* Number of out-URBs which send the data: min=5 */
162 /* must have more buffers due to buggy USB ctr */
163 #define NUMOFOUTBUFFERSHIGH 10
165 /* number of retries to get the right dux command */
168 static const struct comedi_lrange range_usbdux_ai_range = {
171 BIP_RANGE(4.096 / 2),
177 static const struct comedi_lrange range_usbdux_ao_range = {
184 struct usbdux_private {
185 /* actual number of in-buffers */
187 /* actual number of out-buffers */
189 /* ISO-transfer handling: buffers */
190 struct urb **ai_urbs;
191 struct urb **ao_urbs;
192 /* pwm-transfer handling */
195 unsigned int pwm_period;
196 /* PWM internal delay for the GPIF in the FX2 */
198 /* size of the PWM buffer which holds the bit pattern */
200 /* input buffer for the ISO-transfer */
202 /* input buffer for single insn */
205 uint8_t ao_chanlist[USBDUX_NUM_AO_CHAN];
206 unsigned int ao_readback[USBDUX_NUM_AO_CHAN];
208 unsigned int high_speed:1;
209 unsigned int ai_cmd_running:1;
210 unsigned int ai_continous:1;
211 unsigned int ao_cmd_running:1;
212 unsigned int ao_continous:1;
213 unsigned int pwm_cmd_running:1;
215 /* number of samples to acquire */
218 /* time between samples in units of the timer */
219 unsigned int ai_timer;
220 unsigned int ao_timer;
221 /* counter between aquisitions */
222 unsigned int ai_counter;
223 unsigned int ao_counter;
224 /* interval in frames/uframes */
225 unsigned int ai_interval;
227 uint8_t *dux_commands;
228 struct semaphore sem;
231 static void usbdux_unlink_urbs(struct urb **urbs, int num_urbs)
235 for (i = 0; i < num_urbs; i++)
236 usb_kill_urb(urbs[i]);
239 static void usbdux_ai_stop(struct comedi_device *dev, int do_unlink)
241 struct usbdux_private *devpriv = dev->private;
243 if (do_unlink && devpriv->ai_urbs)
244 usbdux_unlink_urbs(devpriv->ai_urbs, devpriv->n_ai_urbs);
246 devpriv->ai_cmd_running = 0;
249 static int usbdux_ai_cancel(struct comedi_device *dev,
250 struct comedi_subdevice *s)
252 struct usbdux_private *devpriv = dev->private;
254 /* prevent other CPUs from submitting new commands just now */
256 /* unlink only if the urb really has been submitted */
257 usbdux_ai_stop(dev, devpriv->ai_cmd_running);
263 /* analogue IN - interrupt service routine */
264 static void usbduxsub_ai_isoc_irq(struct urb *urb)
266 struct comedi_device *dev = urb->context;
267 struct comedi_subdevice *s = dev->read_subdev;
268 struct usbdux_private *devpriv = dev->private;
271 /* first we test if something unusual has just happened */
272 switch (urb->status) {
274 /* copy the result in the transfer buffer */
275 memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF);
278 /* error in the ISOchronous data */
279 /* we don't copy the data into the transfer buffer */
280 /* and recycle the last data byte */
281 dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
288 /* happens after an unlink command */
289 if (devpriv->ai_cmd_running) {
290 s->async->events |= COMEDI_CB_EOA;
291 s->async->events |= COMEDI_CB_ERROR;
292 comedi_event(dev, s);
293 /* stop the transfer w/o unlink */
294 usbdux_ai_stop(dev, 0);
299 /* a real error on the bus */
300 /* pass error to comedi if we are really running a command */
301 if (devpriv->ai_cmd_running) {
302 dev_err(dev->class_dev,
303 "Non-zero urb status received in ai intr context: %d\n",
305 s->async->events |= COMEDI_CB_EOA;
306 s->async->events |= COMEDI_CB_ERROR;
307 comedi_event(dev, s);
308 /* don't do an unlink here */
309 usbdux_ai_stop(dev, 0);
315 * at this point we are reasonably sure that nothing dodgy has happened
316 * are we running a command?
318 if (unlikely(!devpriv->ai_cmd_running)) {
320 * not running a command, do not continue execution if no
321 * asynchronous command is running in particular not resubmit
326 urb->dev = comedi_to_usb_dev(dev);
328 /* resubmit the urb */
329 err = usb_submit_urb(urb, GFP_ATOMIC);
330 if (unlikely(err < 0)) {
331 dev_err(dev->class_dev,
332 "urb resubmit failed in int-context! err=%d\n", err);
333 if (err == -EL2NSYNC)
334 dev_err(dev->class_dev,
335 "buggy USB host controller or bug in IRQ handler!\n");
336 s->async->events |= COMEDI_CB_EOA;
337 s->async->events |= COMEDI_CB_ERROR;
338 comedi_event(dev, s);
339 /* don't do an unlink here */
340 usbdux_ai_stop(dev, 0);
344 devpriv->ai_counter--;
345 if (likely(devpriv->ai_counter > 0))
348 /* timer zero, transfer measurements to comedi */
349 devpriv->ai_counter = devpriv->ai_timer;
351 /* test, if we transmit only a fixed number of samples */
352 if (!devpriv->ai_continous) {
353 /* not continuous, fixed number of samples */
354 devpriv->ai_sample_count--;
355 /* all samples received? */
356 if (devpriv->ai_sample_count < 0) {
357 /* prevent a resubmit next time */
358 usbdux_ai_stop(dev, 0);
359 /* say comedi that the acquistion is over */
360 s->async->events |= COMEDI_CB_EOA;
361 comedi_event(dev, s);
365 /* get the data from the USB bus and hand it over to comedi */
366 n = s->async->cmd.chanlist_len;
367 for (i = 0; i < n; i++) {
368 unsigned int range = CR_RANGE(s->async->cmd.chanlist[i]);
369 uint16_t val = le16_to_cpu(devpriv->in_buf[i]);
371 /* bipolar data is two's-complement */
372 if (comedi_range_is_bipolar(s, range))
373 val ^= ((s->maxdata + 1) >> 1);
376 err = comedi_buf_put(s->async, val);
377 if (unlikely(err == 0)) {
378 /* buffer overflow */
379 usbdux_ai_stop(dev, 0);
383 /* tell comedi that data is there */
384 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
385 comedi_event(dev, s);
388 static void usbdux_ao_stop(struct comedi_device *dev, int do_unlink)
390 struct usbdux_private *devpriv = dev->private;
392 if (do_unlink && devpriv->ao_urbs)
393 usbdux_unlink_urbs(devpriv->ao_urbs, devpriv->n_ao_urbs);
395 devpriv->ao_cmd_running = 0;
398 static int usbdux_ao_cancel(struct comedi_device *dev,
399 struct comedi_subdevice *s)
401 struct usbdux_private *devpriv = dev->private;
403 /* prevent other CPUs from submitting a command just now */
405 /* unlink only if it is really running */
406 usbdux_ao_stop(dev, devpriv->ao_cmd_running);
412 static void usbduxsub_ao_isoc_irq(struct urb *urb)
414 struct comedi_device *dev = urb->context;
415 struct comedi_subdevice *s = dev->write_subdev;
416 struct usbdux_private *devpriv = dev->private;
422 switch (urb->status) {
431 /* after an unlink command, unplug, ... etc */
432 /* no unlink needed here. Already shutting down. */
433 if (devpriv->ao_cmd_running) {
434 s->async->events |= COMEDI_CB_EOA;
435 comedi_event(dev, s);
436 usbdux_ao_stop(dev, 0);
442 if (devpriv->ao_cmd_running) {
443 dev_err(dev->class_dev,
444 "Non-zero urb status received in ao intr context: %d\n",
446 s->async->events |= COMEDI_CB_ERROR;
447 s->async->events |= COMEDI_CB_EOA;
448 comedi_event(dev, s);
449 /* we do an unlink if we are in the high speed mode */
450 usbdux_ao_stop(dev, 0);
455 /* are we actually running? */
456 if (!devpriv->ao_cmd_running)
459 /* normal operation: executing a command in this subdevice */
460 devpriv->ao_counter--;
461 if ((int)devpriv->ao_counter <= 0) {
463 devpriv->ao_counter = devpriv->ao_timer;
465 /* handle non continous acquisition */
466 if (!devpriv->ao_continous) {
467 /* fixed number of samples */
468 devpriv->ao_sample_count--;
469 if (devpriv->ao_sample_count < 0) {
470 /* all samples transmitted */
471 usbdux_ao_stop(dev, 0);
472 s->async->events |= COMEDI_CB_EOA;
473 comedi_event(dev, s);
474 /* no resubmit of the urb */
479 /* transmit data to the USB bus */
480 datap = urb->transfer_buffer;
481 len = s->async->cmd.chanlist_len;
483 for (i = 0; i < s->async->cmd.chanlist_len; i++) {
484 unsigned int chan = devpriv->ao_chanlist[i];
487 ret = comedi_buf_get(s->async, &val);
489 dev_err(dev->class_dev, "buffer underflow\n");
490 s->async->events |= (COMEDI_CB_EOA |
493 /* pointer to the DA */
494 *datap++ = val & 0xff;
495 *datap++ = (val >> 8) & 0xff;
497 devpriv->ao_readback[chan] = val;
499 s->async->events |= COMEDI_CB_BLOCK;
500 comedi_event(dev, s);
503 urb->transfer_buffer_length = SIZEOUTBUF;
504 urb->dev = comedi_to_usb_dev(dev);
506 if (devpriv->ao_cmd_running) {
507 if (devpriv->high_speed)
508 urb->interval = 8; /* uframes */
510 urb->interval = 1; /* frames */
511 urb->number_of_packets = 1;
512 urb->iso_frame_desc[0].offset = 0;
513 urb->iso_frame_desc[0].length = SIZEOUTBUF;
514 urb->iso_frame_desc[0].status = 0;
515 ret = usb_submit_urb(urb, GFP_ATOMIC);
517 dev_err(dev->class_dev,
518 "ao urb resubm failed in int-cont. ret=%d",
521 dev_err(dev->class_dev,
522 "buggy USB host controller or bug in IRQ handling!\n");
524 s->async->events |= COMEDI_CB_EOA;
525 s->async->events |= COMEDI_CB_ERROR;
526 comedi_event(dev, s);
527 /* don't do an unlink here */
528 usbdux_ao_stop(dev, 0);
533 static int usbdux_submit_urbs(struct comedi_device *dev,
534 struct urb **urbs, int num_urbs,
537 struct usb_device *usb = comedi_to_usb_dev(dev);
538 struct usbdux_private *devpriv = dev->private;
543 /* Submit all URBs and start the transfer on the bus */
544 for (i = 0; i < num_urbs; i++) {
547 /* in case of a resubmission after an unlink... */
549 urb->interval = devpriv->ai_interval;
553 urb->transfer_flags = URB_ISO_ASAP;
555 ret = usb_submit_urb(urb, GFP_ATOMIC);
562 static int usbdux_ai_cmdtest(struct comedi_device *dev,
563 struct comedi_subdevice *s, struct comedi_cmd *cmd)
565 struct usbdux_private *this_usbduxsub = dev->private;
567 unsigned int tmp_timer;
569 /* Step 1 : check if triggers are trivially valid */
571 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
572 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
573 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
574 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
575 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
580 /* Step 2a : make sure trigger sources are unique */
582 err |= cfc_check_trigger_is_unique(cmd->start_src);
583 err |= cfc_check_trigger_is_unique(cmd->stop_src);
585 /* Step 2b : and mutually compatible */
590 /* Step 3: check if arguments are trivially valid */
592 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
594 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
595 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
597 if (cmd->scan_begin_src == TRIG_TIMER) {
598 if (this_usbduxsub->high_speed) {
600 * In high speed mode microframes are possible.
601 * However, during one microframe we can roughly
602 * sample one channel. Thus, the more channels
603 * are in the channel list the more time we need.
606 /* find a power of 2 for the number of channels */
607 while (i < (cmd->chanlist_len))
610 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
612 /* now calc the real sampling rate with all the
615 ((unsigned int)(cmd->scan_begin_arg / 125000)) *
619 /* 1kHz scans every USB frame */
620 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
623 * calc the real sampling rate with the rounding errors
625 tmp_timer = ((unsigned int)(cmd->scan_begin_arg /
628 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
632 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
634 if (cmd->stop_src == TRIG_COUNT) {
635 /* any count is allowed */
638 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
648 * creates the ADC command for the MAX1271
649 * range is the range value from comedi
651 static uint8_t create_adc_command(unsigned int chan, unsigned int range)
653 uint8_t p = (range <= 1);
654 uint8_t r = ((range % 2) == 0);
656 return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
659 static int send_dux_commands(struct comedi_device *dev, unsigned int cmd_type)
661 struct usb_device *usb = comedi_to_usb_dev(dev);
662 struct usbdux_private *devpriv = dev->private;
665 devpriv->dux_commands[0] = cmd_type;
667 return usb_bulk_msg(usb, usb_sndbulkpipe(usb, 1),
668 devpriv->dux_commands, SIZEOFDUXBUFFER,
669 &nsent, BULK_TIMEOUT);
672 static int receive_dux_commands(struct comedi_device *dev, unsigned int command)
674 struct usb_device *usb = comedi_to_usb_dev(dev);
675 struct usbdux_private *devpriv = dev->private;
680 for (i = 0; i < RETRIES; i++) {
681 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, 8),
682 devpriv->insn_buf, SIZEINSNBUF,
683 &nrec, BULK_TIMEOUT);
686 if (le16_to_cpu(devpriv->insn_buf[0]) == command)
689 /* command not received */
693 static int usbdux_ai_inttrig(struct comedi_device *dev,
694 struct comedi_subdevice *s,
695 unsigned int trignum)
697 struct usbdux_private *devpriv = dev->private;
705 if (!devpriv->ai_cmd_running) {
706 devpriv->ai_cmd_running = 1;
707 ret = usbdux_submit_urbs(dev, devpriv->ai_urbs,
708 devpriv->n_ai_urbs, 1);
710 devpriv->ai_cmd_running = 0;
713 s->async->inttrig = NULL;
723 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
725 struct usbdux_private *devpriv = dev->private;
726 struct comedi_cmd *cmd = &s->async->cmd;
727 int len = cmd->chanlist_len;
731 /* block other CPUs from starting an ai_cmd */
734 if (devpriv->ai_cmd_running)
737 /* set current channel of the running acquisition to zero */
738 s->async->cur_chan = 0;
740 devpriv->dux_commands[1] = len;
741 for (i = 0; i < len; ++i) {
742 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
743 unsigned int range = CR_RANGE(cmd->chanlist[i]);
745 devpriv->dux_commands[i + 2] = create_adc_command(chan, range);
748 ret = send_dux_commands(dev, USBDUX_CMD_MULT_AI);
752 if (devpriv->high_speed) {
754 * every channel gets a time window of 125us. Thus, if we
755 * sample all 8 channels we need 1ms. If we sample only one
756 * channel we need only 125us
758 devpriv->ai_interval = 1;
759 /* find a power of 2 for the interval */
760 while (devpriv->ai_interval < len)
761 devpriv->ai_interval *= 2;
763 devpriv->ai_timer = cmd->scan_begin_arg /
764 (125000 * devpriv->ai_interval);
766 /* interval always 1ms */
767 devpriv->ai_interval = 1;
768 devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
770 if (devpriv->ai_timer < 1) {
775 devpriv->ai_counter = devpriv->ai_timer;
777 if (cmd->stop_src == TRIG_COUNT) {
778 /* data arrives as one packet */
779 devpriv->ai_sample_count = cmd->stop_arg;
780 devpriv->ai_continous = 0;
782 /* continous acquisition */
783 devpriv->ai_continous = 1;
784 devpriv->ai_sample_count = 0;
787 if (cmd->start_src == TRIG_NOW) {
788 /* enable this acquisition operation */
789 devpriv->ai_cmd_running = 1;
790 ret = usbdux_submit_urbs(dev, devpriv->ai_urbs,
791 devpriv->n_ai_urbs, 1);
793 devpriv->ai_cmd_running = 0;
794 /* fixme: unlink here?? */
797 s->async->inttrig = NULL;
800 /* don't enable the acquision operation */
801 /* wait for an internal signal */
802 s->async->inttrig = usbdux_ai_inttrig;
811 /* Mode 0 is used to get a single conversion on demand */
812 static int usbdux_ai_insn_read(struct comedi_device *dev,
813 struct comedi_subdevice *s,
814 struct comedi_insn *insn,
817 struct usbdux_private *devpriv = dev->private;
818 unsigned int chan = CR_CHAN(insn->chanspec);
819 unsigned int range = CR_RANGE(insn->chanspec);
826 if (devpriv->ai_cmd_running)
829 /* set command for the first channel */
830 devpriv->dux_commands[1] = create_adc_command(chan, range);
833 ret = send_dux_commands(dev, USBDUX_CMD_SINGLE_AI);
837 for (i = 0; i < insn->n; i++) {
838 ret = receive_dux_commands(dev, USBDUX_CMD_SINGLE_AI);
842 val = le16_to_cpu(devpriv->insn_buf[1]);
844 /* bipolar data is two's-complement */
845 if (comedi_range_is_bipolar(s, range))
846 val ^= ((s->maxdata + 1) >> 1);
854 return ret ? ret : insn->n;
857 static int usbdux_ao_insn_read(struct comedi_device *dev,
858 struct comedi_subdevice *s,
859 struct comedi_insn *insn,
862 struct usbdux_private *devpriv = dev->private;
863 unsigned int chan = CR_CHAN(insn->chanspec);
867 for (i = 0; i < insn->n; i++)
868 data[i] = devpriv->ao_readback[chan];
874 static int usbdux_ao_insn_write(struct comedi_device *dev,
875 struct comedi_subdevice *s,
876 struct comedi_insn *insn,
879 struct usbdux_private *devpriv = dev->private;
880 unsigned int chan = CR_CHAN(insn->chanspec);
881 unsigned int val = devpriv->ao_readback[chan];
882 uint16_t *p = (uint16_t *)&devpriv->dux_commands[2];
888 if (devpriv->ao_cmd_running)
891 /* number of channels: 1 */
892 devpriv->dux_commands[1] = 1;
894 devpriv->dux_commands[4] = chan << 6;
896 for (i = 0; i < insn->n; i++) {
899 /* one 16 bit value */
900 *p = cpu_to_le16(val);
902 ret = send_dux_commands(dev, USBDUX_CMD_AO);
906 devpriv->ao_readback[chan] = val;
911 return ret ? ret : insn->n;
914 static int usbdux_ao_inttrig(struct comedi_device *dev,
915 struct comedi_subdevice *s,
916 unsigned int trignum)
918 struct usbdux_private *devpriv = dev->private;
926 if (!devpriv->ao_cmd_running) {
927 devpriv->ao_cmd_running = 1;
928 ret = usbdux_submit_urbs(dev, devpriv->ao_urbs,
929 devpriv->n_ao_urbs, 0);
931 devpriv->ao_cmd_running = 0;
934 s->async->inttrig = NULL;
944 static int usbdux_ao_cmdtest(struct comedi_device *dev,
945 struct comedi_subdevice *s, struct comedi_cmd *cmd)
947 struct usbdux_private *this_usbduxsub = dev->private;
954 /* Step 1 : check if triggers are trivially valid */
956 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
958 if (0) { /* (this_usbduxsub->high_speed) */
959 /* the sampling rate is set by the coversion rate */
962 /* start a new scan (output at once) with a timer */
965 err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
967 if (0) { /* (this_usbduxsub->high_speed) */
969 * in usb-2.0 only one conversion it transmitted
975 * all conversion events happen simultaneously with
980 err |= cfc_check_trigger_src(&cmd->convert_src, flags);
982 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
983 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
988 /* Step 2a : make sure trigger sources are unique */
990 err |= cfc_check_trigger_is_unique(cmd->start_src);
991 err |= cfc_check_trigger_is_unique(cmd->stop_src);
993 /* Step 2b : and mutually compatible */
998 /* Step 3: check if arguments are trivially valid */
1000 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1002 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
1003 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1005 if (cmd->scan_begin_src == TRIG_TIMER)
1006 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1009 /* not used now, is for later use */
1010 if (cmd->convert_src == TRIG_TIMER)
1011 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
1013 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1015 if (cmd->stop_src == TRIG_COUNT) {
1016 /* any count is allowed */
1019 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1028 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1030 struct usbdux_private *devpriv = dev->private;
1031 struct comedi_cmd *cmd = &s->async->cmd;
1035 down(&devpriv->sem);
1037 if (devpriv->ao_cmd_running)
1040 /* set current channel of the running acquisition to zero */
1041 s->async->cur_chan = 0;
1043 for (i = 0; i < cmd->chanlist_len; ++i) {
1044 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
1046 devpriv->ao_chanlist[i] = chan << 6;
1049 /* we count in steps of 1ms (125us) */
1050 /* 125us mode not used yet */
1051 if (0) { /* (devpriv->high_speed) */
1053 /* timing of the conversion itself: every 125 us */
1054 devpriv->ao_timer = cmd->convert_arg / 125000;
1057 /* timing of the scan: we get all channels at once */
1058 devpriv->ao_timer = cmd->scan_begin_arg / 1000000;
1059 if (devpriv->ao_timer < 1) {
1065 devpriv->ao_counter = devpriv->ao_timer;
1067 if (cmd->stop_src == TRIG_COUNT) {
1068 /* not continuous */
1070 /* high speed also scans everything at once */
1071 if (0) { /* (devpriv->high_speed) */
1072 devpriv->ao_sample_count = cmd->stop_arg *
1075 /* there's no scan as the scan has been */
1076 /* perf inside the FX2 */
1077 /* data arrives as one packet */
1078 devpriv->ao_sample_count = cmd->stop_arg;
1080 devpriv->ao_continous = 0;
1082 /* continous acquisition */
1083 devpriv->ao_continous = 1;
1084 devpriv->ao_sample_count = 0;
1087 if (cmd->start_src == TRIG_NOW) {
1088 /* enable this acquisition operation */
1089 devpriv->ao_cmd_running = 1;
1090 ret = usbdux_submit_urbs(dev, devpriv->ao_urbs,
1091 devpriv->n_ao_urbs, 0);
1093 devpriv->ao_cmd_running = 0;
1094 /* fixme: unlink here?? */
1097 s->async->inttrig = NULL;
1100 /* submit the urbs later */
1101 /* wait for an internal signal */
1102 s->async->inttrig = usbdux_ao_inttrig;
1111 static int usbdux_dio_insn_config(struct comedi_device *dev,
1112 struct comedi_subdevice *s,
1113 struct comedi_insn *insn,
1118 ret = comedi_dio_insn_config(dev, s, insn, data, 0);
1123 * We don't tell the firmware here as it would take 8 frames
1124 * to submit the information. We do it in the insn_bits.
1129 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1130 struct comedi_subdevice *s,
1131 struct comedi_insn *insn,
1135 struct usbdux_private *devpriv = dev->private;
1138 down(&devpriv->sem);
1140 comedi_dio_update_state(s, data);
1142 /* Always update the hardware. See the (*insn_config). */
1143 devpriv->dux_commands[1] = s->io_bits;
1144 devpriv->dux_commands[2] = s->state;
1147 * This command also tells the firmware to return
1148 * the digital input lines.
1150 ret = send_dux_commands(dev, USBDUX_CMD_DIO_BITS);
1153 ret = receive_dux_commands(dev, USBDUX_CMD_DIO_BITS);
1157 data[1] = le16_to_cpu(devpriv->insn_buf[1]);
1162 return ret ? ret : insn->n;
1165 static int usbdux_counter_read(struct comedi_device *dev,
1166 struct comedi_subdevice *s,
1167 struct comedi_insn *insn,
1170 struct usbdux_private *devpriv = dev->private;
1171 unsigned int chan = CR_CHAN(insn->chanspec);
1175 down(&devpriv->sem);
1177 for (i = 0; i < insn->n; i++) {
1178 ret = send_dux_commands(dev, USBDUX_CMD_TIMER_RD);
1180 goto counter_read_exit;
1181 ret = receive_dux_commands(dev, USBDUX_CMD_TIMER_RD);
1183 goto counter_read_exit;
1185 data[i] = le16_to_cpu(devpriv->insn_buf[chan + 1]);
1191 return ret ? ret : insn->n;
1194 static int usbdux_counter_write(struct comedi_device *dev,
1195 struct comedi_subdevice *s,
1196 struct comedi_insn *insn,
1199 struct usbdux_private *devpriv = dev->private;
1200 unsigned int chan = CR_CHAN(insn->chanspec);
1201 uint16_t *p = (uint16_t *)&devpriv->dux_commands[2];
1205 down(&devpriv->sem);
1207 devpriv->dux_commands[1] = chan;
1209 for (i = 0; i < insn->n; i++) {
1210 *p = cpu_to_le16(data[i]);
1212 ret = send_dux_commands(dev, USBDUX_CMD_TIMER_WR);
1219 return ret ? ret : insn->n;
1222 static int usbdux_counter_config(struct comedi_device *dev,
1223 struct comedi_subdevice *s,
1224 struct comedi_insn *insn, unsigned int *data)
1226 /* nothing to do so far */
1230 static void usbduxsub_unlink_pwm_urbs(struct comedi_device *dev)
1232 struct usbdux_private *devpriv = dev->private;
1234 usb_kill_urb(devpriv->pwm_urb);
1237 static void usbdux_pwm_stop(struct comedi_device *dev, int do_unlink)
1239 struct usbdux_private *devpriv = dev->private;
1242 usbduxsub_unlink_pwm_urbs(dev);
1244 devpriv->pwm_cmd_running = 0;
1247 static int usbdux_pwm_cancel(struct comedi_device *dev,
1248 struct comedi_subdevice *s)
1250 struct usbdux_private *devpriv = dev->private;
1253 down(&devpriv->sem);
1254 /* unlink only if it is really running */
1255 usbdux_pwm_stop(dev, devpriv->pwm_cmd_running);
1256 ret = send_dux_commands(dev, USBDUX_CMD_PWM_OFF);
1262 static void usbduxsub_pwm_irq(struct urb *urb)
1264 struct comedi_device *dev = urb->context;
1265 struct usbdux_private *devpriv = dev->private;
1268 switch (urb->status) {
1278 * after an unlink command, unplug, ... etc
1279 * no unlink needed here. Already shutting down.
1281 if (devpriv->pwm_cmd_running)
1282 usbdux_pwm_stop(dev, 0);
1288 if (devpriv->pwm_cmd_running) {
1289 dev_err(dev->class_dev,
1290 "Non-zero urb status received in pwm intr context: %d\n",
1292 usbdux_pwm_stop(dev, 0);
1297 /* are we actually running? */
1298 if (!devpriv->pwm_cmd_running)
1301 urb->transfer_buffer_length = devpriv->pwm_buf_sz;
1302 urb->dev = comedi_to_usb_dev(dev);
1304 if (devpriv->pwm_cmd_running) {
1305 ret = usb_submit_urb(urb, GFP_ATOMIC);
1307 dev_err(dev->class_dev,
1308 "pwm urb resubm failed in int-cont. ret=%d",
1310 if (ret == EL2NSYNC)
1311 dev_err(dev->class_dev,
1312 "buggy USB host controller or bug in IRQ handling!\n");
1314 /* don't do an unlink here */
1315 usbdux_pwm_stop(dev, 0);
1320 static int usbduxsub_submit_pwm_urbs(struct comedi_device *dev)
1322 struct usb_device *usb = comedi_to_usb_dev(dev);
1323 struct usbdux_private *devpriv = dev->private;
1324 struct urb *urb = devpriv->pwm_urb;
1326 /* in case of a resubmission after an unlink... */
1327 usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, 4),
1328 urb->transfer_buffer,
1329 devpriv->pwm_buf_sz,
1333 return usb_submit_urb(urb, GFP_ATOMIC);
1336 static int usbdux_pwm_period(struct comedi_device *dev,
1337 struct comedi_subdevice *s,
1338 unsigned int period)
1340 struct usbdux_private *devpriv = dev->private;
1343 if (period < MIN_PWM_PERIOD) {
1346 fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
1350 devpriv->pwm_delay = fx2delay;
1351 devpriv->pwm_period = period;
1356 static int usbdux_pwm_start(struct comedi_device *dev,
1357 struct comedi_subdevice *s)
1359 struct usbdux_private *devpriv = dev->private;
1362 down(&devpriv->sem);
1364 if (devpriv->pwm_cmd_running)
1365 goto pwm_start_exit;
1367 devpriv->dux_commands[1] = devpriv->pwm_delay;
1368 ret = send_dux_commands(dev, USBDUX_CMD_PWM_ON);
1370 goto pwm_start_exit;
1372 /* initialise the buffer */
1373 memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);
1375 devpriv->pwm_cmd_running = 1;
1376 ret = usbduxsub_submit_pwm_urbs(dev);
1378 devpriv->pwm_cmd_running = 0;
1386 static void usbdux_pwm_pattern(struct comedi_device *dev,
1387 struct comedi_subdevice *s,
1392 struct usbdux_private *devpriv = dev->private;
1393 char pwm_mask = (1 << chan); /* DIO bit for the PWM data */
1394 char sgn_mask = (16 << chan); /* DIO bit for the sign */
1395 char *buf = (char *)(devpriv->pwm_urb->transfer_buffer);
1396 int szbuf = devpriv->pwm_buf_sz;
1399 for (i = 0; i < szbuf; i++) {
1413 static int usbdux_pwm_write(struct comedi_device *dev,
1414 struct comedi_subdevice *s,
1415 struct comedi_insn *insn,
1418 unsigned int chan = CR_CHAN(insn->chanspec);
1421 * It doesn't make sense to support more than one value here
1422 * because it would just overwrite the PWM buffer.
1428 * The sign is set via a special INSN only, this gives us 8 bits
1429 * for normal operation, sign is 0 by default.
1431 usbdux_pwm_pattern(dev, s, chan, data[0], 0);
1436 static int usbdux_pwm_config(struct comedi_device *dev,
1437 struct comedi_subdevice *s,
1438 struct comedi_insn *insn,
1441 struct usbdux_private *devpriv = dev->private;
1442 unsigned int chan = CR_CHAN(insn->chanspec);
1445 case INSN_CONFIG_ARM:
1447 * if not zero the PWM is limited to a certain time which is
1448 * not supported here
1452 return usbdux_pwm_start(dev, s);
1453 case INSN_CONFIG_DISARM:
1454 return usbdux_pwm_cancel(dev, s);
1455 case INSN_CONFIG_GET_PWM_STATUS:
1456 data[1] = devpriv->pwm_cmd_running;
1458 case INSN_CONFIG_PWM_SET_PERIOD:
1459 return usbdux_pwm_period(dev, s, data[1]);
1460 case INSN_CONFIG_PWM_GET_PERIOD:
1461 data[1] = devpriv->pwm_period;
1463 case INSN_CONFIG_PWM_SET_H_BRIDGE:
1466 * data[2] = sign (for a relay)
1468 usbdux_pwm_pattern(dev, s, chan, data[1], (data[2] != 0));
1470 case INSN_CONFIG_PWM_GET_H_BRIDGE:
1471 /* values are not kept in this driver, nothing to return here */
1477 static int usbdux_firmware_upload(struct comedi_device *dev,
1478 const u8 *data, size_t size,
1479 unsigned long context)
1481 struct usb_device *usb = comedi_to_usb_dev(dev);
1489 if (size > USBDUX_FIRMWARE_MAX_LEN) {
1490 dev_err(dev->class_dev,
1491 "usbdux firmware binary it too large for FX2.\n");
1495 /* we generate a local buffer for the firmware */
1496 buf = kmemdup(data, size, GFP_KERNEL);
1500 /* we need a malloc'ed buffer for usb_control_msg() */
1501 tmp = kmalloc(1, GFP_KERNEL);
1507 /* stop the current firmware on the device */
1508 *tmp = 1; /* 7f92 to one */
1509 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1510 USBDUX_FIRMWARE_CMD,
1512 USBDUX_CPU_CS, 0x0000,
1516 dev_err(dev->class_dev, "can not stop firmware\n");
1520 /* upload the new firmware to the device */
1521 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1522 USBDUX_FIRMWARE_CMD,
1528 dev_err(dev->class_dev, "firmware upload failed\n");
1532 /* start the new firmware on the device */
1533 *tmp = 0; /* 7f92 to zero */
1534 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1535 USBDUX_FIRMWARE_CMD,
1537 USBDUX_CPU_CS, 0x0000,
1541 dev_err(dev->class_dev, "can not start firmware\n");
1549 static int usbdux_alloc_usb_buffers(struct comedi_device *dev)
1551 struct usb_device *usb = comedi_to_usb_dev(dev);
1552 struct usbdux_private *devpriv = dev->private;
1556 devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1557 devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL);
1558 devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1559 devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(void *),
1561 devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(void *),
1563 if (!devpriv->dux_commands || !devpriv->in_buf || !devpriv->insn_buf ||
1564 !devpriv->ai_urbs || !devpriv->ao_urbs)
1567 for (i = 0; i < devpriv->n_ai_urbs; i++) {
1568 /* one frame: 1ms */
1569 urb = usb_alloc_urb(1, GFP_KERNEL);
1572 devpriv->ai_urbs[i] = urb;
1576 urb->pipe = usb_rcvisocpipe(usb, 6);
1577 urb->transfer_flags = URB_ISO_ASAP;
1578 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1579 if (!urb->transfer_buffer)
1582 urb->complete = usbduxsub_ai_isoc_irq;
1583 urb->number_of_packets = 1;
1584 urb->transfer_buffer_length = SIZEINBUF;
1585 urb->iso_frame_desc[0].offset = 0;
1586 urb->iso_frame_desc[0].length = SIZEINBUF;
1589 for (i = 0; i < devpriv->n_ao_urbs; i++) {
1590 /* one frame: 1ms */
1591 urb = usb_alloc_urb(1, GFP_KERNEL);
1594 devpriv->ao_urbs[i] = urb;
1598 urb->pipe = usb_sndisocpipe(usb, 2);
1599 urb->transfer_flags = URB_ISO_ASAP;
1600 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1601 if (!urb->transfer_buffer)
1604 urb->complete = usbduxsub_ao_isoc_irq;
1605 urb->number_of_packets = 1;
1606 urb->transfer_buffer_length = SIZEOUTBUF;
1607 urb->iso_frame_desc[0].offset = 0;
1608 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1609 if (devpriv->high_speed)
1610 urb->interval = 8; /* uframes */
1612 urb->interval = 1; /* frames */
1616 if (devpriv->pwm_buf_sz) {
1617 urb = usb_alloc_urb(0, GFP_KERNEL);
1620 devpriv->pwm_urb = urb;
1622 /* max bulk ep size in high speed */
1623 urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz,
1625 if (!urb->transfer_buffer)
1632 static void usbdux_free_usb_buffers(struct comedi_device *dev)
1634 struct usbdux_private *devpriv = dev->private;
1638 urb = devpriv->pwm_urb;
1640 kfree(urb->transfer_buffer);
1643 if (devpriv->ao_urbs) {
1644 for (i = 0; i < devpriv->n_ao_urbs; i++) {
1645 urb = devpriv->ao_urbs[i];
1647 kfree(urb->transfer_buffer);
1651 kfree(devpriv->ao_urbs);
1653 if (devpriv->ai_urbs) {
1654 for (i = 0; i < devpriv->n_ai_urbs; i++) {
1655 urb = devpriv->ai_urbs[i];
1657 kfree(urb->transfer_buffer);
1661 kfree(devpriv->ai_urbs);
1663 kfree(devpriv->insn_buf);
1664 kfree(devpriv->in_buf);
1665 kfree(devpriv->dux_commands);
1668 static int usbdux_auto_attach(struct comedi_device *dev,
1669 unsigned long context_unused)
1671 struct usb_interface *intf = comedi_to_usb_interface(dev);
1672 struct usb_device *usb = comedi_to_usb_dev(dev);
1673 struct usbdux_private *devpriv;
1674 struct comedi_subdevice *s;
1677 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1681 sema_init(&devpriv->sem, 1);
1683 usb_set_intfdata(intf, devpriv);
1685 devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1686 if (devpriv->high_speed) {
1687 devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH;
1688 devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH;
1689 devpriv->pwm_buf_sz = 512;
1691 devpriv->n_ai_urbs = NUMOFINBUFFERSFULL;
1692 devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL;
1695 ret = usbdux_alloc_usb_buffers(dev);
1699 /* setting to alternate setting 3: enabling iso ep and bulk ep. */
1700 ret = usb_set_interface(usb, intf->altsetting->desc.bInterfaceNumber,
1703 dev_err(dev->class_dev,
1704 "could not set alternate setting 3 in high speed\n");
1708 ret = comedi_load_firmware(dev, &usb->dev, USBDUX_FIRMWARE,
1709 usbdux_firmware_upload, 0);
1713 ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 5 : 4);
1717 /* Analog Input subdevice */
1718 s = &dev->subdevices[0];
1719 dev->read_subdev = s;
1720 s->type = COMEDI_SUBD_AI;
1721 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
1723 s->maxdata = 0x0fff;
1724 s->len_chanlist = 8;
1725 s->range_table = &range_usbdux_ai_range;
1726 s->insn_read = usbdux_ai_insn_read;
1727 s->do_cmdtest = usbdux_ai_cmdtest;
1728 s->do_cmd = usbdux_ai_cmd;
1729 s->cancel = usbdux_ai_cancel;
1731 /* Analog Output subdevice */
1732 s = &dev->subdevices[1];
1733 dev->write_subdev = s;
1734 s->type = COMEDI_SUBD_AO;
1735 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1736 s->n_chan = USBDUX_NUM_AO_CHAN;
1737 s->maxdata = 0x0fff;
1738 s->len_chanlist = s->n_chan;
1739 s->range_table = &range_usbdux_ao_range;
1740 s->do_cmdtest = usbdux_ao_cmdtest;
1741 s->do_cmd = usbdux_ao_cmd;
1742 s->cancel = usbdux_ao_cancel;
1743 s->insn_read = usbdux_ao_insn_read;
1744 s->insn_write = usbdux_ao_insn_write;
1746 /* Digital I/O subdevice */
1747 s = &dev->subdevices[2];
1748 s->type = COMEDI_SUBD_DIO;
1749 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1752 s->range_table = &range_digital;
1753 s->insn_bits = usbdux_dio_insn_bits;
1754 s->insn_config = usbdux_dio_insn_config;
1756 /* Counter subdevice */
1757 s = &dev->subdevices[3];
1758 s->type = COMEDI_SUBD_COUNTER;
1759 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1761 s->maxdata = 0xffff;
1762 s->insn_read = usbdux_counter_read;
1763 s->insn_write = usbdux_counter_write;
1764 s->insn_config = usbdux_counter_config;
1766 if (devpriv->high_speed) {
1768 s = &dev->subdevices[4];
1769 s->type = COMEDI_SUBD_PWM;
1770 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1772 s->maxdata = devpriv->pwm_buf_sz;
1773 s->insn_write = usbdux_pwm_write;
1774 s->insn_config = usbdux_pwm_config;
1776 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1782 static void usbdux_detach(struct comedi_device *dev)
1784 struct usb_interface *intf = comedi_to_usb_interface(dev);
1785 struct usbdux_private *devpriv = dev->private;
1787 usb_set_intfdata(intf, NULL);
1792 down(&devpriv->sem);
1794 /* force unlink all urbs */
1795 usbdux_pwm_stop(dev, 1);
1796 usbdux_ao_stop(dev, 1);
1797 usbdux_ai_stop(dev, 1);
1799 usbdux_free_usb_buffers(dev);
1804 static struct comedi_driver usbdux_driver = {
1805 .driver_name = "usbdux",
1806 .module = THIS_MODULE,
1807 .auto_attach = usbdux_auto_attach,
1808 .detach = usbdux_detach,
1811 static int usbdux_usb_probe(struct usb_interface *intf,
1812 const struct usb_device_id *id)
1814 return comedi_usb_auto_config(intf, &usbdux_driver, 0);
1817 static const struct usb_device_id usbdux_usb_table[] = {
1818 { USB_DEVICE(0x13d8, 0x0001) },
1819 { USB_DEVICE(0x13d8, 0x0002) },
1822 MODULE_DEVICE_TABLE(usb, usbdux_usb_table);
1824 static struct usb_driver usbdux_usb_driver = {
1826 .probe = usbdux_usb_probe,
1827 .disconnect = comedi_usb_auto_unconfig,
1828 .id_table = usbdux_usb_table,
1830 module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver);
1832 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1833 MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com");
1834 MODULE_LICENSE("GPL");
1835 MODULE_FIRMWARE(USBDUX_FIRMWARE);