2 comedi/drivers/usbdux.c
3 Copyright (C) 2011 Bernd Porr, Bernd.Porr@f2s.com
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
17 Description: University of Stirling USB DAQ & INCITE Technology Limited
18 Devices: [ITL] USB-DUX (usbduxsigma.o)
19 Author: Bernd Porr <BerndPorr@f2s.com>
24 * I must give credit here to Chris Baugher who
25 * wrote the driver for AT-MIO-16d. I used some parts of this
26 * driver. I also must give credits to David Brownell
27 * who supported me with the USB development.
29 * Note: the raw data from the A/D converter is 24 bit big endian
30 * anything else is little endian to/from the dux board
34 * 0.1: initial version
35 * 0.2: all basic functions implemented, digital I/O only for one port
36 * 0.3: proper vendor ID and driver name
37 * 0.4: fixed D/A voltage range
38 * 0.5: various bug fixes, health check at startup
39 * 0.6: corrected wrong input range
42 #include <linux/kernel.h>
43 #include <linux/module.h>
44 #include <linux/init.h>
45 #include <linux/slab.h>
46 #include <linux/input.h>
47 #include <linux/usb.h>
48 #include <linux/fcntl.h>
49 #include <linux/compiler.h>
51 #include "comedi_fc.h"
52 #include "../comedidev.h"
54 /* timeout for the USB-transfer in ms*/
55 #define BULK_TIMEOUT 1000
57 /* constants for "firmware" upload and download */
58 #define FIRMWARE "usbduxsigma_firmware.bin"
59 #define USBDUXSUB_FIRMWARE 0xA0
60 #define VENDOR_DIR_IN 0xC0
61 #define VENDOR_DIR_OUT 0x40
63 /* internal addresses of the 8051 processor */
64 #define USBDUXSUB_CPUCS 0xE600
67 * the minor device number, major is 180 only for debugging purposes and to
68 * upload special firmware (programming the eeprom etc) which is not
69 * compatible with the comedi framwork
71 #define USBDUXSUB_MINOR 32
73 /* max lenghth of the transfer-buffer for software upload */
76 /* Input endpoint number: ISO/IRQ */
79 /* Output endpoint number: ISO/IRQ */
82 /* This EP sends DUX commands to USBDUX */
83 #define COMMAND_OUT_EP 1
85 /* This EP receives the DUX commands from USBDUX */
86 #define COMMAND_IN_EP 8
88 /* Output endpoint for PWM */
91 /* 300Hz max frequ under PWM */
92 #define MIN_PWM_PERIOD ((long)(1E9/300))
94 /* Default PWM frequency */
95 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
97 /* Number of channels (16 AD and offset)*/
98 #define NUMCHANNELS 16
100 /* Size of one A/D value */
101 #define SIZEADIN ((sizeof(int32_t)))
104 * Size of the async input-buffer IN BYTES, the DIO state is transmitted
107 #define SIZEINBUF (((NUMCHANNELS+1)*SIZEADIN))
110 #define SIZEINSNBUF 16
112 /* Number of DA channels */
113 #define NUMOUTCHANNELS 8
115 /* size of one value for the D/A converter: channel and value */
116 #define SIZEDAOUT ((sizeof(uint8_t)+sizeof(int16_t)))
119 * Size of the output-buffer in bytes
120 * Actually only the first 4 triplets are used but for the
121 * high speed mode we need to pad it to 8 (microframes).
123 #define SIZEOUTBUF ((8*SIZEDAOUT))
126 * Size of the buffer for the dux commands: just now max size is determined
127 * by the analogue out + command byte + panic bytes...
129 #define SIZEOFDUXBUFFER ((8*SIZEDAOUT+2))
131 /* Number of in-URBs which receive the data: min=2 */
132 #define NUMOFINBUFFERSFULL 5
134 /* Number of out-URBs which send the data: min=2 */
135 #define NUMOFOUTBUFFERSFULL 5
137 /* Number of in-URBs which receive the data: min=5 */
138 /* must have more buffers due to buggy USB ctr */
139 #define NUMOFINBUFFERSHIGH 10
141 /* Number of out-URBs which send the data: min=5 */
142 /* must have more buffers due to buggy USB ctr */
143 #define NUMOFOUTBUFFERSHIGH 10
145 /* Analogue in subdevice */
148 /* Analogue out subdevice */
154 /* timer aka pwm output */
157 /* number of retries to get the right dux command */
160 /**************************************************/
161 /* comedi constants */
162 static const struct comedi_lrange range_usbdux_ai_range = { 1, {
168 struct usbduxsigma_private {
169 /* pointer to the usb-device */
170 struct usb_device *usbdev;
171 /* actual number of in-buffers */
173 /* actual number of out-buffers */
175 /* ISO-transfer handling: buffers */
178 /* pwm-transfer handling */
181 unsigned int pwmPeriod;
182 /* PWM internal delay for the GPIF in the FX2 */
184 /* size of the PWM buffer which holds the bit pattern */
186 /* input buffer for the ISO-transfer */
188 /* input buffer for single insn */
190 /* output buffer for single DA outputs */
192 /* interface structure in 2.6 */
193 struct usb_interface *interface;
194 /* is it USB_SPEED_HIGH or not? */
195 short int high_speed;
196 /* asynchronous command is running */
197 short int ai_cmd_running;
198 short int ao_cmd_running;
200 short int pwm_cmd_running;
201 /* continuous acquisition */
202 short int ai_continuous;
203 short int ao_continuous;
204 /* number of samples to acquire */
207 /* time between samples in units of the timer */
208 unsigned int ai_timer;
209 unsigned int ao_timer;
210 /* counter between acquisitions */
211 unsigned int ai_counter;
212 unsigned int ao_counter;
213 /* interval in frames/uframes */
214 unsigned int ai_interval;
216 uint8_t *dac_commands;
218 uint8_t *dux_commands;
219 struct semaphore sem;
222 static void usbdux_ai_stop(struct usbduxsigma_private *devpriv, int do_unlink)
227 for (i = 0; i < devpriv->numOfInBuffers; i++) {
228 if (devpriv->urbIn[i])
229 usb_kill_urb(devpriv->urbIn[i]);
233 devpriv->ai_cmd_running = 0;
236 static int usbdux_ai_cancel(struct comedi_device *dev,
237 struct comedi_subdevice *s)
239 struct usbduxsigma_private *devpriv = dev->private;
242 /* unlink only if it is really running */
243 usbdux_ai_stop(devpriv, devpriv->ai_cmd_running);
249 static void usbduxsub_ai_IsocIrq(struct urb *urb)
251 struct comedi_device *dev = urb->context;
252 struct usbduxsigma_private *devpriv = dev->private;
253 struct comedi_subdevice *s = dev->read_subdev;
254 unsigned int dio_state;
259 /* first we test if something unusual has just happened */
260 switch (urb->status) {
262 /* copy the result in the transfer buffer */
263 memcpy(devpriv->inBuffer, urb->transfer_buffer, SIZEINBUF);
267 * error in the ISOchronous data
268 * we don't copy the data into the transfer buffer
269 * and recycle the last data byte
271 dev_dbg(dev->class_dev,"CRC error in ISO IN stream\n");
279 /* happens after an unlink command */
280 if (devpriv->ai_cmd_running) {
281 usbdux_ai_stop(devpriv, 0); /* w/o unlink */
282 /* we are still running a command, tell comedi */
283 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
284 comedi_event(dev, s);
290 * a real error on the bus
291 * pass error to comedi if we are really running a command
293 if (devpriv->ai_cmd_running) {
294 dev_err(dev->class_dev,
295 "%s: non-zero urb status (%d)\n",
296 __func__, urb->status);
297 usbdux_ai_stop(devpriv, 0); /* w/o unlink */
298 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
299 comedi_event(dev, s);
304 if (unlikely(!devpriv->ai_cmd_running))
307 urb->dev = devpriv->usbdev;
309 ret = usb_submit_urb(urb, GFP_ATOMIC);
310 if (unlikely(ret < 0)) {
311 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
313 if (ret == -EL2NSYNC)
314 dev_err(dev->class_dev,
315 "buggy USB host controller or bug in IRQ handler\n");
316 usbdux_ai_stop(devpriv, 0); /* w/o unlink */
317 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
318 comedi_event(dev, s);
322 /* get the state of the dio pins to allow external trigger */
323 dio_state = be32_to_cpu(devpriv->inBuffer[0]);
325 devpriv->ai_counter--;
326 if (likely(devpriv->ai_counter > 0))
329 /* timer zero, transfer measurements to comedi */
330 devpriv->ai_counter = devpriv->ai_timer;
332 if (!devpriv->ai_continuous) {
333 /* not continuous, fixed number of samples */
334 devpriv->ai_sample_count--;
335 if (devpriv->ai_sample_count < 0) {
336 usbdux_ai_stop(devpriv, 0); /* w/o unlink */
337 /* acquistion is over, tell comedi */
338 s->async->events |= COMEDI_CB_EOA;
339 comedi_event(dev, s);
344 /* get the data from the USB bus and hand it over to comedi */
345 for (i = 0; i < s->async->cmd.chanlist_len; i++) {
346 /* transfer data, note first byte is the DIO state */
347 val = be32_to_cpu(devpriv->inBuffer[i+1]);
348 val &= 0x00ffffff; /* strip status byte */
349 val ^= 0x00800000; /* convert to unsigned */
351 ret = cfc_write_array_to_buffer(s, &val, sizeof(uint32_t));
352 if (unlikely(ret == 0)) {
353 /* buffer overflow */
354 usbdux_ai_stop(devpriv, 0); /* w/o unlink */
358 /* tell comedi that data is there */
359 s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
360 comedi_event(dev, s);
363 static void usbdux_ao_stop(struct usbduxsigma_private *devpriv, int do_unlink)
368 for (i = 0; i < devpriv->numOfOutBuffers; i++) {
369 if (devpriv->urbOut[i])
370 usb_kill_urb(devpriv->urbOut[i]);
374 devpriv->ao_cmd_running = 0;
377 static int usbdux_ao_cancel(struct comedi_device *dev,
378 struct comedi_subdevice *s)
380 struct usbduxsigma_private *devpriv = dev->private;
383 /* unlink only if it is really running */
384 usbdux_ao_stop(devpriv, devpriv->ao_cmd_running);
390 static void usbduxsub_ao_IsocIrq(struct urb *urb)
392 struct comedi_device *dev = urb->context;
393 struct usbduxsigma_private *devpriv = dev->private;
394 struct comedi_subdevice *s = dev->write_subdev;
400 switch (urb->status) {
409 /* happens after an unlink command */
410 if (devpriv->ao_cmd_running) {
411 usbdux_ao_stop(devpriv, 0); /* w/o unlink */
412 s->async->events |= COMEDI_CB_EOA;
413 comedi_event(dev, s);
419 if (devpriv->ao_cmd_running) {
420 dev_err(dev->class_dev,
421 "%s: non-zero urb status (%d)\n",
422 __func__, urb->status);
423 usbdux_ao_stop(devpriv, 0); /* w/o unlink */
424 s->async->events |= (COMEDI_CB_ERROR | COMEDI_CB_EOA);
425 comedi_event(dev, s);
430 if (!devpriv->ao_cmd_running)
433 devpriv->ao_counter--;
434 if ((int)devpriv->ao_counter <= 0) {
435 /* timer zero, transfer from comedi */
436 devpriv->ao_counter = devpriv->ao_timer;
438 if (!devpriv->ao_continuous) {
439 /* not continuous, fixed number of samples */
440 devpriv->ao_sample_count--;
441 if (devpriv->ao_sample_count < 0) {
442 usbdux_ao_stop(devpriv, 0); /* w/o unlink */
443 /* acquistion is over, tell comedi */
444 s->async->events |= COMEDI_CB_EOA;
445 comedi_event(dev, s);
450 /* transmit data to the USB bus */
451 datap = urb->transfer_buffer;
452 len = s->async->cmd.chanlist_len;
454 for (i = 0; i < len; i++) {
457 if (i >= NUMOUTCHANNELS)
460 ret = comedi_buf_get(s->async, &val);
462 dev_err(dev->class_dev, "buffer underflow\n");
463 s->async->events |= (COMEDI_CB_EOA |
467 *datap++ = devpriv->dac_commands[i];
469 s->async->events |= COMEDI_CB_BLOCK;
470 comedi_event(dev, s);
474 urb->transfer_buffer_length = SIZEOUTBUF;
475 urb->dev = devpriv->usbdev;
477 if (devpriv->high_speed)
478 urb->interval = 8; /* uframes */
480 urb->interval = 1; /* frames */
481 urb->number_of_packets = 1;
482 urb->iso_frame_desc[0].offset = 0;
483 urb->iso_frame_desc[0].length = SIZEOUTBUF;
484 urb->iso_frame_desc[0].status = 0;
485 ret = usb_submit_urb(urb, GFP_ATOMIC);
487 dev_err(dev->class_dev,
488 "%s: urb resubmit failed (%d)\n",
491 dev_err(dev->class_dev,
492 "buggy USB host controller or bug in IRQ handler\n");
493 usbdux_ao_stop(devpriv, 0); /* w/o unlink */
494 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
495 comedi_event(dev, s);
499 /* the FX2LP has twice as much as the standard FX2 */
500 #define FIRMWARE_MAX_LEN 0x4000
502 static int usbduxsigma_firmware_upload(struct comedi_device *dev,
503 const u8 *data, size_t size,
504 unsigned long context)
506 struct usbduxsigma_private *usbduxsub = dev->private;
507 struct usb_device *usb = usbduxsub->usbdev;
515 if (size > FIRMWARE_MAX_LEN) {
516 dev_err(&usbduxsub->interface->dev,
517 "usbduxsigma firmware binary it too large for FX2.\n");
521 /* we generate a local buffer for the firmware */
522 buf = kmemdup(data, size, GFP_KERNEL);
524 dev_err(&usbduxsub->interface->dev,
525 "comedi_: mem alloc for firmware failed\n");
529 /* we need a malloc'ed buffer for usb_control_msg() */
530 tmp = kmalloc(1, GFP_KERNEL);
536 /* stop the current firmware on the device */
537 *tmp = 1; /* 7f92 to one */
538 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
541 USBDUXSUB_CPUCS, 0x0000,
545 dev_err(&usbduxsub->interface->dev,
546 "comedi_: can not stop firmware\n");
550 /* upload the new firmware to the device */
551 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
558 dev_err(&usbduxsub->interface->dev,
559 "comedi_: firmware upload failed\n");
563 /* start the new firmware on the device */
564 *tmp = 0; /* 7f92 to zero */
565 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
568 USBDUXSUB_CPUCS, 0x0000,
572 dev_err(&usbduxsub->interface->dev,
573 "comedi_: can not start firmware\n");
581 static int usbduxsigma_submit_urbs(struct comedi_device *dev,
582 struct urb **urbs, int num_urbs,
585 struct usbduxsigma_private *devpriv = dev->private;
590 /* Submit all URBs and start the transfer on the bus */
591 for (i = 0; i < num_urbs; i++) {
594 /* in case of a resubmission after an unlink... */
596 urb->interval = devpriv->ai_interval;
598 urb->dev = devpriv->usbdev;
600 urb->transfer_flags = URB_ISO_ASAP;
602 ret = usb_submit_urb(urb, GFP_ATOMIC);
609 static int chanToInterval(int nChannels)
621 static int usbdux_ai_cmdtest(struct comedi_device *dev,
622 struct comedi_subdevice *s,
623 struct comedi_cmd *cmd)
625 struct usbduxsigma_private *this_usbduxsub = dev->private;
627 unsigned int tmpTimer;
629 /* Step 1 : check if triggers are trivially valid */
631 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
632 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
633 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
634 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
635 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
640 /* Step 2a : make sure trigger sources are unique */
642 err |= cfc_check_trigger_is_unique(cmd->start_src);
643 err |= cfc_check_trigger_is_unique(cmd->stop_src);
645 /* Step 2b : and mutually compatible */
650 /* Step 3: check if arguments are trivially valid */
652 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
654 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
655 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
657 if (cmd->scan_begin_src == TRIG_TIMER) {
658 if (this_usbduxsub->high_speed) {
660 * In high speed mode microframes are possible.
661 * However, during one microframe we can roughly
662 * sample two channels. Thus, the more channels
663 * are in the channel list the more time we need.
665 i = chanToInterval(cmd->chanlist_len);
666 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
668 /* now calc the real sampling rate with all the
671 ((unsigned int)(cmd->scan_begin_arg / 125000)) *
675 /* 1kHz scans every USB frame */
676 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
679 * calc the real sampling rate with the rounding errors
681 tmpTimer = ((unsigned int)(cmd->scan_begin_arg /
684 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
688 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
690 if (cmd->stop_src == TRIG_COUNT) {
691 /* any count is allowed */
694 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
704 * creates the ADC command for the MAX1271
705 * range is the range value from comedi
707 static void create_adc_command(unsigned int chan,
712 (*muxsg0) = (*muxsg0) | (1 << chan);
714 (*muxsg1) = (*muxsg1) | (1 << (chan-8));
718 /* bulk transfers to usbdux */
720 #define SENDADCOMMANDS 0
721 #define SENDDACOMMANDS 1
722 #define SENDDIOCONFIGCOMMAND 2
723 #define SENDDIOBITSCOMMAND 3
724 #define SENDSINGLEAD 4
728 static int send_dux_commands(struct usbduxsigma_private *devpriv,
733 devpriv->dux_commands[0] = cmd_type;
735 return usb_bulk_msg(devpriv->usbdev,
736 usb_sndbulkpipe(devpriv->usbdev, COMMAND_OUT_EP),
737 devpriv->dux_commands, SIZEOFDUXBUFFER,
738 &nsent, BULK_TIMEOUT);
741 static int receive_dux_commands(struct usbduxsigma_private *devpriv,
748 for (i = 0; i < RETRIES; i++) {
749 ret = usb_bulk_msg(devpriv->usbdev,
750 usb_rcvbulkpipe(devpriv->usbdev,
752 devpriv->insnBuffer, SIZEINSNBUF,
753 &nrec, BULK_TIMEOUT);
757 if (devpriv->insnBuffer[0] == command)
761 * This is only reached if the data has been requested a
762 * couple of times and the command was not received.
767 static int usbdux_ai_inttrig(struct comedi_device *dev,
768 struct comedi_subdevice *s, unsigned int trignum)
770 struct usbduxsigma_private *this_usbduxsub = dev->private;
775 down(&this_usbduxsub->sem);
777 dev_err(&this_usbduxsub->interface->dev,
778 "comedi%d: usbdux_ai_inttrig: invalid trignum\n",
780 up(&this_usbduxsub->sem);
783 if (!this_usbduxsub->ai_cmd_running) {
784 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbIn,
785 this_usbduxsub->numOfInBuffers,
788 up(&this_usbduxsub->sem);
791 this_usbduxsub->ai_cmd_running = 1;
792 s->async->inttrig = NULL;
794 dev_err(&this_usbduxsub->interface->dev,
795 "comedi%d: ai_inttrig but acqu is already running\n",
798 up(&this_usbduxsub->sem);
802 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
804 struct usbduxsigma_private *this_usbduxsub = dev->private;
805 struct comedi_cmd *cmd = &s->async->cmd;
816 /* block other CPUs from starting an ai_cmd */
817 down(&this_usbduxsub->sem);
818 if (this_usbduxsub->ai_cmd_running) {
819 dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
820 "ai_cmd not possible. Another ai_cmd is running.\n",
822 up(&this_usbduxsub->sem);
825 /* set current channel of the running acquisition to zero */
826 s->async->cur_chan = 0;
828 /* first the number of channels per time step */
829 this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
832 this_usbduxsub->dux_commands[2] = 0x12;
834 /* CONFIG1: 23kHz sampling rate, delay = 0us, */
835 this_usbduxsub->dux_commands[3] = 0x03;
837 /* CONFIG3: differential channels off */
838 this_usbduxsub->dux_commands[4] = 0x00;
840 for (i = 0; i < cmd->chanlist_len; i++) {
841 chan = CR_CHAN(cmd->chanlist[i]);
842 create_adc_command(chan, &muxsg0, &muxsg1);
843 if (i >= NUMCHANNELS) {
844 dev_err(&this_usbduxsub->interface->dev,
845 "comedi%d: channel list too long\n",
850 this_usbduxsub->dux_commands[5] = muxsg0;
851 this_usbduxsub->dux_commands[6] = muxsg1;
852 this_usbduxsub->dux_commands[7] = sysred;
854 result = send_dux_commands(this_usbduxsub, SENDADCOMMANDS);
856 up(&this_usbduxsub->sem);
860 if (this_usbduxsub->high_speed) {
862 * every 2 channels get a time window of 125us. Thus, if we
863 * sample all 16 channels we need 1ms. If we sample only one
864 * channel we need only 125us
866 this_usbduxsub->ai_interval =
867 chanToInterval(cmd->chanlist_len);
868 this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
872 /* interval always 1ms */
873 this_usbduxsub->ai_interval = 1;
874 this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000;
876 if (this_usbduxsub->ai_timer < 1) {
877 dev_err(&this_usbduxsub->interface->dev, "comedi%d: ai_cmd: "
878 "timer=%d, scan_begin_arg=%d. "
879 "Not properly tested by cmdtest?\n", dev->minor,
880 this_usbduxsub->ai_timer, cmd->scan_begin_arg);
881 up(&this_usbduxsub->sem);
884 this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
886 if (cmd->stop_src == TRIG_COUNT) {
887 /* data arrives as one packet */
888 this_usbduxsub->ai_sample_count = cmd->stop_arg;
889 this_usbduxsub->ai_continuous = 0;
891 /* continuous acquisition */
892 this_usbduxsub->ai_continuous = 1;
893 this_usbduxsub->ai_sample_count = 0;
896 if (cmd->start_src == TRIG_NOW) {
897 /* enable this acquisition operation */
898 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbIn,
899 this_usbduxsub->numOfInBuffers,
902 up(&this_usbduxsub->sem);
905 this_usbduxsub->ai_cmd_running = 1;
906 s->async->inttrig = NULL;
909 /* don't enable the acquision operation */
910 /* wait for an internal signal */
911 s->async->inttrig = usbdux_ai_inttrig;
913 up(&this_usbduxsub->sem);
917 /* Mode 0 is used to get a single conversion on demand */
918 static int usbdux_ai_insn_read(struct comedi_device *dev,
919 struct comedi_subdevice *s,
920 struct comedi_insn *insn, unsigned int *data)
922 struct usbduxsigma_private *this_usbduxsub = dev->private;
934 down(&this_usbduxsub->sem);
935 if (this_usbduxsub->ai_cmd_running) {
936 dev_err(&this_usbduxsub->interface->dev,
937 "comedi%d: ai_insn_read not possible. "
938 "Async Command is running.\n", dev->minor);
939 up(&this_usbduxsub->sem);
943 /* sample one channel */
944 /* CONFIG0: chopper on */
945 this_usbduxsub->dux_commands[1] = 0x16;
947 /* CONFIG1: 2kHz sampling rate */
948 this_usbduxsub->dux_commands[2] = 0x80;
950 /* CONFIG3: differential channels off */
951 this_usbduxsub->dux_commands[3] = 0x00;
953 chan = CR_CHAN(insn->chanspec);
954 create_adc_command(chan, &muxsg0, &muxsg1);
956 this_usbduxsub->dux_commands[4] = muxsg0;
957 this_usbduxsub->dux_commands[5] = muxsg1;
958 this_usbduxsub->dux_commands[6] = sysred;
961 err = send_dux_commands(this_usbduxsub, SENDSINGLEAD);
963 up(&this_usbduxsub->sem);
967 for (i = 0; i < insn->n; i++) {
968 err = receive_dux_commands(this_usbduxsub, SENDSINGLEAD);
970 up(&this_usbduxsub->sem);
973 /* 32 bits big endian from the A/D converter */
974 one = be32_to_cpu(*((int32_t *)
975 ((this_usbduxsub->insnBuffer)+1)));
976 /* mask out the status byte */
977 one = one & 0x00ffffff;
978 /* turn it into an unsigned integer */
979 one = one ^ 0x00800000;
982 up(&this_usbduxsub->sem);
989 static int usbdux_getstatusinfo(struct comedi_device *dev, int chan)
991 struct usbduxsigma_private *this_usbduxsub = dev->private;
999 if (this_usbduxsub->ai_cmd_running) {
1000 dev_err(&this_usbduxsub->interface->dev,
1001 "comedi%d: status read not possible. "
1002 "Async Command is running.\n", dev->minor);
1007 this_usbduxsub->dux_commands[1] = 0x12;
1009 /* CONFIG1: 2kHz sampling rate */
1010 this_usbduxsub->dux_commands[2] = 0x80;
1012 /* CONFIG3: differential channels off */
1013 this_usbduxsub->dux_commands[3] = 0x00;
1017 sysred = sysred | 1;
1018 } else if (chan == 2) {
1020 sysred = sysred | 4;
1021 } else if (chan == 3) {
1023 sysred = sysred | 8;
1024 } else if (chan == 4) {
1026 sysred = sysred | 16;
1027 } else if (chan == 5) {
1029 sysred = sysred | 32;
1032 this_usbduxsub->dux_commands[4] = 0;
1033 this_usbduxsub->dux_commands[5] = 0;
1034 this_usbduxsub->dux_commands[6] = sysred;
1037 err = send_dux_commands(this_usbduxsub, SENDSINGLEAD);
1041 err = receive_dux_commands(this_usbduxsub, SENDSINGLEAD);
1045 /* 32 bits big endian from the A/D converter */
1046 one = be32_to_cpu(*((int32_t *)((this_usbduxsub->insnBuffer)+1)));
1047 /* mask out the status byte */
1048 one = one & 0x00ffffff;
1049 one = one ^ 0x00800000;
1059 /************************************/
1062 static int usbdux_ao_insn_read(struct comedi_device *dev,
1063 struct comedi_subdevice *s,
1064 struct comedi_insn *insn, unsigned int *data)
1066 struct usbduxsigma_private *this_usbduxsub = dev->private;
1068 int chan = CR_CHAN(insn->chanspec);
1070 if (!this_usbduxsub)
1073 down(&this_usbduxsub->sem);
1074 for (i = 0; i < insn->n; i++)
1075 data[i] = this_usbduxsub->outBuffer[chan];
1077 up(&this_usbduxsub->sem);
1081 static int usbdux_ao_insn_write(struct comedi_device *dev,
1082 struct comedi_subdevice *s,
1083 struct comedi_insn *insn, unsigned int *data)
1085 struct usbduxsigma_private *this_usbduxsub = dev->private;
1087 int chan = CR_CHAN(insn->chanspec);
1089 if (!this_usbduxsub)
1092 down(&this_usbduxsub->sem);
1093 if (this_usbduxsub->ao_cmd_running) {
1094 dev_err(&this_usbduxsub->interface->dev,
1095 "comedi%d: ao_insn_write: "
1096 "ERROR: asynchronous ao_cmd is running\n", dev->minor);
1097 up(&this_usbduxsub->sem);
1101 for (i = 0; i < insn->n; i++) {
1102 dev_dbg(&this_usbduxsub->interface->dev,
1103 "comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n",
1104 dev->minor, chan, i, data[i]);
1106 /* number of channels: 1 */
1107 this_usbduxsub->dux_commands[1] = 1;
1108 /* channel number */
1109 this_usbduxsub->dux_commands[2] = data[i];
1110 this_usbduxsub->outBuffer[chan] = data[i];
1111 this_usbduxsub->dux_commands[3] = chan;
1112 err = send_dux_commands(this_usbduxsub, SENDDACOMMANDS);
1114 up(&this_usbduxsub->sem);
1118 up(&this_usbduxsub->sem);
1123 static int usbdux_ao_inttrig(struct comedi_device *dev,
1124 struct comedi_subdevice *s, unsigned int trignum)
1126 struct usbduxsigma_private *this_usbduxsub = dev->private;
1129 if (!this_usbduxsub)
1132 down(&this_usbduxsub->sem);
1134 dev_err(&this_usbduxsub->interface->dev,
1135 "comedi%d: usbdux_ao_inttrig: invalid trignum\n",
1140 if (!(this_usbduxsub->ao_cmd_running)) {
1141 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbOut,
1142 this_usbduxsub->numOfOutBuffers,
1146 this_usbduxsub->ao_cmd_running = 1;
1147 s->async->inttrig = NULL;
1149 dev_err(&this_usbduxsub->interface->dev,
1150 "comedi%d: ao_inttrig but acqu is already running.\n",
1155 up(&this_usbduxsub->sem);
1159 static int usbdux_ao_cmdtest(struct comedi_device *dev,
1160 struct comedi_subdevice *s,
1161 struct comedi_cmd *cmd)
1163 struct usbduxsigma_private *this_usbduxsub = dev->private;
1167 if (!this_usbduxsub)
1170 /* Step 1 : check if triggers are trivially valid */
1172 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
1174 if (0) { /* (this_usbduxsub->high_speed) */
1176 * start immediately a new scan
1177 * the sampling rate is set by the coversion rate
1179 flags = TRIG_FOLLOW;
1181 /* start a new scan (output at once) with a timer */
1184 err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
1186 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1187 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1188 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1193 /* Step 2a : make sure trigger sources are unique */
1195 err |= cfc_check_trigger_is_unique(cmd->start_src);
1196 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1198 /* Step 2b : and mutually compatible */
1203 /* Step 3: check if arguments are trivially valid */
1205 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1207 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
1208 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1210 if (cmd->scan_begin_src == TRIG_TIMER)
1211 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1214 /* not used now, is for later use */
1215 if (cmd->convert_src == TRIG_TIMER)
1216 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
1218 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1220 if (cmd->stop_src == TRIG_COUNT) {
1221 /* any count is allowed */
1224 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1233 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1235 struct usbduxsigma_private *this_usbduxsub = dev->private;
1236 struct comedi_cmd *cmd = &s->async->cmd;
1237 unsigned int chan, gain;
1240 if (!this_usbduxsub)
1243 down(&this_usbduxsub->sem);
1244 /* set current channel of the running acquisition to zero */
1245 s->async->cur_chan = 0;
1246 for (i = 0; i < cmd->chanlist_len; ++i) {
1247 chan = CR_CHAN(cmd->chanlist[i]);
1248 gain = CR_RANGE(cmd->chanlist[i]);
1249 if (i >= NUMOUTCHANNELS) {
1250 dev_err(&this_usbduxsub->interface->dev,
1251 "comedi%d: %s: channel list too long\n",
1252 dev->minor, __func__);
1255 this_usbduxsub->dac_commands[i] = chan;
1256 dev_dbg(&this_usbduxsub->interface->dev,
1257 "comedi%d: dac command for ch %d is %x\n",
1258 dev->minor, i, this_usbduxsub->dac_commands[i]);
1261 /* we count in steps of 1ms (125us) */
1262 /* 125us mode not used yet */
1263 if (0) { /* (this_usbduxsub->high_speed) */
1265 /* timing of the conversion itself: every 125 us */
1266 this_usbduxsub->ao_timer = cmd->convert_arg / 125000;
1269 /* timing of the scan: we get all channels at once */
1270 this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000;
1271 dev_dbg(&this_usbduxsub->interface->dev,
1272 "comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
1273 "convert_src=%d, convert_arg=%d\n", dev->minor,
1274 cmd->scan_begin_src, cmd->scan_begin_arg,
1275 cmd->convert_src, cmd->convert_arg);
1276 dev_dbg(&this_usbduxsub->interface->dev,
1277 "comedi%d: ao_timer=%d (ms)\n",
1278 dev->minor, this_usbduxsub->ao_timer);
1279 if (this_usbduxsub->ao_timer < 1) {
1280 dev_err(&this_usbduxsub->interface->dev,
1281 "comedi%d: usbdux: ao_timer=%d, "
1282 "scan_begin_arg=%d. "
1283 "Not properly tested by cmdtest?\n",
1284 dev->minor, this_usbduxsub->ao_timer,
1285 cmd->scan_begin_arg);
1286 up(&this_usbduxsub->sem);
1290 this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
1292 if (cmd->stop_src == TRIG_COUNT) {
1293 /* not continuous */
1295 /* high speed also scans everything at once */
1296 if (0) { /* (this_usbduxsub->high_speed) */
1297 this_usbduxsub->ao_sample_count =
1298 (cmd->stop_arg) * (cmd->scan_end_arg);
1300 /* there's no scan as the scan has been */
1301 /* perf inside the FX2 */
1302 /* data arrives as one packet */
1303 this_usbduxsub->ao_sample_count = cmd->stop_arg;
1305 this_usbduxsub->ao_continuous = 0;
1307 /* continuous acquisition */
1308 this_usbduxsub->ao_continuous = 1;
1309 this_usbduxsub->ao_sample_count = 0;
1312 if (cmd->start_src == TRIG_NOW) {
1313 /* enable this acquisition operation */
1314 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbOut,
1315 this_usbduxsub->numOfOutBuffers,
1318 up(&this_usbduxsub->sem);
1321 this_usbduxsub->ao_cmd_running = 1;
1322 s->async->inttrig = NULL;
1325 /* submit the urbs later */
1326 /* wait for an internal signal */
1327 s->async->inttrig = usbdux_ao_inttrig;
1330 up(&this_usbduxsub->sem);
1334 static int usbdux_dio_insn_config(struct comedi_device *dev,
1335 struct comedi_subdevice *s,
1336 struct comedi_insn *insn, unsigned int *data)
1338 int chan = CR_CHAN(insn->chanspec);
1340 /* The input or output configuration of each digital line is
1341 * configured by a special insn_config instruction. chanspec
1342 * contains the channel to be changed, and data[0] contains the
1343 * value COMEDI_INPUT or COMEDI_OUTPUT. */
1346 case INSN_CONFIG_DIO_OUTPUT:
1347 s->io_bits |= 1 << chan; /* 1 means Out */
1349 case INSN_CONFIG_DIO_INPUT:
1350 s->io_bits &= ~(1 << chan);
1352 case INSN_CONFIG_DIO_QUERY:
1354 (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1360 /* we don't tell the firmware here as it would take 8 frames */
1361 /* to submit the information. We do it in the insn_bits. */
1365 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1366 struct comedi_subdevice *s,
1367 struct comedi_insn *insn,
1370 struct usbduxsigma_private *this_usbduxsub = dev->private;
1373 if (!this_usbduxsub)
1376 down(&this_usbduxsub->sem);
1378 /* The insn data is a mask in data[0] and the new data
1379 * in data[1], each channel cooresponding to a bit. */
1380 s->state &= ~data[0];
1381 s->state |= data[0] & data[1];
1382 /* The commands are 8 bits wide */
1383 this_usbduxsub->dux_commands[1] = (s->io_bits) & 0x000000FF;
1384 this_usbduxsub->dux_commands[4] = (s->state) & 0x000000FF;
1385 this_usbduxsub->dux_commands[2] = ((s->io_bits) & 0x0000FF00) >> 8;
1386 this_usbduxsub->dux_commands[5] = ((s->state) & 0x0000FF00) >> 8;
1387 this_usbduxsub->dux_commands[3] = ((s->io_bits) & 0x00FF0000) >> 16;
1388 this_usbduxsub->dux_commands[6] = ((s->state) & 0x00FF0000) >> 16;
1390 /* This command also tells the firmware to return */
1391 /* the digital input lines */
1392 err = send_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1394 up(&this_usbduxsub->sem);
1397 err = receive_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1399 up(&this_usbduxsub->sem);
1403 data[1] = (((unsigned int)(this_usbduxsub->insnBuffer[1]))&0xff) |
1404 ((((unsigned int)(this_usbduxsub->insnBuffer[2]))&0xff) << 8) |
1405 ((((unsigned int)(this_usbduxsub->insnBuffer[3]))&0xff) << 16);
1409 up(&this_usbduxsub->sem);
1413 static void usbdux_pwm_stop(struct usbduxsigma_private *devpriv, int do_unlink)
1416 if (devpriv->urbPwm)
1417 usb_kill_urb(devpriv->urbPwm);
1420 devpriv->pwm_cmd_running = 0;
1423 static int usbdux_pwm_cancel(struct comedi_device *dev,
1424 struct comedi_subdevice *s)
1426 struct usbduxsigma_private *devpriv = dev->private;
1428 /* unlink only if it is really running */
1429 usbdux_pwm_stop(devpriv, devpriv->pwm_cmd_running);
1431 return send_dux_commands(devpriv, SENDPWMOFF);
1434 static void usbduxsub_pwm_irq(struct urb *urb)
1436 struct comedi_device *dev = urb->context;
1437 struct usbduxsigma_private *devpriv = dev->private;
1440 switch (urb->status) {
1449 /* happens after an unlink command */
1450 if (devpriv->pwm_cmd_running)
1451 usbdux_pwm_stop(devpriv, 0); /* w/o unlink */
1456 if (devpriv->pwm_cmd_running) {
1457 dev_err(dev->class_dev,
1458 "%s: non-zero urb status (%d)\n",
1459 __func__, urb->status);
1460 usbdux_pwm_stop(devpriv, 0); /* w/o unlink */
1465 if (!devpriv->pwm_cmd_running)
1468 urb->transfer_buffer_length = devpriv->sizePwmBuf;
1469 urb->dev = devpriv->usbdev;
1471 ret = usb_submit_urb(urb, GFP_ATOMIC);
1473 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
1475 if (ret == EL2NSYNC)
1476 dev_err(dev->class_dev,
1477 "buggy USB host controller or bug in IRQ handler\n");
1478 usbdux_pwm_stop(devpriv, 0); /* w/o unlink */
1482 static int usbduxsigma_submit_pwm_urb(struct comedi_device *dev)
1484 struct usb_device *usb = comedi_to_usb_dev(dev);
1485 struct usbduxsigma_private *devpriv = dev->private;
1486 struct urb *urb = devpriv->urbPwm;
1488 /* in case of a resubmission after an unlink... */
1489 usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, PWM_EP),
1490 urb->transfer_buffer, devpriv->sizePwmBuf,
1491 usbduxsub_pwm_irq, dev);
1493 return usb_submit_urb(urb, GFP_ATOMIC);
1496 static int usbdux_pwm_period(struct comedi_device *dev,
1497 struct comedi_subdevice *s, unsigned int period)
1499 struct usbduxsigma_private *this_usbduxsub = dev->private;
1502 if (period < MIN_PWM_PERIOD) {
1503 dev_err(&this_usbduxsub->interface->dev,
1504 "comedi%d: illegal period setting for pwm.\n",
1508 fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
1509 if (fx2delay > 255) {
1510 dev_err(&this_usbduxsub->interface->dev,
1511 "comedi%d: period %d for pwm is too low.\n",
1512 dev->minor, period);
1516 this_usbduxsub->pwmDelay = fx2delay;
1517 this_usbduxsub->pwmPeriod = period;
1521 /* is called from insn so there's no need to do all the sanity checks */
1522 static int usbdux_pwm_start(struct comedi_device *dev,
1523 struct comedi_subdevice *s)
1525 struct usbduxsigma_private *this_usbduxsub = dev->private;
1528 if (this_usbduxsub->pwm_cmd_running) {
1529 /* already running */
1533 this_usbduxsub->dux_commands[1] = ((uint8_t) this_usbduxsub->pwmDelay);
1534 ret = send_dux_commands(this_usbduxsub, SENDPWMON);
1538 /* initialise the buffer */
1539 for (i = 0; i < this_usbduxsub->sizePwmBuf; i++)
1540 ((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0;
1542 ret = usbduxsigma_submit_pwm_urb(dev);
1545 this_usbduxsub->pwm_cmd_running = 1;
1550 /* generates the bit pattern for PWM with the optional sign bit */
1551 static int usbdux_pwm_pattern(struct comedi_device *dev,
1552 struct comedi_subdevice *s, int channel,
1553 unsigned int value, unsigned int sign)
1555 struct usbduxsigma_private *this_usbduxsub = dev->private;
1562 if (!this_usbduxsub)
1565 /* this is the DIO bit which carries the PWM data */
1566 pwm_mask = (1 << channel);
1567 /* this is the DIO bit which carries the optional direction bit */
1568 sgn_mask = (16 << channel);
1569 /* this is the buffer which will be filled with the with bit */
1570 /* pattern for one period */
1571 szbuf = this_usbduxsub->sizePwmBuf;
1572 pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer);
1573 for (i = 0; i < szbuf; i++) {
1576 c = c & (~pwm_mask);
1577 /* set the bit as long as the index is lower than the value */
1580 /* set the optional sign bit for a relay */
1582 /* positive value */
1583 c = c & (~sgn_mask);
1585 /* negative value */
1593 static int usbdux_pwm_write(struct comedi_device *dev,
1594 struct comedi_subdevice *s,
1595 struct comedi_insn *insn, unsigned int *data)
1597 struct usbduxsigma_private *this_usbduxsub = dev->private;
1599 if (!this_usbduxsub)
1602 if ((insn->n) != 1) {
1604 * doesn't make sense to have more than one value here because
1605 * it would just overwrite the PWM buffer a couple of times
1611 * the sign is set via a special INSN only, this gives us 8 bits for
1613 * relay sign 0 by default
1615 return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
1618 static int usbdux_pwm_read(struct comedi_device *x1,
1619 struct comedi_subdevice *x2, struct comedi_insn *x3,
1626 /* switches on/off PWM */
1627 static int usbdux_pwm_config(struct comedi_device *dev,
1628 struct comedi_subdevice *s,
1629 struct comedi_insn *insn, unsigned int *data)
1631 struct usbduxsigma_private *this_usbduxsub = dev->private;
1633 case INSN_CONFIG_ARM:
1636 * if not zero the PWM is limited to a certain time which is
1637 * not supported here
1641 return usbdux_pwm_start(dev, s);
1642 case INSN_CONFIG_DISARM:
1643 return usbdux_pwm_cancel(dev, s);
1644 case INSN_CONFIG_GET_PWM_STATUS:
1646 * to check if the USB transmission has failed or in case PWM
1647 * was limited to n cycles to check if it has terminated
1649 data[1] = this_usbduxsub->pwm_cmd_running;
1651 case INSN_CONFIG_PWM_SET_PERIOD:
1652 return usbdux_pwm_period(dev, s, data[1]);
1653 case INSN_CONFIG_PWM_GET_PERIOD:
1654 data[1] = this_usbduxsub->pwmPeriod;
1656 case INSN_CONFIG_PWM_SET_H_BRIDGE:
1657 /* value in the first byte and the sign in the second for a
1659 return usbdux_pwm_pattern(dev, s,
1660 /* the channel number */
1661 CR_CHAN(insn->chanspec),
1662 /* actual PWM data */
1666 case INSN_CONFIG_PWM_GET_H_BRIDGE:
1667 /* values are not kept in this driver, nothing to return */
1674 /*****************************************************************/
1676 static void tidy_up(struct usbduxsigma_private *usbduxsub_tmp)
1683 /* shows the usb subsystem that the driver is down */
1684 if (usbduxsub_tmp->interface)
1685 usb_set_intfdata(usbduxsub_tmp->interface, NULL);
1687 if (usbduxsub_tmp->urbIn) {
1688 /* force unlink all urbs */
1689 usbdux_ai_stop(usbduxsub_tmp, 1);
1690 for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
1691 kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer);
1692 usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL;
1693 usb_free_urb(usbduxsub_tmp->urbIn[i]);
1694 usbduxsub_tmp->urbIn[i] = NULL;
1696 kfree(usbduxsub_tmp->urbIn);
1697 usbduxsub_tmp->urbIn = NULL;
1699 if (usbduxsub_tmp->urbOut) {
1700 /* force unlink all urbs */
1701 usbdux_ao_stop(usbduxsub_tmp, 1);
1702 for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
1703 if (usbduxsub_tmp->urbOut[i]->transfer_buffer) {
1704 kfree(usbduxsub_tmp->
1705 urbOut[i]->transfer_buffer);
1706 usbduxsub_tmp->urbOut[i]->transfer_buffer =
1709 if (usbduxsub_tmp->urbOut[i]) {
1710 usb_free_urb(usbduxsub_tmp->urbOut[i]);
1711 usbduxsub_tmp->urbOut[i] = NULL;
1714 kfree(usbduxsub_tmp->urbOut);
1715 usbduxsub_tmp->urbOut = NULL;
1717 if (usbduxsub_tmp->urbPwm) {
1718 /* force unlink urb */
1719 usbdux_pwm_stop(usbduxsub_tmp, 1);
1720 kfree(usbduxsub_tmp->urbPwm->transfer_buffer);
1721 usbduxsub_tmp->urbPwm->transfer_buffer = NULL;
1722 usb_free_urb(usbduxsub_tmp->urbPwm);
1723 usbduxsub_tmp->urbPwm = NULL;
1725 kfree(usbduxsub_tmp->inBuffer);
1726 usbduxsub_tmp->inBuffer = NULL;
1727 kfree(usbduxsub_tmp->insnBuffer);
1728 usbduxsub_tmp->insnBuffer = NULL;
1729 kfree(usbduxsub_tmp->outBuffer);
1730 usbduxsub_tmp->outBuffer = NULL;
1731 kfree(usbduxsub_tmp->dac_commands);
1732 usbduxsub_tmp->dac_commands = NULL;
1733 kfree(usbduxsub_tmp->dux_commands);
1734 usbduxsub_tmp->dux_commands = NULL;
1737 static int usbduxsigma_attach_common(struct comedi_device *dev)
1739 struct usbduxsigma_private *uds = dev->private;
1741 struct comedi_subdevice *s;
1747 /* set number of subdevices */
1748 if (uds->high_speed)
1749 n_subdevs = 4; /* with pwm */
1751 n_subdevs = 3; /* without pwm */
1752 ret = comedi_alloc_subdevices(dev, n_subdevs);
1757 /* the first subdevice is the A/D converter */
1758 s = &dev->subdevices[SUBDEV_AD];
1759 /* the URBs get the comedi subdevice */
1760 /* which is responsible for reading */
1761 /* this is the subdevice which reads data */
1762 dev->read_subdev = s;
1763 /* the subdevice receives as private structure the */
1767 s->type = COMEDI_SUBD_AI;
1768 /* readable and ref is to ground, 32 bit wide data! */
1769 s->subdev_flags = SDF_READABLE | SDF_GROUND |
1770 SDF_CMD_READ | SDF_LSAMPL;
1771 /* 16 A/D channels */
1772 s->n_chan = NUMCHANNELS;
1773 /* length of the channellist */
1774 s->len_chanlist = NUMCHANNELS;
1775 /* callback functions */
1776 s->insn_read = usbdux_ai_insn_read;
1777 s->do_cmdtest = usbdux_ai_cmdtest;
1778 s->do_cmd = usbdux_ai_cmd;
1779 s->cancel = usbdux_ai_cancel;
1780 /* max value from the A/D converter (24bit) */
1781 s->maxdata = 0x00FFFFFF;
1782 /* range table to convert to physical units */
1783 s->range_table = (&range_usbdux_ai_range);
1784 /* analog output subdevice */
1785 s = &dev->subdevices[SUBDEV_DA];
1787 s->type = COMEDI_SUBD_AO;
1788 /* backward pointer */
1789 dev->write_subdev = s;
1790 /* the subdevice receives as private structure the */
1794 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1797 /* length of the channellist */
1798 s->len_chanlist = 4;
1799 /* 8 bit resolution */
1800 s->maxdata = 0x00ff;
1801 /* unipolar range */
1802 s->range_table = &range_unipolar2_5;
1804 s->do_cmdtest = usbdux_ao_cmdtest;
1805 s->do_cmd = usbdux_ao_cmd;
1806 s->cancel = usbdux_ao_cancel;
1807 s->insn_read = usbdux_ao_insn_read;
1808 s->insn_write = usbdux_ao_insn_write;
1809 /* digital I/O subdevice */
1810 s = &dev->subdevices[SUBDEV_DIO];
1811 s->type = COMEDI_SUBD_DIO;
1812 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1813 /* 8 external and 16 internal channels */
1816 s->range_table = (&range_digital);
1817 s->insn_bits = usbdux_dio_insn_bits;
1818 s->insn_config = usbdux_dio_insn_config;
1819 /* we don't use it */
1821 if (uds->high_speed) {
1822 /* timer / pwm subdevice */
1823 s = &dev->subdevices[SUBDEV_PWM];
1824 s->type = COMEDI_SUBD_PWM;
1825 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1827 /* this defines the max duty cycle resolution */
1828 s->maxdata = uds->sizePwmBuf;
1829 s->insn_write = usbdux_pwm_write;
1830 s->insn_read = usbdux_pwm_read;
1831 s->insn_config = usbdux_pwm_config;
1832 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1835 offset = usbdux_getstatusinfo(dev, 0);
1837 dev_err(&uds->interface->dev,
1838 "Communication to USBDUXSIGMA failed! Check firmware and cabling.");
1839 dev_info(&uds->interface->dev,
1840 "comedi%d: attached, ADC_zero = %x\n", dev->minor, offset);
1844 static int usbduxsigma_alloc_usb_buffers(struct usbduxsigma_private *devpriv)
1846 struct usb_device *usb = devpriv->usbdev;
1850 devpriv->dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
1851 devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1852 devpriv->inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1853 devpriv->insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1854 devpriv->outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1855 devpriv->urbIn = kcalloc(devpriv->numOfInBuffers, sizeof(*urb),
1857 devpriv->urbOut = kcalloc(devpriv->numOfOutBuffers, sizeof(*urb),
1859 if (!devpriv->dac_commands || !devpriv->dux_commands ||
1860 !devpriv->inBuffer || !devpriv->insnBuffer ||
1861 !devpriv->outBuffer || !devpriv->urbIn || !devpriv->urbOut)
1864 for (i = 0; i < devpriv->numOfInBuffers; i++) {
1865 /* one frame: 1ms */
1866 urb = usb_alloc_urb(1, GFP_KERNEL);
1869 devpriv->urbIn[i] = urb;
1871 /* will be filled later with a pointer to the comedi-device */
1872 /* and ONLY then the urb should be submitted */
1873 urb->context = NULL;
1874 urb->pipe = usb_rcvisocpipe(usb, ISOINEP);
1875 urb->transfer_flags = URB_ISO_ASAP;
1876 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1877 if (!urb->transfer_buffer)
1879 urb->complete = usbduxsub_ai_IsocIrq;
1880 urb->number_of_packets = 1;
1881 urb->transfer_buffer_length = SIZEINBUF;
1882 urb->iso_frame_desc[0].offset = 0;
1883 urb->iso_frame_desc[0].length = SIZEINBUF;
1886 for (i = 0; i < devpriv->numOfOutBuffers; i++) {
1887 /* one frame: 1ms */
1888 urb = usb_alloc_urb(1, GFP_KERNEL);
1891 devpriv->urbOut[i] = urb;
1893 /* will be filled later with a pointer to the comedi-device */
1894 /* and ONLY then the urb should be submitted */
1895 urb->context = NULL;
1896 urb->pipe = usb_sndisocpipe(usb, ISOOUTEP);
1897 urb->transfer_flags = URB_ISO_ASAP;
1898 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1899 if (!urb->transfer_buffer)
1901 urb->complete = usbduxsub_ao_IsocIrq;
1902 urb->number_of_packets = 1;
1903 urb->transfer_buffer_length = SIZEOUTBUF;
1904 urb->iso_frame_desc[0].offset = 0;
1905 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1906 if (devpriv->high_speed)
1907 urb->interval = 8; /* uframes */
1909 urb->interval = 1; /* frames */
1912 if (devpriv->high_speed) {
1913 /* max bulk ep size in high speed */
1914 devpriv->sizePwmBuf = 512;
1915 urb = usb_alloc_urb(0, GFP_KERNEL);
1918 devpriv->urbPwm = urb;
1919 urb->transfer_buffer = kzalloc(devpriv->sizePwmBuf, GFP_KERNEL);
1920 if (!urb->transfer_buffer)
1923 devpriv->urbPwm = NULL;
1924 devpriv->sizePwmBuf = 0;
1930 static int usbduxsigma_auto_attach(struct comedi_device *dev,
1931 unsigned long context_unused)
1933 struct usb_interface *intf = comedi_to_usb_interface(dev);
1934 struct usb_device *usb = comedi_to_usb_dev(dev);
1935 struct usbduxsigma_private *devpriv;
1938 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1941 dev->private = devpriv;
1943 sema_init(&devpriv->sem, 1);
1944 devpriv->usbdev = usb;
1945 devpriv->interface = intf;
1946 usb_set_intfdata(intf, devpriv);
1948 ret = usb_set_interface(usb,
1949 intf->altsetting->desc.bInterfaceNumber, 3);
1951 dev_err(dev->class_dev,
1952 "could not set alternate setting 3 in high speed\n");
1956 /* test if it is high speed (USB 2.0) */
1957 devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1958 if (devpriv->high_speed) {
1959 devpriv->numOfInBuffers = NUMOFINBUFFERSHIGH;
1960 devpriv->numOfOutBuffers = NUMOFOUTBUFFERSHIGH;
1962 devpriv->numOfInBuffers = NUMOFINBUFFERSFULL;
1963 devpriv->numOfOutBuffers = NUMOFOUTBUFFERSFULL;
1966 ret = usbduxsigma_alloc_usb_buffers(devpriv);
1972 ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1973 usbduxsigma_firmware_upload, 0);
1977 return usbduxsigma_attach_common(dev);
1980 static void usbduxsigma_detach(struct comedi_device *dev)
1982 struct usbduxsigma_private *devpriv = dev->private;
1987 /* stop any running commands */
1988 usbdux_ai_stop(devpriv, devpriv->ai_cmd_running);
1989 usbdux_ao_stop(devpriv, devpriv->ao_cmd_running);
1991 down(&devpriv->sem);
1996 static struct comedi_driver usbduxsigma_driver = {
1997 .driver_name = "usbduxsigma",
1998 .module = THIS_MODULE,
1999 .auto_attach = usbduxsigma_auto_attach,
2000 .detach = usbduxsigma_detach,
2003 static int usbduxsigma_usb_probe(struct usb_interface *intf,
2004 const struct usb_device_id *id)
2006 return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0);;
2009 static const struct usb_device_id usbduxsigma_usb_table[] = {
2010 { USB_DEVICE(0x13d8, 0x0020) },
2011 { USB_DEVICE(0x13d8, 0x0021) },
2012 { USB_DEVICE(0x13d8, 0x0022) },
2015 MODULE_DEVICE_TABLE(usb, usbduxsigma_usb_table);
2017 static struct usb_driver usbduxsigma_usb_driver = {
2018 .name = "usbduxsigma",
2019 .probe = usbduxsigma_usb_probe,
2020 .disconnect = comedi_usb_auto_unconfig,
2021 .id_table = usbduxsigma_usb_table,
2023 module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver);
2025 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
2026 MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com");
2027 MODULE_LICENSE("GPL");
2028 MODULE_FIRMWARE(FIRMWARE);