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/init.h>
84 #include <linux/slab.h>
85 #include <linux/input.h>
86 #include <linux/usb.h>
87 #include <linux/fcntl.h>
88 #include <linux/compiler.h>
90 #include "../comedidev.h"
92 #include "comedi_fc.h"
94 /* timeout for the USB-transfer in ms*/
95 #define BULK_TIMEOUT 1000
97 /* constants for "firmware" upload and download */
98 #define FIRMWARE "usbdux_firmware.bin"
99 #define USBDUXSUB_FIRMWARE 0xA0
100 #define VENDOR_DIR_IN 0xC0
101 #define VENDOR_DIR_OUT 0x40
103 /* internal addresses of the 8051 processor */
104 #define USBDUXSUB_CPUCS 0xE600
107 * the minor device number, major is 180 only for debugging purposes and to
108 * upload special firmware (programming the eeprom etc) which is not compatible
109 * with the comedi framwork
111 #define USBDUXSUB_MINOR 32
113 /* max lenghth of the transfer-buffer for software upload */
114 #define TB_LEN 0x2000
116 /* Input endpoint number: ISO/IRQ */
119 /* Output endpoint number: ISO/IRQ */
122 /* This EP sends DUX commands to USBDUX */
123 #define COMMAND_OUT_EP 1
125 /* This EP receives the DUX commands from USBDUX */
126 #define COMMAND_IN_EP 8
128 /* Output endpoint for PWM */
131 /* 300Hz max frequ under PWM */
132 #define MIN_PWM_PERIOD ((long)(1E9/300))
134 /* Default PWM frequency */
135 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
137 /* Number of channels */
138 #define NUMCHANNELS 8
140 /* Size of one A/D value */
141 #define SIZEADIN ((sizeof(int16_t)))
144 * Size of the input-buffer IN BYTES
145 * Always multiple of 8 for 8 microframes which is needed in the highspeed mode
147 #define SIZEINBUF ((8*SIZEADIN))
150 #define SIZEINSNBUF 16
152 /* Number of DA channels */
153 #define NUMOUTCHANNELS 8
155 /* size of one value for the D/A converter: channel and value */
156 #define SIZEDAOUT ((sizeof(int8_t)+sizeof(int16_t)))
159 * Size of the output-buffer in bytes
160 * Actually only the first 4 triplets are used but for the
161 * high speed mode we need to pad it to 8 (microframes).
163 #define SIZEOUTBUF ((8*SIZEDAOUT))
166 * Size of the buffer for the dux commands: just now max size is determined
167 * by the analogue out + command byte + panic bytes...
169 #define SIZEOFDUXBUFFER ((8*SIZEDAOUT+2))
171 /* Number of in-URBs which receive the data: min=2 */
172 #define NUMOFINBUFFERSFULL 5
174 /* Number of out-URBs which send the data: min=2 */
175 #define NUMOFOUTBUFFERSFULL 5
177 /* Number of in-URBs which receive the data: min=5 */
178 /* must have more buffers due to buggy USB ctr */
179 #define NUMOFINBUFFERSHIGH 10
181 /* Number of out-URBs which send the data: min=5 */
182 /* must have more buffers due to buggy USB ctr */
183 #define NUMOFOUTBUFFERSHIGH 10
185 /* number of retries to get the right dux command */
188 static const struct comedi_lrange range_usbdux_ai_range = {
191 BIP_RANGE(4.096 / 2),
197 static const struct comedi_lrange range_usbdux_ao_range = {
204 struct usbdux_private {
205 /* pointer to the usb-device */
206 struct usb_device *usbdev;
207 /* actual number of in-buffers */
209 /* actual number of out-buffers */
211 /* ISO-transfer handling: buffers */
213 struct urb **urb_out;
214 /* pwm-transfer handling */
217 unsigned int pwm_period;
218 /* PWM internal delay for the GPIF in the FX2 */
220 /* size of the PWM buffer which holds the bit pattern */
222 /* input buffer for the ISO-transfer */
224 /* input buffer for single insn */
225 int16_t *insn_buffer;
226 /* output buffer for single DA outputs */
228 /* interface number */
230 /* interface structure in 2.6 */
231 struct usb_interface *interface;
232 /* comedi device for the interrupt context */
233 struct comedi_device *comedidev;
234 /* is it USB_SPEED_HIGH or not? */
235 short int high_speed;
236 /* asynchronous command is running */
237 short int ai_cmd_running;
238 short int ao_cmd_running;
240 short int pwm_cmd_running;
241 /* continous acquisition */
242 short int ai_continous;
243 short int ao_continous;
244 /* number of samples to acquire */
247 /* time between samples in units of the timer */
248 unsigned int ai_timer;
249 unsigned int ao_timer;
250 /* counter between aquisitions */
251 unsigned int ai_counter;
252 unsigned int ao_counter;
253 /* interval in frames/uframes */
254 unsigned int ai_interval;
256 int8_t *dac_commands;
258 int8_t *dux_commands;
259 struct semaphore sem;
263 * Stops the data acquision
264 * It should be safe to call this function from any context
266 static int usbduxsub_unlink_inurbs(struct usbdux_private *usbduxsub_tmp)
271 if (usbduxsub_tmp && usbduxsub_tmp->urb_in) {
272 for (i = 0; i < usbduxsub_tmp->num_in_buffers; i++) {
273 if (usbduxsub_tmp->urb_in[i]) {
274 /* We wait here until all transfers have been
276 usb_kill_urb(usbduxsub_tmp->urb_in[i]);
278 dev_dbg(&usbduxsub_tmp->interface->dev,
279 "comedi: usbdux: unlinked InURB %d, err=%d\n",
287 * This will stop a running acquisition operation
288 * Is called from within this driver from both the
289 * interrupt context and from comedi
291 static int usbdux_ai_stop(struct usbdux_private *this_usbduxsub, int do_unlink)
295 if (!this_usbduxsub) {
296 pr_err("comedi?: usbdux_ai_stop: this_usbduxsub=NULL!\n");
299 dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_stop\n");
303 ret = usbduxsub_unlink_inurbs(this_usbduxsub);
306 this_usbduxsub->ai_cmd_running = 0;
312 * This will cancel a running acquisition operation.
313 * This is called by comedi but never from inside the driver.
315 static int usbdux_ai_cancel(struct comedi_device *dev,
316 struct comedi_subdevice *s)
318 struct usbdux_private *this_usbduxsub;
321 /* force unlink of all urbs */
322 this_usbduxsub = dev->private;
326 dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_cancel\n");
328 /* prevent other CPUs from submitting new commands just now */
329 down(&this_usbduxsub->sem);
330 /* unlink only if the urb really has been submitted */
331 res = usbdux_ai_stop(this_usbduxsub, this_usbduxsub->ai_cmd_running);
332 up(&this_usbduxsub->sem);
336 /* analogue IN - interrupt service routine */
337 static void usbduxsub_ai_isoc_irq(struct urb *urb)
339 struct comedi_device *dev = urb->context;
340 struct comedi_subdevice *s = dev->read_subdev;
341 struct usbdux_private *devpriv = dev->private;
344 /* first we test if something unusual has just happened */
345 switch (urb->status) {
347 /* copy the result in the transfer buffer */
348 memcpy(devpriv->in_buffer, urb->transfer_buffer, SIZEINBUF);
351 /* error in the ISOchronous data */
352 /* we don't copy the data into the transfer buffer */
353 /* and recycle the last data byte */
354 dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
361 /* happens after an unlink command */
362 if (devpriv->ai_cmd_running) {
363 s->async->events |= COMEDI_CB_EOA;
364 s->async->events |= COMEDI_CB_ERROR;
365 comedi_event(dev, s);
366 /* stop the transfer w/o unlink */
367 usbdux_ai_stop(devpriv, 0);
372 /* a real error on the bus */
373 /* pass error to comedi if we are really running a command */
374 if (devpriv->ai_cmd_running) {
375 dev_err(dev->class_dev,
376 "Non-zero urb status received in ai intr context: %d\n",
378 s->async->events |= COMEDI_CB_EOA;
379 s->async->events |= COMEDI_CB_ERROR;
380 comedi_event(dev, s);
381 /* don't do an unlink here */
382 usbdux_ai_stop(devpriv, 0);
388 * at this point we are reasonably sure that nothing dodgy has happened
389 * are we running a command?
391 if (unlikely(!devpriv->ai_cmd_running)) {
393 * not running a command, do not continue execution if no
394 * asynchronous command is running in particular not resubmit
399 urb->dev = devpriv->usbdev;
401 /* resubmit the urb */
402 err = usb_submit_urb(urb, GFP_ATOMIC);
403 if (unlikely(err < 0)) {
404 dev_err(dev->class_dev,
405 "urb resubmit failed in int-context! err=%d\n", err);
406 if (err == -EL2NSYNC)
407 dev_err(dev->class_dev,
408 "buggy USB host controller or bug in IRQ handler!\n");
409 s->async->events |= COMEDI_CB_EOA;
410 s->async->events |= COMEDI_CB_ERROR;
411 comedi_event(dev, s);
412 /* don't do an unlink here */
413 usbdux_ai_stop(devpriv, 0);
417 devpriv->ai_counter--;
418 if (likely(devpriv->ai_counter > 0))
421 /* timer zero, transfer measurements to comedi */
422 devpriv->ai_counter = devpriv->ai_timer;
424 /* test, if we transmit only a fixed number of samples */
425 if (!devpriv->ai_continous) {
426 /* not continuous, fixed number of samples */
427 devpriv->ai_sample_count--;
428 /* all samples received? */
429 if (devpriv->ai_sample_count < 0) {
430 /* prevent a resubmit next time */
431 usbdux_ai_stop(devpriv, 0);
432 /* say comedi that the acquistion is over */
433 s->async->events |= COMEDI_CB_EOA;
434 comedi_event(dev, s);
438 /* get the data from the USB bus and hand it over to comedi */
439 n = s->async->cmd.chanlist_len;
440 for (i = 0; i < n; i++) {
442 if (CR_RANGE(s->async->cmd.chanlist[i]) <= 1) {
443 err = comedi_buf_put(s->async,
444 le16_to_cpu(devpriv->in_buffer[i]) ^ 0x800);
446 err = comedi_buf_put(s->async,
447 le16_to_cpu(devpriv->in_buffer[i]));
449 if (unlikely(err == 0)) {
450 /* buffer overflow */
451 usbdux_ai_stop(devpriv, 0);
455 /* tell comedi that data is there */
456 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
457 comedi_event(dev, s);
460 static int usbduxsub_unlink_outurbs(struct usbdux_private *usbduxsub_tmp)
465 if (usbduxsub_tmp && usbduxsub_tmp->urb_out) {
466 for (i = 0; i < usbduxsub_tmp->num_out_buffers; i++) {
467 if (usbduxsub_tmp->urb_out[i])
468 usb_kill_urb(usbduxsub_tmp->urb_out[i]);
470 dev_dbg(&usbduxsub_tmp->interface->dev,
471 "comedi: usbdux: unlinked OutURB %d: res=%d\n",
478 /* This will cancel a running acquisition operation
481 static int usbdux_ao_stop(struct usbdux_private *this_usbduxsub, int do_unlink)
487 dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ao_cancel\n");
490 ret = usbduxsub_unlink_outurbs(this_usbduxsub);
492 this_usbduxsub->ao_cmd_running = 0;
497 /* force unlink, is called by comedi */
498 static int usbdux_ao_cancel(struct comedi_device *dev,
499 struct comedi_subdevice *s)
501 struct usbdux_private *this_usbduxsub = dev->private;
507 /* prevent other CPUs from submitting a command just now */
508 down(&this_usbduxsub->sem);
509 /* unlink only if it is really running */
510 res = usbdux_ao_stop(this_usbduxsub, this_usbduxsub->ao_cmd_running);
511 up(&this_usbduxsub->sem);
515 static void usbduxsub_ao_isoc_irq(struct urb *urb)
517 struct comedi_device *dev = urb->context;
518 struct comedi_subdevice *s = dev->write_subdev;
519 struct usbdux_private *devpriv = dev->private;
523 switch (urb->status) {
532 /* after an unlink command, unplug, ... etc */
533 /* no unlink needed here. Already shutting down. */
534 if (devpriv->ao_cmd_running) {
535 s->async->events |= COMEDI_CB_EOA;
536 comedi_event(dev, s);
537 usbdux_ao_stop(devpriv, 0);
543 if (devpriv->ao_cmd_running) {
544 dev_err(dev->class_dev,
545 "Non-zero urb status received in ao intr context: %d\n",
547 s->async->events |= COMEDI_CB_ERROR;
548 s->async->events |= COMEDI_CB_EOA;
549 comedi_event(dev, s);
550 /* we do an unlink if we are in the high speed mode */
551 usbdux_ao_stop(devpriv, 0);
556 /* are we actually running? */
557 if (!devpriv->ao_cmd_running)
560 /* normal operation: executing a command in this subdevice */
561 devpriv->ao_counter--;
562 if ((int)devpriv->ao_counter <= 0) {
564 devpriv->ao_counter = devpriv->ao_timer;
566 /* handle non continous acquisition */
567 if (!devpriv->ao_continous) {
568 /* fixed number of samples */
569 devpriv->ao_sample_count--;
570 if (devpriv->ao_sample_count < 0) {
571 /* all samples transmitted */
572 usbdux_ao_stop(devpriv, 0);
573 s->async->events |= COMEDI_CB_EOA;
574 comedi_event(dev, s);
575 /* no resubmit of the urb */
579 /* transmit data to the USB bus */
580 ((uint8_t *) (urb->transfer_buffer))[0] =
581 s->async->cmd.chanlist_len;
582 for (i = 0; i < s->async->cmd.chanlist_len; i++) {
584 if (i >= NUMOUTCHANNELS)
587 /* pointer to the DA */
589 (&(((int8_t *) urb->transfer_buffer)[i * 3 + 1]));
590 /* get the data from comedi */
591 ret = comedi_buf_get(s->async, &temp);
593 datap[1] = temp >> 8;
594 datap[2] = devpriv->dac_commands[i];
596 dev_err(&urb->dev->dev,
597 "comedi: buffer underflow\n");
598 s->async->events |= COMEDI_CB_EOA;
599 s->async->events |= COMEDI_CB_OVERFLOW;
601 /* transmit data to comedi */
602 s->async->events |= COMEDI_CB_BLOCK;
603 comedi_event(dev, s);
606 urb->transfer_buffer_length = SIZEOUTBUF;
607 urb->dev = devpriv->usbdev;
609 if (devpriv->ao_cmd_running) {
610 if (devpriv->high_speed)
611 urb->interval = 8; /* uframes */
613 urb->interval = 1; /* frames */
614 urb->number_of_packets = 1;
615 urb->iso_frame_desc[0].offset = 0;
616 urb->iso_frame_desc[0].length = SIZEOUTBUF;
617 urb->iso_frame_desc[0].status = 0;
618 ret = usb_submit_urb(urb, GFP_ATOMIC);
620 dev_err(dev->class_dev,
621 "ao urb resubm failed in int-cont. ret=%d",
624 dev_err(dev->class_dev,
625 "buggy USB host controller or bug in IRQ handling!\n");
627 s->async->events |= COMEDI_CB_EOA;
628 s->async->events |= COMEDI_CB_ERROR;
629 comedi_event(dev, s);
630 /* don't do an unlink here */
631 usbdux_ao_stop(devpriv, 0);
636 #define FIRMWARE_MAX_LEN 0x2000
638 static int usbdux_firmware_upload(struct comedi_device *dev,
639 const u8 *data, size_t size,
640 unsigned long context)
642 struct usbdux_private *usbduxsub = dev->private;
643 struct usb_device *usb = usbduxsub->usbdev;
651 if (size > FIRMWARE_MAX_LEN) {
652 dev_err(&usbduxsub->interface->dev,
653 "usbdux firmware binary it too large for FX2.\n");
657 /* we generate a local buffer for the firmware */
658 buf = kmemdup(data, size, GFP_KERNEL);
662 /* we need a malloc'ed buffer for usb_control_msg() */
663 tmp = kmalloc(1, GFP_KERNEL);
669 /* stop the current firmware on the device */
670 *tmp = 1; /* 7f92 to one */
671 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
674 USBDUXSUB_CPUCS, 0x0000,
678 dev_err(&usbduxsub->interface->dev,
679 "comedi_: can not stop firmware\n");
683 /* upload the new firmware to the device */
684 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
691 dev_err(&usbduxsub->interface->dev,
692 "comedi_: firmware upload failed\n");
696 /* start the new firmware on the device */
697 *tmp = 0; /* 7f92 to zero */
698 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
701 USBDUXSUB_CPUCS, 0x0000,
705 dev_err(&usbduxsub->interface->dev,
706 "comedi_: can not start firmware\n");
714 static int usbduxsub_submit_inurbs(struct usbdux_private *usbduxsub)
721 /* Submit all URBs and start the transfer on the bus */
722 for (i = 0; i < usbduxsub->num_in_buffers; i++) {
723 /* in case of a resubmission after an unlink... */
724 usbduxsub->urb_in[i]->interval = usbduxsub->ai_interval;
725 usbduxsub->urb_in[i]->context = usbduxsub->comedidev;
726 usbduxsub->urb_in[i]->dev = usbduxsub->usbdev;
727 usbduxsub->urb_in[i]->status = 0;
728 usbduxsub->urb_in[i]->transfer_flags = URB_ISO_ASAP;
729 dev_dbg(&usbduxsub->interface->dev,
730 "comedi%d: submitting in-urb[%d]: %p,%p intv=%d\n",
731 usbduxsub->comedidev->minor, i,
732 (usbduxsub->urb_in[i]->context),
733 (usbduxsub->urb_in[i]->dev),
734 (usbduxsub->urb_in[i]->interval));
735 err_flag = usb_submit_urb(usbduxsub->urb_in[i], GFP_ATOMIC);
737 dev_err(&usbduxsub->interface->dev,
738 "comedi_: ai: usb_submit_urb(%d) error %d\n",
746 static int usbduxsub_submit_outurbs(struct usbdux_private *usbduxsub)
753 for (i = 0; i < usbduxsub->num_out_buffers; i++) {
754 dev_dbg(&usbduxsub->interface->dev,
755 "comedi_: submitting out-urb[%d]\n", i);
756 /* in case of a resubmission after an unlink... */
757 usbduxsub->urb_out[i]->context = usbduxsub->comedidev;
758 usbduxsub->urb_out[i]->dev = usbduxsub->usbdev;
759 usbduxsub->urb_out[i]->status = 0;
760 usbduxsub->urb_out[i]->transfer_flags = URB_ISO_ASAP;
761 err_flag = usb_submit_urb(usbduxsub->urb_out[i], GFP_ATOMIC);
763 dev_err(&usbduxsub->interface->dev,
764 "comedi_: ao: usb_submit_urb(%d) error %d\n",
772 static int usbdux_ai_cmdtest(struct comedi_device *dev,
773 struct comedi_subdevice *s, struct comedi_cmd *cmd)
775 struct usbdux_private *this_usbduxsub = dev->private;
777 unsigned int tmp_timer;
779 /* Step 1 : check if triggers are trivially valid */
781 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
782 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
783 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
784 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
785 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
790 /* Step 2a : make sure trigger sources are unique */
792 err |= cfc_check_trigger_is_unique(cmd->start_src);
793 err |= cfc_check_trigger_is_unique(cmd->stop_src);
795 /* Step 2b : and mutually compatible */
800 /* Step 3: check if arguments are trivially valid */
802 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
804 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
805 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
807 if (cmd->scan_begin_src == TRIG_TIMER) {
808 if (this_usbduxsub->high_speed) {
810 * In high speed mode microframes are possible.
811 * However, during one microframe we can roughly
812 * sample one channel. Thus, the more channels
813 * are in the channel list the more time we need.
816 /* find a power of 2 for the number of channels */
817 while (i < (cmd->chanlist_len))
820 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
822 /* now calc the real sampling rate with all the
825 ((unsigned int)(cmd->scan_begin_arg / 125000)) *
829 /* 1kHz scans every USB frame */
830 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
833 * calc the real sampling rate with the rounding errors
835 tmp_timer = ((unsigned int)(cmd->scan_begin_arg /
838 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
842 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
844 if (cmd->stop_src == TRIG_COUNT) {
845 /* any count is allowed */
848 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
858 * creates the ADC command for the MAX1271
859 * range is the range value from comedi
861 static int8_t create_adc_command(unsigned int chan, int range)
863 int8_t p = (range <= 1);
864 int8_t r = ((range % 2) == 0);
865 return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
868 /* bulk transfers to usbdux */
870 #define SENDADCOMMANDS 0
871 #define SENDDACOMMANDS 1
872 #define SENDDIOCONFIGCOMMAND 2
873 #define SENDDIOBITSCOMMAND 3
874 #define SENDSINGLEAD 4
875 #define READCOUNTERCOMMAND 5
876 #define WRITECOUNTERCOMMAND 6
880 static int send_dux_commands(struct usbdux_private *this_usbduxsub, int cmd_type)
884 this_usbduxsub->dux_commands[0] = cmd_type;
885 result = usb_bulk_msg(this_usbduxsub->usbdev,
886 usb_sndbulkpipe(this_usbduxsub->usbdev,
888 this_usbduxsub->dux_commands, SIZEOFDUXBUFFER,
889 &nsent, BULK_TIMEOUT);
891 dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
892 "could not transmit dux_command to the usb-device, "
893 "err=%d\n", this_usbduxsub->comedidev->minor, result);
898 static int receive_dux_commands(struct usbdux_private *this_usbduxsub, int command)
900 int result = (-EFAULT);
904 for (i = 0; i < RETRIES; i++) {
905 result = usb_bulk_msg(this_usbduxsub->usbdev,
906 usb_rcvbulkpipe(this_usbduxsub->usbdev,
908 this_usbduxsub->insn_buffer, SIZEINSNBUF,
909 &nrec, BULK_TIMEOUT);
911 dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
912 "insn: USB error %d while receiving DUX command"
913 "\n", this_usbduxsub->comedidev->minor, result);
916 if (le16_to_cpu(this_usbduxsub->insn_buffer[0]) == command)
919 /* this is only reached if the data has been requested a couple of
921 dev_err(&this_usbduxsub->interface->dev, "comedi%d: insn: "
922 "wrong data returned from firmware: want cmd %d, got cmd %d.\n",
923 this_usbduxsub->comedidev->minor, command,
924 le16_to_cpu(this_usbduxsub->insn_buffer[0]));
928 static int usbdux_ai_inttrig(struct comedi_device *dev,
929 struct comedi_subdevice *s, unsigned int trignum)
932 struct usbdux_private *this_usbduxsub = dev->private;
936 down(&this_usbduxsub->sem);
937 dev_dbg(&this_usbduxsub->interface->dev,
938 "comedi%d: usbdux_ai_inttrig\n", dev->minor);
941 dev_err(&this_usbduxsub->interface->dev,
942 "comedi%d: usbdux_ai_inttrig: invalid trignum\n",
944 up(&this_usbduxsub->sem);
947 if (!(this_usbduxsub->ai_cmd_running)) {
948 this_usbduxsub->ai_cmd_running = 1;
949 ret = usbduxsub_submit_inurbs(this_usbduxsub);
951 dev_err(&this_usbduxsub->interface->dev,
952 "comedi%d: usbdux_ai_inttrig: "
953 "urbSubmit: err=%d\n", dev->minor, ret);
954 this_usbduxsub->ai_cmd_running = 0;
955 up(&this_usbduxsub->sem);
958 s->async->inttrig = NULL;
960 dev_err(&this_usbduxsub->interface->dev,
961 "comedi%d: ai_inttrig but acqu is already running\n",
964 up(&this_usbduxsub->sem);
968 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
970 struct comedi_cmd *cmd = &s->async->cmd;
971 unsigned int chan, range;
973 struct usbdux_private *this_usbduxsub = dev->private;
979 dev_dbg(&this_usbduxsub->interface->dev,
980 "comedi%d: usbdux_ai_cmd\n", dev->minor);
982 /* block other CPUs from starting an ai_cmd */
983 down(&this_usbduxsub->sem);
984 if (this_usbduxsub->ai_cmd_running) {
985 dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
986 "ai_cmd not possible. Another ai_cmd is running.\n",
988 up(&this_usbduxsub->sem);
991 /* set current channel of the running acquisition to zero */
992 s->async->cur_chan = 0;
994 this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
995 for (i = 0; i < cmd->chanlist_len; ++i) {
996 chan = CR_CHAN(cmd->chanlist[i]);
997 range = CR_RANGE(cmd->chanlist[i]);
998 if (i >= NUMCHANNELS) {
999 dev_err(&this_usbduxsub->interface->dev,
1000 "comedi%d: channel list too long\n",
1004 this_usbduxsub->dux_commands[i + 2] =
1005 create_adc_command(chan, range);
1008 dev_dbg(&this_usbduxsub->interface->dev,
1009 "comedi %d: sending commands to the usb device: size=%u\n",
1010 dev->minor, NUMCHANNELS);
1012 result = send_dux_commands(this_usbduxsub, SENDADCOMMANDS);
1014 up(&this_usbduxsub->sem);
1018 if (this_usbduxsub->high_speed) {
1020 * every channel gets a time window of 125us. Thus, if we
1021 * sample all 8 channels we need 1ms. If we sample only one
1022 * channel we need only 125us
1024 this_usbduxsub->ai_interval = 1;
1025 /* find a power of 2 for the interval */
1026 while ((this_usbduxsub->ai_interval) < (cmd->chanlist_len)) {
1027 this_usbduxsub->ai_interval =
1028 (this_usbduxsub->ai_interval) * 2;
1030 this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
1034 /* interval always 1ms */
1035 this_usbduxsub->ai_interval = 1;
1036 this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000;
1038 if (this_usbduxsub->ai_timer < 1) {
1039 dev_err(&this_usbduxsub->interface->dev, "comedi%d: ai_cmd: "
1040 "timer=%d, scan_begin_arg=%d. "
1041 "Not properly tested by cmdtest?\n", dev->minor,
1042 this_usbduxsub->ai_timer, cmd->scan_begin_arg);
1043 up(&this_usbduxsub->sem);
1046 this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
1048 if (cmd->stop_src == TRIG_COUNT) {
1049 /* data arrives as one packet */
1050 this_usbduxsub->ai_sample_count = cmd->stop_arg;
1051 this_usbduxsub->ai_continous = 0;
1053 /* continous acquisition */
1054 this_usbduxsub->ai_continous = 1;
1055 this_usbduxsub->ai_sample_count = 0;
1058 if (cmd->start_src == TRIG_NOW) {
1059 /* enable this acquisition operation */
1060 this_usbduxsub->ai_cmd_running = 1;
1061 ret = usbduxsub_submit_inurbs(this_usbduxsub);
1063 this_usbduxsub->ai_cmd_running = 0;
1064 /* fixme: unlink here?? */
1065 up(&this_usbduxsub->sem);
1068 s->async->inttrig = NULL;
1071 /* don't enable the acquision operation */
1072 /* wait for an internal signal */
1073 s->async->inttrig = usbdux_ai_inttrig;
1075 up(&this_usbduxsub->sem);
1079 /* Mode 0 is used to get a single conversion on demand */
1080 static int usbdux_ai_insn_read(struct comedi_device *dev,
1081 struct comedi_subdevice *s,
1082 struct comedi_insn *insn, unsigned int *data)
1085 unsigned int one = 0;
1088 struct usbdux_private *this_usbduxsub = dev->private;
1090 if (!this_usbduxsub)
1093 dev_dbg(&this_usbduxsub->interface->dev,
1094 "comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n",
1095 dev->minor, insn->n, insn->subdev);
1097 down(&this_usbduxsub->sem);
1098 if (this_usbduxsub->ai_cmd_running) {
1099 dev_err(&this_usbduxsub->interface->dev,
1100 "comedi%d: ai_insn_read not possible. "
1101 "Async Command is running.\n", dev->minor);
1102 up(&this_usbduxsub->sem);
1106 /* sample one channel */
1107 chan = CR_CHAN(insn->chanspec);
1108 range = CR_RANGE(insn->chanspec);
1109 /* set command for the first channel */
1110 this_usbduxsub->dux_commands[1] = create_adc_command(chan, range);
1113 err = send_dux_commands(this_usbduxsub, SENDSINGLEAD);
1115 up(&this_usbduxsub->sem);
1119 for (i = 0; i < insn->n; i++) {
1120 err = receive_dux_commands(this_usbduxsub, SENDSINGLEAD);
1122 up(&this_usbduxsub->sem);
1125 one = le16_to_cpu(this_usbduxsub->insn_buffer[1]);
1126 if (CR_RANGE(insn->chanspec) <= 1)
1131 up(&this_usbduxsub->sem);
1135 /************************************/
1138 static int usbdux_ao_insn_read(struct comedi_device *dev,
1139 struct comedi_subdevice *s,
1140 struct comedi_insn *insn, unsigned int *data)
1143 int chan = CR_CHAN(insn->chanspec);
1144 struct usbdux_private *this_usbduxsub = dev->private;
1146 if (!this_usbduxsub)
1149 down(&this_usbduxsub->sem);
1150 for (i = 0; i < insn->n; i++)
1151 data[i] = this_usbduxsub->out_buffer[chan];
1153 up(&this_usbduxsub->sem);
1157 static int usbdux_ao_insn_write(struct comedi_device *dev,
1158 struct comedi_subdevice *s,
1159 struct comedi_insn *insn, unsigned int *data)
1162 int chan = CR_CHAN(insn->chanspec);
1163 struct usbdux_private *this_usbduxsub = dev->private;
1165 if (!this_usbduxsub)
1168 dev_dbg(&this_usbduxsub->interface->dev,
1169 "comedi%d: ao_insn_write\n", dev->minor);
1171 down(&this_usbduxsub->sem);
1172 if (this_usbduxsub->ao_cmd_running) {
1173 dev_err(&this_usbduxsub->interface->dev,
1174 "comedi%d: ao_insn_write: "
1175 "ERROR: asynchronous ao_cmd is running\n", dev->minor);
1176 up(&this_usbduxsub->sem);
1180 for (i = 0; i < insn->n; i++) {
1181 dev_dbg(&this_usbduxsub->interface->dev,
1182 "comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n",
1183 dev->minor, chan, i, data[i]);
1185 /* number of channels: 1 */
1186 this_usbduxsub->dux_commands[1] = 1;
1187 /* one 16 bit value */
1188 *((int16_t *) (this_usbduxsub->dux_commands + 2)) =
1189 cpu_to_le16(data[i]);
1190 this_usbduxsub->out_buffer[chan] = data[i];
1191 /* channel number */
1192 this_usbduxsub->dux_commands[4] = (chan << 6);
1193 err = send_dux_commands(this_usbduxsub, SENDDACOMMANDS);
1195 up(&this_usbduxsub->sem);
1199 up(&this_usbduxsub->sem);
1204 static int usbdux_ao_inttrig(struct comedi_device *dev,
1205 struct comedi_subdevice *s, unsigned int trignum)
1208 struct usbdux_private *this_usbduxsub = dev->private;
1210 if (!this_usbduxsub)
1213 down(&this_usbduxsub->sem);
1215 dev_err(&this_usbduxsub->interface->dev,
1216 "comedi%d: usbdux_ao_inttrig: invalid trignum\n",
1218 up(&this_usbduxsub->sem);
1221 if (!(this_usbduxsub->ao_cmd_running)) {
1222 this_usbduxsub->ao_cmd_running = 1;
1223 ret = usbduxsub_submit_outurbs(this_usbduxsub);
1225 dev_err(&this_usbduxsub->interface->dev,
1226 "comedi%d: usbdux_ao_inttrig: submitURB: "
1227 "err=%d\n", dev->minor, ret);
1228 this_usbduxsub->ao_cmd_running = 0;
1229 up(&this_usbduxsub->sem);
1232 s->async->inttrig = NULL;
1234 dev_err(&this_usbduxsub->interface->dev,
1235 "comedi%d: ao_inttrig but acqu is already running.\n",
1238 up(&this_usbduxsub->sem);
1242 static int usbdux_ao_cmdtest(struct comedi_device *dev,
1243 struct comedi_subdevice *s, struct comedi_cmd *cmd)
1245 struct usbdux_private *this_usbduxsub = dev->private;
1249 if (!this_usbduxsub)
1252 /* Step 1 : check if triggers are trivially valid */
1254 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
1256 if (0) { /* (this_usbduxsub->high_speed) */
1257 /* the sampling rate is set by the coversion rate */
1258 flags = TRIG_FOLLOW;
1260 /* start a new scan (output at once) with a timer */
1263 err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
1265 if (0) { /* (this_usbduxsub->high_speed) */
1267 * in usb-2.0 only one conversion it transmitted
1273 * all conversion events happen simultaneously with
1278 err |= cfc_check_trigger_src(&cmd->convert_src, flags);
1280 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1281 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1286 /* Step 2a : make sure trigger sources are unique */
1288 err |= cfc_check_trigger_is_unique(cmd->start_src);
1289 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1291 /* Step 2b : and mutually compatible */
1296 /* Step 3: check if arguments are trivially valid */
1298 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1300 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
1301 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1303 if (cmd->scan_begin_src == TRIG_TIMER)
1304 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1307 /* not used now, is for later use */
1308 if (cmd->convert_src == TRIG_TIMER)
1309 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
1311 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1313 if (cmd->stop_src == TRIG_COUNT) {
1314 /* any count is allowed */
1317 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1326 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1328 struct comedi_cmd *cmd = &s->async->cmd;
1329 unsigned int chan, gain;
1331 struct usbdux_private *this_usbduxsub = dev->private;
1333 if (!this_usbduxsub)
1336 down(&this_usbduxsub->sem);
1337 dev_dbg(&this_usbduxsub->interface->dev,
1338 "comedi%d: %s\n", dev->minor, __func__);
1340 /* set current channel of the running acquisition to zero */
1341 s->async->cur_chan = 0;
1342 for (i = 0; i < cmd->chanlist_len; ++i) {
1343 chan = CR_CHAN(cmd->chanlist[i]);
1344 gain = CR_RANGE(cmd->chanlist[i]);
1345 if (i >= NUMOUTCHANNELS) {
1346 dev_err(&this_usbduxsub->interface->dev,
1347 "comedi%d: %s: channel list too long\n",
1348 dev->minor, __func__);
1351 this_usbduxsub->dac_commands[i] = (chan << 6);
1352 dev_dbg(&this_usbduxsub->interface->dev,
1353 "comedi%d: dac command for ch %d is %x\n",
1354 dev->minor, i, this_usbduxsub->dac_commands[i]);
1357 /* we count in steps of 1ms (125us) */
1358 /* 125us mode not used yet */
1359 if (0) { /* (this_usbduxsub->high_speed) */
1361 /* timing of the conversion itself: every 125 us */
1362 this_usbduxsub->ao_timer = cmd->convert_arg / 125000;
1365 /* timing of the scan: we get all channels at once */
1366 this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000;
1367 dev_dbg(&this_usbduxsub->interface->dev,
1368 "comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
1369 "convert_src=%d, convert_arg=%d\n", dev->minor,
1370 cmd->scan_begin_src, cmd->scan_begin_arg,
1371 cmd->convert_src, cmd->convert_arg);
1372 dev_dbg(&this_usbduxsub->interface->dev,
1373 "comedi%d: ao_timer=%d (ms)\n",
1374 dev->minor, this_usbduxsub->ao_timer);
1375 if (this_usbduxsub->ao_timer < 1) {
1376 dev_err(&this_usbduxsub->interface->dev,
1377 "comedi%d: usbdux: ao_timer=%d, "
1378 "scan_begin_arg=%d. "
1379 "Not properly tested by cmdtest?\n",
1380 dev->minor, this_usbduxsub->ao_timer,
1381 cmd->scan_begin_arg);
1382 up(&this_usbduxsub->sem);
1386 this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
1388 if (cmd->stop_src == TRIG_COUNT) {
1389 /* not continuous */
1391 /* high speed also scans everything at once */
1392 if (0) { /* (this_usbduxsub->high_speed) */
1393 this_usbduxsub->ao_sample_count =
1394 (cmd->stop_arg) * (cmd->scan_end_arg);
1396 /* there's no scan as the scan has been */
1397 /* perf inside the FX2 */
1398 /* data arrives as one packet */
1399 this_usbduxsub->ao_sample_count = cmd->stop_arg;
1401 this_usbduxsub->ao_continous = 0;
1403 /* continous acquisition */
1404 this_usbduxsub->ao_continous = 1;
1405 this_usbduxsub->ao_sample_count = 0;
1408 if (cmd->start_src == TRIG_NOW) {
1409 /* enable this acquisition operation */
1410 this_usbduxsub->ao_cmd_running = 1;
1411 ret = usbduxsub_submit_outurbs(this_usbduxsub);
1413 this_usbduxsub->ao_cmd_running = 0;
1414 /* fixme: unlink here?? */
1415 up(&this_usbduxsub->sem);
1418 s->async->inttrig = NULL;
1421 /* submit the urbs later */
1422 /* wait for an internal signal */
1423 s->async->inttrig = usbdux_ao_inttrig;
1426 up(&this_usbduxsub->sem);
1430 static int usbdux_dio_insn_config(struct comedi_device *dev,
1431 struct comedi_subdevice *s,
1432 struct comedi_insn *insn, unsigned int *data)
1434 int chan = CR_CHAN(insn->chanspec);
1436 /* The input or output configuration of each digital line is
1437 * configured by a special insn_config instruction. chanspec
1438 * contains the channel to be changed, and data[0] contains the
1439 * value COMEDI_INPUT or COMEDI_OUTPUT. */
1442 case INSN_CONFIG_DIO_OUTPUT:
1443 s->io_bits |= 1 << chan; /* 1 means Out */
1445 case INSN_CONFIG_DIO_INPUT:
1446 s->io_bits &= ~(1 << chan);
1448 case INSN_CONFIG_DIO_QUERY:
1450 (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1456 /* we don't tell the firmware here as it would take 8 frames */
1457 /* to submit the information. We do it in the insn_bits. */
1461 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1462 struct comedi_subdevice *s,
1463 struct comedi_insn *insn, unsigned int *data)
1466 struct usbdux_private *this_usbduxsub = dev->private;
1469 if (!this_usbduxsub)
1472 down(&this_usbduxsub->sem);
1474 /* The insn data is a mask in data[0] and the new data
1475 * in data[1], each channel cooresponding to a bit. */
1476 s->state &= ~data[0];
1477 s->state |= data[0] & data[1];
1478 this_usbduxsub->dux_commands[1] = s->io_bits;
1479 this_usbduxsub->dux_commands[2] = s->state;
1481 /* This command also tells the firmware to return */
1482 /* the digital input lines */
1483 err = send_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1485 up(&this_usbduxsub->sem);
1488 err = receive_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1490 up(&this_usbduxsub->sem);
1494 data[1] = le16_to_cpu(this_usbduxsub->insn_buffer[1]);
1495 up(&this_usbduxsub->sem);
1499 /* reads the 4 counters, only two are used just now */
1500 static int usbdux_counter_read(struct comedi_device *dev,
1501 struct comedi_subdevice *s,
1502 struct comedi_insn *insn, unsigned int *data)
1504 struct usbdux_private *this_usbduxsub = dev->private;
1505 int chan = insn->chanspec;
1508 if (!this_usbduxsub)
1511 down(&this_usbduxsub->sem);
1512 err = send_dux_commands(this_usbduxsub, READCOUNTERCOMMAND);
1514 up(&this_usbduxsub->sem);
1518 err = receive_dux_commands(this_usbduxsub, READCOUNTERCOMMAND);
1520 up(&this_usbduxsub->sem);
1524 data[0] = le16_to_cpu(this_usbduxsub->insn_buffer[chan + 1]);
1525 up(&this_usbduxsub->sem);
1529 static int usbdux_counter_write(struct comedi_device *dev,
1530 struct comedi_subdevice *s,
1531 struct comedi_insn *insn, unsigned int *data)
1533 struct usbdux_private *this_usbduxsub = dev->private;
1536 if (!this_usbduxsub)
1539 down(&this_usbduxsub->sem);
1540 this_usbduxsub->dux_commands[1] = insn->chanspec;
1541 *((int16_t *) (this_usbduxsub->dux_commands + 2)) = cpu_to_le16(*data);
1543 err = send_dux_commands(this_usbduxsub, WRITECOUNTERCOMMAND);
1545 up(&this_usbduxsub->sem);
1549 up(&this_usbduxsub->sem);
1554 static int usbdux_counter_config(struct comedi_device *dev,
1555 struct comedi_subdevice *s,
1556 struct comedi_insn *insn, unsigned int *data)
1558 /* nothing to do so far */
1562 /***********************************/
1565 static int usbduxsub_unlink_pwm_urbs(struct usbdux_private *usbduxsub_tmp)
1569 if (usbduxsub_tmp && usbduxsub_tmp->urb_pwm) {
1570 if (usbduxsub_tmp->urb_pwm)
1571 usb_kill_urb(usbduxsub_tmp->urb_pwm);
1572 dev_dbg(&usbduxsub_tmp->interface->dev,
1573 "comedi: unlinked PwmURB: res=%d\n", err);
1578 /* This cancels a running acquisition operation
1581 static int usbdux_pwm_stop(struct usbdux_private *this_usbduxsub, int do_unlink)
1585 if (!this_usbduxsub)
1588 dev_dbg(&this_usbduxsub->interface->dev, "comedi: %s\n", __func__);
1590 ret = usbduxsub_unlink_pwm_urbs(this_usbduxsub);
1592 this_usbduxsub->pwm_cmd_running = 0;
1597 /* force unlink - is called by comedi */
1598 static int usbdux_pwm_cancel(struct comedi_device *dev,
1599 struct comedi_subdevice *s)
1601 struct usbdux_private *this_usbduxsub = dev->private;
1604 /* unlink only if it is really running */
1605 res = usbdux_pwm_stop(this_usbduxsub, this_usbduxsub->pwm_cmd_running);
1607 dev_dbg(&this_usbduxsub->interface->dev,
1608 "comedi %d: sending pwm off command to the usb device.\n",
1611 return send_dux_commands(this_usbduxsub, SENDPWMOFF);
1614 static void usbduxsub_pwm_irq(struct urb *urb)
1616 struct comedi_device *dev = urb->context;
1617 struct usbdux_private *devpriv = dev->private;
1620 switch (urb->status) {
1630 * after an unlink command, unplug, ... etc
1631 * no unlink needed here. Already shutting down.
1633 if (devpriv->pwm_cmd_running)
1634 usbdux_pwm_stop(devpriv, 0);
1640 if (devpriv->pwm_cmd_running) {
1641 dev_err(dev->class_dev,
1642 "Non-zero urb status received in pwm intr context: %d\n",
1644 usbdux_pwm_stop(devpriv, 0);
1649 /* are we actually running? */
1650 if (!devpriv->pwm_cmd_running)
1653 urb->transfer_buffer_length = devpriv->size_pwm_buf;
1654 urb->dev = devpriv->usbdev;
1656 if (devpriv->pwm_cmd_running) {
1657 ret = usb_submit_urb(urb, GFP_ATOMIC);
1659 dev_err(dev->class_dev,
1660 "pwm urb resubm failed in int-cont. ret=%d",
1662 if (ret == EL2NSYNC)
1663 dev_err(dev->class_dev,
1664 "buggy USB host controller or bug in IRQ handling!\n");
1666 /* don't do an unlink here */
1667 usbdux_pwm_stop(devpriv, 0);
1672 static int usbduxsub_submit_pwm_urbs(struct usbdux_private *usbduxsub)
1679 dev_dbg(&usbduxsub->interface->dev, "comedi_: submitting pwm-urb\n");
1681 /* in case of a resubmission after an unlink... */
1682 usb_fill_bulk_urb(usbduxsub->urb_pwm,
1684 usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP),
1685 usbduxsub->urb_pwm->transfer_buffer,
1686 usbduxsub->size_pwm_buf, usbduxsub_pwm_irq,
1687 usbduxsub->comedidev);
1689 err_flag = usb_submit_urb(usbduxsub->urb_pwm, GFP_ATOMIC);
1691 dev_err(&usbduxsub->interface->dev,
1692 "comedi_: usbdux: pwm: usb_submit_urb error %d\n",
1699 static int usbdux_pwm_period(struct comedi_device *dev,
1700 struct comedi_subdevice *s, unsigned int period)
1702 struct usbdux_private *this_usbduxsub = dev->private;
1705 if (period < MIN_PWM_PERIOD) {
1706 dev_err(&this_usbduxsub->interface->dev,
1707 "comedi%d: illegal period setting for pwm.\n",
1711 fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
1712 if (fx2delay > 255) {
1713 dev_err(&this_usbduxsub->interface->dev,
1714 "comedi%d: period %d for pwm is too low.\n",
1715 dev->minor, period);
1719 this_usbduxsub->pwn_delay = fx2delay;
1720 this_usbduxsub->pwm_period = period;
1721 dev_dbg(&this_usbduxsub->interface->dev, "%s: frequ=%d, period=%d\n",
1722 __func__, period, fx2delay);
1726 /* is called from insn so there's no need to do all the sanity checks */
1727 static int usbdux_pwm_start(struct comedi_device *dev,
1728 struct comedi_subdevice *s)
1731 struct usbdux_private *this_usbduxsub = dev->private;
1733 dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: %s\n",
1734 dev->minor, __func__);
1736 if (this_usbduxsub->pwm_cmd_running) {
1737 /* already running */
1741 this_usbduxsub->dux_commands[1] = ((int8_t) this_usbduxsub->pwn_delay);
1742 ret = send_dux_commands(this_usbduxsub, SENDPWMON);
1746 /* initialise the buffer */
1747 for (i = 0; i < this_usbduxsub->size_pwm_buf; i++)
1748 ((char *)(this_usbduxsub->urb_pwm->transfer_buffer))[i] = 0;
1750 this_usbduxsub->pwm_cmd_running = 1;
1751 ret = usbduxsub_submit_pwm_urbs(this_usbduxsub);
1753 this_usbduxsub->pwm_cmd_running = 0;
1759 /* generates the bit pattern for PWM with the optional sign bit */
1760 static int usbdux_pwm_pattern(struct comedi_device *dev,
1761 struct comedi_subdevice *s, int channel,
1762 unsigned int value, unsigned int sign)
1764 struct usbdux_private *this_usbduxsub = dev->private;
1771 if (!this_usbduxsub)
1774 /* this is the DIO bit which carries the PWM data */
1775 pwm_mask = (1 << channel);
1776 /* this is the DIO bit which carries the optional direction bit */
1777 sgn_mask = (16 << channel);
1778 /* this is the buffer which will be filled with the with bit */
1779 /* pattern for one period */
1780 szbuf = this_usbduxsub->size_pwm_buf;
1781 p_buf = (char *)(this_usbduxsub->urb_pwm->transfer_buffer);
1782 for (i = 0; i < szbuf; i++) {
1785 c = c & (~pwm_mask);
1786 /* set the bit as long as the index is lower than the value */
1789 /* set the optional sign bit for a relay */
1791 /* positive value */
1792 c = c & (~sgn_mask);
1794 /* negative value */
1802 static int usbdux_pwm_write(struct comedi_device *dev,
1803 struct comedi_subdevice *s,
1804 struct comedi_insn *insn, unsigned int *data)
1806 struct usbdux_private *this_usbduxsub = dev->private;
1808 if (!this_usbduxsub)
1811 if ((insn->n) != 1) {
1813 * doesn't make sense to have more than one value here because
1814 * it would just overwrite the PWM buffer a couple of times
1820 * the sign is set via a special INSN only, this gives us 8 bits for
1822 * relay sign 0 by default
1824 return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
1827 static int usbdux_pwm_read(struct comedi_device *x1,
1828 struct comedi_subdevice *x2, struct comedi_insn *x3,
1835 /* switches on/off PWM */
1836 static int usbdux_pwm_config(struct comedi_device *dev,
1837 struct comedi_subdevice *s,
1838 struct comedi_insn *insn, unsigned int *data)
1840 struct usbdux_private *this_usbduxsub = dev->private;
1842 case INSN_CONFIG_ARM:
1844 dev_dbg(&this_usbduxsub->interface->dev,
1845 "comedi%d: %s: pwm on\n", dev->minor, __func__);
1847 * if not zero the PWM is limited to a certain time which is
1848 * not supported here
1852 return usbdux_pwm_start(dev, s);
1853 case INSN_CONFIG_DISARM:
1854 dev_dbg(&this_usbduxsub->interface->dev,
1855 "comedi%d: %s: pwm off\n", dev->minor, __func__);
1856 return usbdux_pwm_cancel(dev, s);
1857 case INSN_CONFIG_GET_PWM_STATUS:
1859 * to check if the USB transmission has failed or in case PWM
1860 * was limited to n cycles to check if it has terminated
1862 data[1] = this_usbduxsub->pwm_cmd_running;
1864 case INSN_CONFIG_PWM_SET_PERIOD:
1865 dev_dbg(&this_usbduxsub->interface->dev,
1866 "comedi%d: %s: setting period\n", dev->minor, __func__);
1867 return usbdux_pwm_period(dev, s, data[1]);
1868 case INSN_CONFIG_PWM_GET_PERIOD:
1869 data[1] = this_usbduxsub->pwm_period;
1871 case INSN_CONFIG_PWM_SET_H_BRIDGE:
1872 /* value in the first byte and the sign in the second for a
1874 return usbdux_pwm_pattern(dev, s,
1875 /* the channel number */
1876 CR_CHAN(insn->chanspec),
1877 /* actual PWM data */
1881 case INSN_CONFIG_PWM_GET_H_BRIDGE:
1882 /* values are not kept in this driver, nothing to return here */
1889 /*****************************************************************/
1891 static int usbdux_alloc_usb_buffers(struct usbdux_private *devpriv)
1896 /* create space for the commands of the DA converter */
1897 devpriv->dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
1898 if (!devpriv->dac_commands)
1901 /* create space for the commands going to the usb device */
1902 devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1903 if (!devpriv->dux_commands)
1906 /* create space for the in buffer and set it to zero */
1907 devpriv->in_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1908 if (!devpriv->in_buffer)
1911 /* create space of the instruction buffer */
1912 devpriv->insn_buffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1913 if (!devpriv->insn_buffer)
1916 /* create space for the outbuffer */
1917 devpriv->out_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1918 if (!devpriv->out_buffer)
1922 devpriv->urb_in = kcalloc(devpriv->num_in_buffers, sizeof(*urb),
1924 if (!devpriv->urb_in)
1927 for (i = 0; i < devpriv->num_in_buffers; i++) {
1928 /* one frame: 1ms */
1929 urb = usb_alloc_urb(1, GFP_KERNEL);
1932 devpriv->urb_in[i] = urb;
1934 urb->dev = devpriv->usbdev;
1935 /* will be filled later with a pointer to the comedi-device */
1936 /* and ONLY then the urb should be submitted */
1937 urb->context = NULL;
1938 urb->pipe = usb_rcvisocpipe(devpriv->usbdev, ISOINEP);
1939 urb->transfer_flags = URB_ISO_ASAP;
1940 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1941 if (!urb->transfer_buffer)
1944 urb->complete = usbduxsub_ai_isoc_irq;
1945 urb->number_of_packets = 1;
1946 urb->transfer_buffer_length = SIZEINBUF;
1947 urb->iso_frame_desc[0].offset = 0;
1948 urb->iso_frame_desc[0].length = SIZEINBUF;
1952 devpriv->urb_out = kcalloc(devpriv->num_out_buffers, sizeof(*urb),
1954 if (!devpriv->urb_out)
1957 for (i = 0; i < devpriv->num_out_buffers; i++) {
1958 /* one frame: 1ms */
1959 urb = usb_alloc_urb(1, GFP_KERNEL);
1962 devpriv->urb_out[i] = urb;
1964 urb->dev = devpriv->usbdev;
1965 /* will be filled later with a pointer to the comedi-device */
1966 /* and ONLY then the urb should be submitted */
1967 urb->context = NULL;
1968 urb->pipe = usb_sndisocpipe(devpriv->usbdev, ISOOUTEP);
1969 urb->transfer_flags = URB_ISO_ASAP;
1970 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1971 if (!urb->transfer_buffer)
1974 urb->complete = usbduxsub_ao_isoc_irq;
1975 urb->number_of_packets = 1;
1976 urb->transfer_buffer_length = SIZEOUTBUF;
1977 urb->iso_frame_desc[0].offset = 0;
1978 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1979 if (devpriv->high_speed)
1980 urb->interval = 8; /* uframes */
1982 urb->interval = 1; /* frames */
1986 if (devpriv->size_pwm_buf) {
1987 urb = usb_alloc_urb(0, GFP_KERNEL);
1990 devpriv->urb_pwm = urb;
1992 /* max bulk ep size in high speed */
1993 urb->transfer_buffer = kzalloc(devpriv->size_pwm_buf,
1995 if (!urb->transfer_buffer)
2002 static void usbdux_free_usb_buffers(struct usbdux_private *devpriv)
2007 urb = devpriv->urb_pwm;
2009 kfree(urb->transfer_buffer);
2013 if (devpriv->urb_out) {
2014 for (i = 0; i < devpriv->num_out_buffers; i++) {
2015 urb = devpriv->urb_out[i];
2017 kfree(urb->transfer_buffer);
2022 kfree(devpriv->urb_out);
2024 if (devpriv->urb_in) {
2025 for (i = 0; i < devpriv->num_in_buffers; i++) {
2026 urb = devpriv->urb_in[i];
2028 kfree(urb->transfer_buffer);
2033 kfree(devpriv->urb_in);
2035 kfree(devpriv->out_buffer);
2036 kfree(devpriv->insn_buffer);
2037 kfree(devpriv->in_buffer);
2038 kfree(devpriv->dux_commands);
2039 kfree(devpriv->dac_commands);
2042 static int usbdux_auto_attach(struct comedi_device *dev,
2043 unsigned long context_unused)
2045 struct usb_interface *intf = comedi_to_usb_interface(dev);
2046 struct usb_device *usb = comedi_to_usb_dev(dev);
2047 struct usbdux_private *devpriv;
2048 struct comedi_subdevice *s;
2051 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
2055 sema_init(&devpriv->sem, 1);
2057 devpriv->comedidev = dev;
2058 devpriv->usbdev = usb;
2059 devpriv->interface = intf;
2060 devpriv->ifnum = intf->altsetting->desc.bInterfaceNumber;
2061 usb_set_intfdata(intf, devpriv);
2063 devpriv->high_speed = (devpriv->usbdev->speed == USB_SPEED_HIGH);
2064 if (devpriv->high_speed) {
2065 devpriv->num_in_buffers = NUMOFINBUFFERSHIGH;
2066 devpriv->num_out_buffers = NUMOFOUTBUFFERSHIGH;
2067 devpriv->size_pwm_buf = 512;
2069 devpriv->num_in_buffers = NUMOFINBUFFERSFULL;
2070 devpriv->num_out_buffers = NUMOFOUTBUFFERSFULL;
2073 ret = usbdux_alloc_usb_buffers(devpriv);
2077 /* setting to alternate setting 3: enabling iso ep and bulk ep. */
2078 ret = usb_set_interface(devpriv->usbdev, devpriv->ifnum, 3);
2080 dev_err(dev->class_dev,
2081 "could not set alternate setting 3 in high speed\n");
2085 ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
2086 usbdux_firmware_upload, 0);
2090 ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 5 : 4);
2094 /* Analog Input subdevice */
2095 s = &dev->subdevices[0];
2096 dev->read_subdev = s;
2097 s->type = COMEDI_SUBD_AI;
2098 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
2100 s->maxdata = 0x0fff;
2101 s->len_chanlist = 8;
2102 s->range_table = &range_usbdux_ai_range;
2103 s->insn_read = usbdux_ai_insn_read;
2104 s->do_cmdtest = usbdux_ai_cmdtest;
2105 s->do_cmd = usbdux_ai_cmd;
2106 s->cancel = usbdux_ai_cancel;
2108 /* Analog Output subdevice */
2109 s = &dev->subdevices[1];
2110 dev->write_subdev = s;
2111 s->type = COMEDI_SUBD_AO;
2112 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
2114 s->maxdata = 0x0fff;
2115 s->len_chanlist = 4;
2116 s->range_table = &range_usbdux_ao_range;
2117 s->do_cmdtest = usbdux_ao_cmdtest;
2118 s->do_cmd = usbdux_ao_cmd;
2119 s->cancel = usbdux_ao_cancel;
2120 s->insn_read = usbdux_ao_insn_read;
2121 s->insn_write = usbdux_ao_insn_write;
2123 /* Digital I/O subdevice */
2124 s = &dev->subdevices[2];
2125 s->type = COMEDI_SUBD_DIO;
2126 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
2129 s->range_table = &range_digital;
2130 s->insn_bits = usbdux_dio_insn_bits;
2131 s->insn_config = usbdux_dio_insn_config;
2133 /* Counter subdevice */
2134 s = &dev->subdevices[3];
2135 s->type = COMEDI_SUBD_COUNTER;
2136 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
2138 s->maxdata = 0xffff;
2139 s->insn_read = usbdux_counter_read;
2140 s->insn_write = usbdux_counter_write;
2141 s->insn_config = usbdux_counter_config;
2143 if (devpriv->high_speed) {
2145 s = &dev->subdevices[4];
2146 s->type = COMEDI_SUBD_PWM;
2147 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
2149 s->maxdata = devpriv->size_pwm_buf;
2150 s->insn_write = usbdux_pwm_write;
2151 s->insn_read = usbdux_pwm_read;
2152 s->insn_config = usbdux_pwm_config;
2154 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
2160 static void usbdux_detach(struct comedi_device *dev)
2162 struct usbdux_private *devpriv = dev->private;
2165 down(&devpriv->sem);
2167 usb_set_intfdata(devpriv->interface, NULL);
2169 if (devpriv->pwm_cmd_running)
2170 usbduxsub_unlink_pwm_urbs(devpriv);
2171 if (devpriv->ao_cmd_running)
2172 usbduxsub_unlink_outurbs(devpriv);
2173 if (devpriv->ai_cmd_running)
2174 usbduxsub_unlink_inurbs(devpriv);
2176 usbdux_free_usb_buffers(devpriv);
2178 devpriv->comedidev = NULL;
2184 static struct comedi_driver usbdux_driver = {
2185 .driver_name = "usbdux",
2186 .module = THIS_MODULE,
2187 .auto_attach = usbdux_auto_attach,
2188 .detach = usbdux_detach,
2191 static int usbdux_usb_probe(struct usb_interface *intf,
2192 const struct usb_device_id *id)
2194 return comedi_usb_auto_config(intf, &usbdux_driver, 0);
2197 static const struct usb_device_id usbdux_usb_table[] = {
2198 { USB_DEVICE(0x13d8, 0x0001) },
2199 { USB_DEVICE(0x13d8, 0x0002) },
2202 MODULE_DEVICE_TABLE(usb, usbdux_usb_table);
2204 static struct usb_driver usbdux_usb_driver = {
2206 .probe = usbdux_usb_probe,
2207 .disconnect = comedi_usb_auto_unconfig,
2208 .id_table = usbdux_usb_table,
2210 module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver);
2212 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
2213 MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com");
2214 MODULE_LICENSE("GPL");
2215 MODULE_FIRMWARE(FIRMWARE);