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 /* actual number of in-buffers */
171 /* actual number of out-buffers */
173 /* ISO-transfer handling: buffers */
176 /* pwm-transfer handling */
179 unsigned int pwmPeriod;
180 /* PWM internal delay for the GPIF in the FX2 */
182 /* size of the PWM buffer which holds the bit pattern */
184 /* input buffer for the ISO-transfer */
186 /* input buffer for single insn */
188 /* output buffer for single DA outputs */
190 /* interface structure in 2.6 */
191 struct usb_interface *interface;
192 /* is it USB_SPEED_HIGH or not? */
193 short int high_speed;
194 /* asynchronous command is running */
195 short int ai_cmd_running;
196 short int ao_cmd_running;
198 short int pwm_cmd_running;
199 /* continuous acquisition */
200 short int ai_continuous;
201 short int ao_continuous;
202 /* number of samples to acquire */
205 /* time between samples in units of the timer */
206 unsigned int ai_timer;
207 unsigned int ao_timer;
208 /* counter between acquisitions */
209 unsigned int ai_counter;
210 unsigned int ao_counter;
211 /* interval in frames/uframes */
212 unsigned int ai_interval;
214 uint8_t *dac_commands;
216 uint8_t *dux_commands;
217 struct semaphore sem;
220 static void usbdux_ai_stop(struct usbduxsigma_private *devpriv, int do_unlink)
225 for (i = 0; i < devpriv->numOfInBuffers; i++) {
226 if (devpriv->urbIn[i])
227 usb_kill_urb(devpriv->urbIn[i]);
231 devpriv->ai_cmd_running = 0;
234 static int usbdux_ai_cancel(struct comedi_device *dev,
235 struct comedi_subdevice *s)
237 struct usbduxsigma_private *devpriv = dev->private;
240 /* unlink only if it is really running */
241 usbdux_ai_stop(devpriv, devpriv->ai_cmd_running);
247 static void usbduxsub_ai_IsocIrq(struct urb *urb)
249 struct comedi_device *dev = urb->context;
250 struct usbduxsigma_private *devpriv = dev->private;
251 struct comedi_subdevice *s = dev->read_subdev;
252 unsigned int dio_state;
257 /* first we test if something unusual has just happened */
258 switch (urb->status) {
260 /* copy the result in the transfer buffer */
261 memcpy(devpriv->inBuffer, urb->transfer_buffer, SIZEINBUF);
265 * error in the ISOchronous data
266 * we don't copy the data into the transfer buffer
267 * and recycle the last data byte
269 dev_dbg(dev->class_dev,"CRC error in ISO IN stream\n");
277 /* happens after an unlink command */
278 if (devpriv->ai_cmd_running) {
279 usbdux_ai_stop(devpriv, 0); /* w/o unlink */
280 /* we are still running a command, tell comedi */
281 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
282 comedi_event(dev, s);
288 * a real error on the bus
289 * pass error to comedi if we are really running a command
291 if (devpriv->ai_cmd_running) {
292 dev_err(dev->class_dev,
293 "%s: non-zero urb status (%d)\n",
294 __func__, urb->status);
295 usbdux_ai_stop(devpriv, 0); /* w/o unlink */
296 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
297 comedi_event(dev, s);
302 if (unlikely(!devpriv->ai_cmd_running))
305 urb->dev = comedi_to_usb_dev(dev);
307 ret = usb_submit_urb(urb, GFP_ATOMIC);
308 if (unlikely(ret < 0)) {
309 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
311 if (ret == -EL2NSYNC)
312 dev_err(dev->class_dev,
313 "buggy USB host controller or bug in IRQ handler\n");
314 usbdux_ai_stop(devpriv, 0); /* w/o unlink */
315 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
316 comedi_event(dev, s);
320 /* get the state of the dio pins to allow external trigger */
321 dio_state = be32_to_cpu(devpriv->inBuffer[0]);
323 devpriv->ai_counter--;
324 if (likely(devpriv->ai_counter > 0))
327 /* timer zero, transfer measurements to comedi */
328 devpriv->ai_counter = devpriv->ai_timer;
330 if (!devpriv->ai_continuous) {
331 /* not continuous, fixed number of samples */
332 devpriv->ai_sample_count--;
333 if (devpriv->ai_sample_count < 0) {
334 usbdux_ai_stop(devpriv, 0); /* w/o unlink */
335 /* acquistion is over, tell comedi */
336 s->async->events |= COMEDI_CB_EOA;
337 comedi_event(dev, s);
342 /* get the data from the USB bus and hand it over to comedi */
343 for (i = 0; i < s->async->cmd.chanlist_len; i++) {
344 /* transfer data, note first byte is the DIO state */
345 val = be32_to_cpu(devpriv->inBuffer[i+1]);
346 val &= 0x00ffffff; /* strip status byte */
347 val ^= 0x00800000; /* convert to unsigned */
349 ret = cfc_write_array_to_buffer(s, &val, sizeof(uint32_t));
350 if (unlikely(ret == 0)) {
351 /* buffer overflow */
352 usbdux_ai_stop(devpriv, 0); /* w/o unlink */
356 /* tell comedi that data is there */
357 s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
358 comedi_event(dev, s);
361 static void usbdux_ao_stop(struct usbduxsigma_private *devpriv, int do_unlink)
366 for (i = 0; i < devpriv->numOfOutBuffers; i++) {
367 if (devpriv->urbOut[i])
368 usb_kill_urb(devpriv->urbOut[i]);
372 devpriv->ao_cmd_running = 0;
375 static int usbdux_ao_cancel(struct comedi_device *dev,
376 struct comedi_subdevice *s)
378 struct usbduxsigma_private *devpriv = dev->private;
381 /* unlink only if it is really running */
382 usbdux_ao_stop(devpriv, devpriv->ao_cmd_running);
388 static void usbduxsub_ao_IsocIrq(struct urb *urb)
390 struct comedi_device *dev = urb->context;
391 struct usbduxsigma_private *devpriv = dev->private;
392 struct comedi_subdevice *s = dev->write_subdev;
398 switch (urb->status) {
407 /* happens after an unlink command */
408 if (devpriv->ao_cmd_running) {
409 usbdux_ao_stop(devpriv, 0); /* w/o unlink */
410 s->async->events |= COMEDI_CB_EOA;
411 comedi_event(dev, s);
417 if (devpriv->ao_cmd_running) {
418 dev_err(dev->class_dev,
419 "%s: non-zero urb status (%d)\n",
420 __func__, urb->status);
421 usbdux_ao_stop(devpriv, 0); /* w/o unlink */
422 s->async->events |= (COMEDI_CB_ERROR | COMEDI_CB_EOA);
423 comedi_event(dev, s);
428 if (!devpriv->ao_cmd_running)
431 devpriv->ao_counter--;
432 if ((int)devpriv->ao_counter <= 0) {
433 /* timer zero, transfer from comedi */
434 devpriv->ao_counter = devpriv->ao_timer;
436 if (!devpriv->ao_continuous) {
437 /* not continuous, fixed number of samples */
438 devpriv->ao_sample_count--;
439 if (devpriv->ao_sample_count < 0) {
440 usbdux_ao_stop(devpriv, 0); /* w/o unlink */
441 /* acquistion is over, tell comedi */
442 s->async->events |= COMEDI_CB_EOA;
443 comedi_event(dev, s);
448 /* transmit data to the USB bus */
449 datap = urb->transfer_buffer;
450 len = s->async->cmd.chanlist_len;
452 for (i = 0; i < len; i++) {
455 if (i >= NUMOUTCHANNELS)
458 ret = comedi_buf_get(s->async, &val);
460 dev_err(dev->class_dev, "buffer underflow\n");
461 s->async->events |= (COMEDI_CB_EOA |
465 *datap++ = devpriv->dac_commands[i];
467 s->async->events |= COMEDI_CB_BLOCK;
468 comedi_event(dev, s);
472 urb->transfer_buffer_length = SIZEOUTBUF;
473 urb->dev = comedi_to_usb_dev(dev);
475 if (devpriv->high_speed)
476 urb->interval = 8; /* uframes */
478 urb->interval = 1; /* frames */
479 urb->number_of_packets = 1;
480 urb->iso_frame_desc[0].offset = 0;
481 urb->iso_frame_desc[0].length = SIZEOUTBUF;
482 urb->iso_frame_desc[0].status = 0;
483 ret = usb_submit_urb(urb, GFP_ATOMIC);
485 dev_err(dev->class_dev,
486 "%s: urb resubmit failed (%d)\n",
489 dev_err(dev->class_dev,
490 "buggy USB host controller or bug in IRQ handler\n");
491 usbdux_ao_stop(devpriv, 0); /* w/o unlink */
492 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
493 comedi_event(dev, s);
497 /* the FX2LP has twice as much as the standard FX2 */
498 #define FIRMWARE_MAX_LEN 0x4000
500 static int usbduxsigma_firmware_upload(struct comedi_device *dev,
501 const u8 *data, size_t size,
502 unsigned long context)
504 struct usb_device *usb = comedi_to_usb_dev(dev);
512 if (size > FIRMWARE_MAX_LEN) {
513 dev_err(dev->class_dev, "firmware binary too large for FX2\n");
517 /* we generate a local buffer for the firmware */
518 buf = kmemdup(data, size, GFP_KERNEL);
522 /* we need a malloc'ed buffer for usb_control_msg() */
523 tmp = kmalloc(1, GFP_KERNEL);
529 /* stop the current firmware on the device */
530 *tmp = 1; /* 7f92 to one */
531 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
534 USBDUXSUB_CPUCS, 0x0000,
538 dev_err(dev->class_dev, "can not stop firmware\n");
542 /* upload the new firmware to the device */
543 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
550 dev_err(dev->class_dev, "firmware upload failed\n");
554 /* start the new firmware on the device */
555 *tmp = 0; /* 7f92 to zero */
556 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
559 USBDUXSUB_CPUCS, 0x0000,
563 dev_err(dev->class_dev, "can not start firmware\n");
571 static int usbduxsigma_submit_urbs(struct comedi_device *dev,
572 struct urb **urbs, int num_urbs,
575 struct usb_device *usb = comedi_to_usb_dev(dev);
576 struct usbduxsigma_private *devpriv = dev->private;
581 /* Submit all URBs and start the transfer on the bus */
582 for (i = 0; i < num_urbs; i++) {
585 /* in case of a resubmission after an unlink... */
587 urb->interval = devpriv->ai_interval;
591 urb->transfer_flags = URB_ISO_ASAP;
593 ret = usb_submit_urb(urb, GFP_ATOMIC);
600 static int chanToInterval(int nChannels)
612 static int usbdux_ai_cmdtest(struct comedi_device *dev,
613 struct comedi_subdevice *s,
614 struct comedi_cmd *cmd)
616 struct usbduxsigma_private *this_usbduxsub = dev->private;
618 unsigned int tmpTimer;
620 /* Step 1 : check if triggers are trivially valid */
622 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
623 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
624 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
625 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
626 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
631 /* Step 2a : make sure trigger sources are unique */
633 err |= cfc_check_trigger_is_unique(cmd->start_src);
634 err |= cfc_check_trigger_is_unique(cmd->stop_src);
636 /* Step 2b : and mutually compatible */
641 /* Step 3: check if arguments are trivially valid */
643 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
645 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
646 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
648 if (cmd->scan_begin_src == TRIG_TIMER) {
649 if (this_usbduxsub->high_speed) {
651 * In high speed mode microframes are possible.
652 * However, during one microframe we can roughly
653 * sample two channels. Thus, the more channels
654 * are in the channel list the more time we need.
656 i = chanToInterval(cmd->chanlist_len);
657 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
659 /* now calc the real sampling rate with all the
662 ((unsigned int)(cmd->scan_begin_arg / 125000)) *
666 /* 1kHz scans every USB frame */
667 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
670 * calc the real sampling rate with the rounding errors
672 tmpTimer = ((unsigned int)(cmd->scan_begin_arg /
675 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
679 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
681 if (cmd->stop_src == TRIG_COUNT) {
682 /* any count is allowed */
685 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
695 * creates the ADC command for the MAX1271
696 * range is the range value from comedi
698 static void create_adc_command(unsigned int chan,
703 (*muxsg0) = (*muxsg0) | (1 << chan);
705 (*muxsg1) = (*muxsg1) | (1 << (chan-8));
709 /* bulk transfers to usbdux */
711 #define SENDADCOMMANDS 0
712 #define SENDDACOMMANDS 1
713 #define SENDDIOCONFIGCOMMAND 2
714 #define SENDDIOBITSCOMMAND 3
715 #define SENDSINGLEAD 4
719 static int send_dux_commands(struct comedi_device *dev, int cmd_type)
721 struct usb_device *usb = comedi_to_usb_dev(dev);
722 struct usbduxsigma_private *devpriv = dev->private;
725 devpriv->dux_commands[0] = cmd_type;
727 return usb_bulk_msg(usb, usb_sndbulkpipe(usb, COMMAND_OUT_EP),
728 devpriv->dux_commands, SIZEOFDUXBUFFER,
729 &nsent, BULK_TIMEOUT);
732 static int receive_dux_commands(struct comedi_device *dev, int command)
734 struct usb_device *usb = comedi_to_usb_dev(dev);
735 struct usbduxsigma_private *devpriv = dev->private;
740 for (i = 0; i < RETRIES; i++) {
741 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, COMMAND_IN_EP),
742 devpriv->insnBuffer, SIZEINSNBUF,
743 &nrec, BULK_TIMEOUT);
747 if (devpriv->insnBuffer[0] == command)
751 * This is only reached if the data has been requested a
752 * couple of times and the command was not received.
757 static int usbdux_ai_inttrig(struct comedi_device *dev,
758 struct comedi_subdevice *s, unsigned int trignum)
760 struct usbduxsigma_private *this_usbduxsub = dev->private;
763 down(&this_usbduxsub->sem);
765 dev_err(&this_usbduxsub->interface->dev,
766 "comedi%d: usbdux_ai_inttrig: invalid trignum\n",
768 up(&this_usbduxsub->sem);
771 if (!this_usbduxsub->ai_cmd_running) {
772 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbIn,
773 this_usbduxsub->numOfInBuffers,
776 up(&this_usbduxsub->sem);
779 this_usbduxsub->ai_cmd_running = 1;
780 s->async->inttrig = NULL;
782 dev_err(&this_usbduxsub->interface->dev,
783 "comedi%d: ai_inttrig but acqu is already running\n",
786 up(&this_usbduxsub->sem);
790 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
792 struct usbduxsigma_private *this_usbduxsub = dev->private;
793 struct comedi_cmd *cmd = &s->async->cmd;
801 /* block other CPUs from starting an ai_cmd */
802 down(&this_usbduxsub->sem);
803 if (this_usbduxsub->ai_cmd_running) {
804 dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
805 "ai_cmd not possible. Another ai_cmd is running.\n",
807 up(&this_usbduxsub->sem);
810 /* set current channel of the running acquisition to zero */
811 s->async->cur_chan = 0;
813 /* first the number of channels per time step */
814 this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
817 this_usbduxsub->dux_commands[2] = 0x12;
819 /* CONFIG1: 23kHz sampling rate, delay = 0us, */
820 this_usbduxsub->dux_commands[3] = 0x03;
822 /* CONFIG3: differential channels off */
823 this_usbduxsub->dux_commands[4] = 0x00;
825 for (i = 0; i < cmd->chanlist_len; i++) {
826 chan = CR_CHAN(cmd->chanlist[i]);
827 create_adc_command(chan, &muxsg0, &muxsg1);
828 if (i >= NUMCHANNELS) {
829 dev_err(&this_usbduxsub->interface->dev,
830 "comedi%d: channel list too long\n",
835 this_usbduxsub->dux_commands[5] = muxsg0;
836 this_usbduxsub->dux_commands[6] = muxsg1;
837 this_usbduxsub->dux_commands[7] = sysred;
839 result = send_dux_commands(dev, SENDADCOMMANDS);
841 up(&this_usbduxsub->sem);
845 if (this_usbduxsub->high_speed) {
847 * every 2 channels get a time window of 125us. Thus, if we
848 * sample all 16 channels we need 1ms. If we sample only one
849 * channel we need only 125us
851 this_usbduxsub->ai_interval =
852 chanToInterval(cmd->chanlist_len);
853 this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
857 /* interval always 1ms */
858 this_usbduxsub->ai_interval = 1;
859 this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000;
861 if (this_usbduxsub->ai_timer < 1) {
862 dev_err(&this_usbduxsub->interface->dev, "comedi%d: ai_cmd: "
863 "timer=%d, scan_begin_arg=%d. "
864 "Not properly tested by cmdtest?\n", dev->minor,
865 this_usbduxsub->ai_timer, cmd->scan_begin_arg);
866 up(&this_usbduxsub->sem);
869 this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
871 if (cmd->stop_src == TRIG_COUNT) {
872 /* data arrives as one packet */
873 this_usbduxsub->ai_sample_count = cmd->stop_arg;
874 this_usbduxsub->ai_continuous = 0;
876 /* continuous acquisition */
877 this_usbduxsub->ai_continuous = 1;
878 this_usbduxsub->ai_sample_count = 0;
881 if (cmd->start_src == TRIG_NOW) {
882 /* enable this acquisition operation */
883 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbIn,
884 this_usbduxsub->numOfInBuffers,
887 up(&this_usbduxsub->sem);
890 this_usbduxsub->ai_cmd_running = 1;
891 s->async->inttrig = NULL;
894 /* don't enable the acquision operation */
895 /* wait for an internal signal */
896 s->async->inttrig = usbdux_ai_inttrig;
898 up(&this_usbduxsub->sem);
902 /* Mode 0 is used to get a single conversion on demand */
903 static int usbdux_ai_insn_read(struct comedi_device *dev,
904 struct comedi_subdevice *s,
905 struct comedi_insn *insn, unsigned int *data)
907 struct usbduxsigma_private *this_usbduxsub = dev->private;
916 down(&this_usbduxsub->sem);
917 if (this_usbduxsub->ai_cmd_running) {
918 dev_err(&this_usbduxsub->interface->dev,
919 "comedi%d: ai_insn_read not possible. "
920 "Async Command is running.\n", dev->minor);
921 up(&this_usbduxsub->sem);
925 /* sample one channel */
926 /* CONFIG0: chopper on */
927 this_usbduxsub->dux_commands[1] = 0x16;
929 /* CONFIG1: 2kHz sampling rate */
930 this_usbduxsub->dux_commands[2] = 0x80;
932 /* CONFIG3: differential channels off */
933 this_usbduxsub->dux_commands[3] = 0x00;
935 chan = CR_CHAN(insn->chanspec);
936 create_adc_command(chan, &muxsg0, &muxsg1);
938 this_usbduxsub->dux_commands[4] = muxsg0;
939 this_usbduxsub->dux_commands[5] = muxsg1;
940 this_usbduxsub->dux_commands[6] = sysred;
943 err = send_dux_commands(dev, SENDSINGLEAD);
945 up(&this_usbduxsub->sem);
949 for (i = 0; i < insn->n; i++) {
950 err = receive_dux_commands(dev, SENDSINGLEAD);
952 up(&this_usbduxsub->sem);
955 /* 32 bits big endian from the A/D converter */
956 one = be32_to_cpu(*((int32_t *)
957 ((this_usbduxsub->insnBuffer)+1)));
958 /* mask out the status byte */
959 one = one & 0x00ffffff;
960 /* turn it into an unsigned integer */
961 one = one ^ 0x00800000;
964 up(&this_usbduxsub->sem);
971 static int usbdux_getstatusinfo(struct comedi_device *dev, int chan)
973 struct usbduxsigma_private *this_usbduxsub = dev->private;
978 if (this_usbduxsub->ai_cmd_running) {
979 dev_err(&this_usbduxsub->interface->dev,
980 "comedi%d: status read not possible. "
981 "Async Command is running.\n", dev->minor);
986 this_usbduxsub->dux_commands[1] = 0x12;
988 /* CONFIG1: 2kHz sampling rate */
989 this_usbduxsub->dux_commands[2] = 0x80;
991 /* CONFIG3: differential channels off */
992 this_usbduxsub->dux_commands[3] = 0x00;
997 } else if (chan == 2) {
1000 } else if (chan == 3) {
1002 sysred = sysred | 8;
1003 } else if (chan == 4) {
1005 sysred = sysred | 16;
1006 } else if (chan == 5) {
1008 sysred = sysred | 32;
1011 this_usbduxsub->dux_commands[4] = 0;
1012 this_usbduxsub->dux_commands[5] = 0;
1013 this_usbduxsub->dux_commands[6] = sysred;
1016 err = send_dux_commands(dev, SENDSINGLEAD);
1020 err = receive_dux_commands(dev, SENDSINGLEAD);
1024 /* 32 bits big endian from the A/D converter */
1025 one = be32_to_cpu(*((int32_t *)((this_usbduxsub->insnBuffer)+1)));
1026 /* mask out the status byte */
1027 one = one & 0x00ffffff;
1028 one = one ^ 0x00800000;
1038 /************************************/
1041 static int usbdux_ao_insn_read(struct comedi_device *dev,
1042 struct comedi_subdevice *s,
1043 struct comedi_insn *insn, unsigned int *data)
1045 struct usbduxsigma_private *this_usbduxsub = dev->private;
1047 int chan = CR_CHAN(insn->chanspec);
1049 down(&this_usbduxsub->sem);
1050 for (i = 0; i < insn->n; i++)
1051 data[i] = this_usbduxsub->outBuffer[chan];
1053 up(&this_usbduxsub->sem);
1057 static int usbdux_ao_insn_write(struct comedi_device *dev,
1058 struct comedi_subdevice *s,
1059 struct comedi_insn *insn, unsigned int *data)
1061 struct usbduxsigma_private *this_usbduxsub = dev->private;
1063 int chan = CR_CHAN(insn->chanspec);
1065 down(&this_usbduxsub->sem);
1066 if (this_usbduxsub->ao_cmd_running) {
1067 dev_err(&this_usbduxsub->interface->dev,
1068 "comedi%d: ao_insn_write: "
1069 "ERROR: asynchronous ao_cmd is running\n", dev->minor);
1070 up(&this_usbduxsub->sem);
1074 for (i = 0; i < insn->n; i++) {
1075 dev_dbg(&this_usbduxsub->interface->dev,
1076 "comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n",
1077 dev->minor, chan, i, data[i]);
1079 /* number of channels: 1 */
1080 this_usbduxsub->dux_commands[1] = 1;
1081 /* channel number */
1082 this_usbduxsub->dux_commands[2] = data[i];
1083 this_usbduxsub->outBuffer[chan] = data[i];
1084 this_usbduxsub->dux_commands[3] = chan;
1085 err = send_dux_commands(dev, SENDDACOMMANDS);
1087 up(&this_usbduxsub->sem);
1091 up(&this_usbduxsub->sem);
1096 static int usbdux_ao_inttrig(struct comedi_device *dev,
1097 struct comedi_subdevice *s, unsigned int trignum)
1099 struct usbduxsigma_private *this_usbduxsub = dev->private;
1102 down(&this_usbduxsub->sem);
1104 dev_err(&this_usbduxsub->interface->dev,
1105 "comedi%d: usbdux_ao_inttrig: invalid trignum\n",
1110 if (!(this_usbduxsub->ao_cmd_running)) {
1111 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbOut,
1112 this_usbduxsub->numOfOutBuffers,
1116 this_usbduxsub->ao_cmd_running = 1;
1117 s->async->inttrig = NULL;
1119 dev_err(&this_usbduxsub->interface->dev,
1120 "comedi%d: ao_inttrig but acqu is already running.\n",
1125 up(&this_usbduxsub->sem);
1129 static int usbdux_ao_cmdtest(struct comedi_device *dev,
1130 struct comedi_subdevice *s,
1131 struct comedi_cmd *cmd)
1136 /* Step 1 : check if triggers are trivially valid */
1138 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
1140 if (0) { /* (this_usbduxsub->high_speed) */
1142 * start immediately a new scan
1143 * the sampling rate is set by the coversion rate
1145 flags = TRIG_FOLLOW;
1147 /* start a new scan (output at once) with a timer */
1150 err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
1152 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1153 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1154 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1159 /* Step 2a : make sure trigger sources are unique */
1161 err |= cfc_check_trigger_is_unique(cmd->start_src);
1162 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1164 /* Step 2b : and mutually compatible */
1169 /* Step 3: check if arguments are trivially valid */
1171 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1173 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
1174 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1176 if (cmd->scan_begin_src == TRIG_TIMER)
1177 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1180 /* not used now, is for later use */
1181 if (cmd->convert_src == TRIG_TIMER)
1182 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
1184 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1186 if (cmd->stop_src == TRIG_COUNT) {
1187 /* any count is allowed */
1190 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1199 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1201 struct usbduxsigma_private *this_usbduxsub = dev->private;
1202 struct comedi_cmd *cmd = &s->async->cmd;
1203 unsigned int chan, gain;
1206 down(&this_usbduxsub->sem);
1207 /* set current channel of the running acquisition to zero */
1208 s->async->cur_chan = 0;
1209 for (i = 0; i < cmd->chanlist_len; ++i) {
1210 chan = CR_CHAN(cmd->chanlist[i]);
1211 gain = CR_RANGE(cmd->chanlist[i]);
1212 if (i >= NUMOUTCHANNELS) {
1213 dev_err(&this_usbduxsub->interface->dev,
1214 "comedi%d: %s: channel list too long\n",
1215 dev->minor, __func__);
1218 this_usbduxsub->dac_commands[i] = chan;
1219 dev_dbg(&this_usbduxsub->interface->dev,
1220 "comedi%d: dac command for ch %d is %x\n",
1221 dev->minor, i, this_usbduxsub->dac_commands[i]);
1224 /* we count in steps of 1ms (125us) */
1225 /* 125us mode not used yet */
1226 if (0) { /* (this_usbduxsub->high_speed) */
1228 /* timing of the conversion itself: every 125 us */
1229 this_usbduxsub->ao_timer = cmd->convert_arg / 125000;
1232 /* timing of the scan: we get all channels at once */
1233 this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000;
1234 dev_dbg(&this_usbduxsub->interface->dev,
1235 "comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
1236 "convert_src=%d, convert_arg=%d\n", dev->minor,
1237 cmd->scan_begin_src, cmd->scan_begin_arg,
1238 cmd->convert_src, cmd->convert_arg);
1239 dev_dbg(&this_usbduxsub->interface->dev,
1240 "comedi%d: ao_timer=%d (ms)\n",
1241 dev->minor, this_usbduxsub->ao_timer);
1242 if (this_usbduxsub->ao_timer < 1) {
1243 dev_err(&this_usbduxsub->interface->dev,
1244 "comedi%d: usbdux: ao_timer=%d, "
1245 "scan_begin_arg=%d. "
1246 "Not properly tested by cmdtest?\n",
1247 dev->minor, this_usbduxsub->ao_timer,
1248 cmd->scan_begin_arg);
1249 up(&this_usbduxsub->sem);
1253 this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
1255 if (cmd->stop_src == TRIG_COUNT) {
1256 /* not continuous */
1258 /* high speed also scans everything at once */
1259 if (0) { /* (this_usbduxsub->high_speed) */
1260 this_usbduxsub->ao_sample_count =
1261 (cmd->stop_arg) * (cmd->scan_end_arg);
1263 /* there's no scan as the scan has been */
1264 /* perf inside the FX2 */
1265 /* data arrives as one packet */
1266 this_usbduxsub->ao_sample_count = cmd->stop_arg;
1268 this_usbduxsub->ao_continuous = 0;
1270 /* continuous acquisition */
1271 this_usbduxsub->ao_continuous = 1;
1272 this_usbduxsub->ao_sample_count = 0;
1275 if (cmd->start_src == TRIG_NOW) {
1276 /* enable this acquisition operation */
1277 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbOut,
1278 this_usbduxsub->numOfOutBuffers,
1281 up(&this_usbduxsub->sem);
1284 this_usbduxsub->ao_cmd_running = 1;
1285 s->async->inttrig = NULL;
1288 /* submit the urbs later */
1289 /* wait for an internal signal */
1290 s->async->inttrig = usbdux_ao_inttrig;
1293 up(&this_usbduxsub->sem);
1297 static int usbdux_dio_insn_config(struct comedi_device *dev,
1298 struct comedi_subdevice *s,
1299 struct comedi_insn *insn, unsigned int *data)
1301 int chan = CR_CHAN(insn->chanspec);
1303 /* The input or output configuration of each digital line is
1304 * configured by a special insn_config instruction. chanspec
1305 * contains the channel to be changed, and data[0] contains the
1306 * value COMEDI_INPUT or COMEDI_OUTPUT. */
1309 case INSN_CONFIG_DIO_OUTPUT:
1310 s->io_bits |= 1 << chan; /* 1 means Out */
1312 case INSN_CONFIG_DIO_INPUT:
1313 s->io_bits &= ~(1 << chan);
1315 case INSN_CONFIG_DIO_QUERY:
1317 (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1323 /* we don't tell the firmware here as it would take 8 frames */
1324 /* to submit the information. We do it in the insn_bits. */
1328 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1329 struct comedi_subdevice *s,
1330 struct comedi_insn *insn,
1333 struct usbduxsigma_private *this_usbduxsub = dev->private;
1336 down(&this_usbduxsub->sem);
1338 /* The insn data is a mask in data[0] and the new data
1339 * in data[1], each channel cooresponding to a bit. */
1340 s->state &= ~data[0];
1341 s->state |= data[0] & data[1];
1342 /* The commands are 8 bits wide */
1343 this_usbduxsub->dux_commands[1] = (s->io_bits) & 0x000000FF;
1344 this_usbduxsub->dux_commands[4] = (s->state) & 0x000000FF;
1345 this_usbduxsub->dux_commands[2] = ((s->io_bits) & 0x0000FF00) >> 8;
1346 this_usbduxsub->dux_commands[5] = ((s->state) & 0x0000FF00) >> 8;
1347 this_usbduxsub->dux_commands[3] = ((s->io_bits) & 0x00FF0000) >> 16;
1348 this_usbduxsub->dux_commands[6] = ((s->state) & 0x00FF0000) >> 16;
1350 /* This command also tells the firmware to return */
1351 /* the digital input lines */
1352 err = send_dux_commands(dev, SENDDIOBITSCOMMAND);
1354 up(&this_usbduxsub->sem);
1357 err = receive_dux_commands(dev, SENDDIOBITSCOMMAND);
1359 up(&this_usbduxsub->sem);
1363 data[1] = (((unsigned int)(this_usbduxsub->insnBuffer[1]))&0xff) |
1364 ((((unsigned int)(this_usbduxsub->insnBuffer[2]))&0xff) << 8) |
1365 ((((unsigned int)(this_usbduxsub->insnBuffer[3]))&0xff) << 16);
1369 up(&this_usbduxsub->sem);
1373 static void usbdux_pwm_stop(struct usbduxsigma_private *devpriv, int do_unlink)
1376 if (devpriv->urbPwm)
1377 usb_kill_urb(devpriv->urbPwm);
1380 devpriv->pwm_cmd_running = 0;
1383 static int usbdux_pwm_cancel(struct comedi_device *dev,
1384 struct comedi_subdevice *s)
1386 struct usbduxsigma_private *devpriv = dev->private;
1388 /* unlink only if it is really running */
1389 usbdux_pwm_stop(devpriv, devpriv->pwm_cmd_running);
1391 return send_dux_commands(dev, SENDPWMOFF);
1394 static void usbduxsub_pwm_irq(struct urb *urb)
1396 struct comedi_device *dev = urb->context;
1397 struct usbduxsigma_private *devpriv = dev->private;
1400 switch (urb->status) {
1409 /* happens after an unlink command */
1410 if (devpriv->pwm_cmd_running)
1411 usbdux_pwm_stop(devpriv, 0); /* w/o unlink */
1416 if (devpriv->pwm_cmd_running) {
1417 dev_err(dev->class_dev,
1418 "%s: non-zero urb status (%d)\n",
1419 __func__, urb->status);
1420 usbdux_pwm_stop(devpriv, 0); /* w/o unlink */
1425 if (!devpriv->pwm_cmd_running)
1428 urb->transfer_buffer_length = devpriv->sizePwmBuf;
1429 urb->dev = comedi_to_usb_dev(dev);
1431 ret = usb_submit_urb(urb, GFP_ATOMIC);
1433 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
1435 if (ret == EL2NSYNC)
1436 dev_err(dev->class_dev,
1437 "buggy USB host controller or bug in IRQ handler\n");
1438 usbdux_pwm_stop(devpriv, 0); /* w/o unlink */
1442 static int usbduxsigma_submit_pwm_urb(struct comedi_device *dev)
1444 struct usb_device *usb = comedi_to_usb_dev(dev);
1445 struct usbduxsigma_private *devpriv = dev->private;
1446 struct urb *urb = devpriv->urbPwm;
1448 /* in case of a resubmission after an unlink... */
1449 usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, PWM_EP),
1450 urb->transfer_buffer, devpriv->sizePwmBuf,
1451 usbduxsub_pwm_irq, dev);
1453 return usb_submit_urb(urb, GFP_ATOMIC);
1456 static int usbdux_pwm_period(struct comedi_device *dev,
1457 struct comedi_subdevice *s, unsigned int period)
1459 struct usbduxsigma_private *this_usbduxsub = dev->private;
1462 if (period < MIN_PWM_PERIOD) {
1463 dev_err(&this_usbduxsub->interface->dev,
1464 "comedi%d: illegal period setting for pwm.\n",
1468 fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
1469 if (fx2delay > 255) {
1470 dev_err(&this_usbduxsub->interface->dev,
1471 "comedi%d: period %d for pwm is too low.\n",
1472 dev->minor, period);
1476 this_usbduxsub->pwmDelay = fx2delay;
1477 this_usbduxsub->pwmPeriod = period;
1481 /* is called from insn so there's no need to do all the sanity checks */
1482 static int usbdux_pwm_start(struct comedi_device *dev,
1483 struct comedi_subdevice *s)
1485 struct usbduxsigma_private *this_usbduxsub = dev->private;
1488 if (this_usbduxsub->pwm_cmd_running) {
1489 /* already running */
1493 this_usbduxsub->dux_commands[1] = ((uint8_t) this_usbduxsub->pwmDelay);
1494 ret = send_dux_commands(dev, SENDPWMON);
1498 /* initialise the buffer */
1499 for (i = 0; i < this_usbduxsub->sizePwmBuf; i++)
1500 ((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0;
1502 ret = usbduxsigma_submit_pwm_urb(dev);
1505 this_usbduxsub->pwm_cmd_running = 1;
1510 /* generates the bit pattern for PWM with the optional sign bit */
1511 static int usbdux_pwm_pattern(struct comedi_device *dev,
1512 struct comedi_subdevice *s, int channel,
1513 unsigned int value, unsigned int sign)
1515 struct usbduxsigma_private *this_usbduxsub = dev->private;
1522 /* this is the DIO bit which carries the PWM data */
1523 pwm_mask = (1 << channel);
1524 /* this is the DIO bit which carries the optional direction bit */
1525 sgn_mask = (16 << channel);
1526 /* this is the buffer which will be filled with the with bit */
1527 /* pattern for one period */
1528 szbuf = this_usbduxsub->sizePwmBuf;
1529 pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer);
1530 for (i = 0; i < szbuf; i++) {
1533 c = c & (~pwm_mask);
1534 /* set the bit as long as the index is lower than the value */
1537 /* set the optional sign bit for a relay */
1539 /* positive value */
1540 c = c & (~sgn_mask);
1542 /* negative value */
1550 static int usbdux_pwm_write(struct comedi_device *dev,
1551 struct comedi_subdevice *s,
1552 struct comedi_insn *insn, unsigned int *data)
1554 if ((insn->n) != 1) {
1556 * doesn't make sense to have more than one value here because
1557 * it would just overwrite the PWM buffer a couple of times
1563 * the sign is set via a special INSN only, this gives us 8 bits for
1565 * relay sign 0 by default
1567 return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
1570 static int usbdux_pwm_read(struct comedi_device *x1,
1571 struct comedi_subdevice *x2, struct comedi_insn *x3,
1578 /* switches on/off PWM */
1579 static int usbdux_pwm_config(struct comedi_device *dev,
1580 struct comedi_subdevice *s,
1581 struct comedi_insn *insn, unsigned int *data)
1583 struct usbduxsigma_private *this_usbduxsub = dev->private;
1585 case INSN_CONFIG_ARM:
1588 * if not zero the PWM is limited to a certain time which is
1589 * not supported here
1593 return usbdux_pwm_start(dev, s);
1594 case INSN_CONFIG_DISARM:
1595 return usbdux_pwm_cancel(dev, s);
1596 case INSN_CONFIG_GET_PWM_STATUS:
1598 * to check if the USB transmission has failed or in case PWM
1599 * was limited to n cycles to check if it has terminated
1601 data[1] = this_usbduxsub->pwm_cmd_running;
1603 case INSN_CONFIG_PWM_SET_PERIOD:
1604 return usbdux_pwm_period(dev, s, data[1]);
1605 case INSN_CONFIG_PWM_GET_PERIOD:
1606 data[1] = this_usbduxsub->pwmPeriod;
1608 case INSN_CONFIG_PWM_SET_H_BRIDGE:
1609 /* value in the first byte and the sign in the second for a
1611 return usbdux_pwm_pattern(dev, s,
1612 /* the channel number */
1613 CR_CHAN(insn->chanspec),
1614 /* actual PWM data */
1618 case INSN_CONFIG_PWM_GET_H_BRIDGE:
1619 /* values are not kept in this driver, nothing to return */
1626 /*****************************************************************/
1628 static void tidy_up(struct usbduxsigma_private *usbduxsub_tmp)
1632 /* shows the usb subsystem that the driver is down */
1633 if (usbduxsub_tmp->interface)
1634 usb_set_intfdata(usbduxsub_tmp->interface, NULL);
1636 if (usbduxsub_tmp->urbIn) {
1637 /* force unlink all urbs */
1638 usbdux_ai_stop(usbduxsub_tmp, 1);
1639 for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
1640 kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer);
1641 usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL;
1642 usb_free_urb(usbduxsub_tmp->urbIn[i]);
1643 usbduxsub_tmp->urbIn[i] = NULL;
1645 kfree(usbduxsub_tmp->urbIn);
1646 usbduxsub_tmp->urbIn = NULL;
1648 if (usbduxsub_tmp->urbOut) {
1649 /* force unlink all urbs */
1650 usbdux_ao_stop(usbduxsub_tmp, 1);
1651 for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
1652 if (usbduxsub_tmp->urbOut[i]->transfer_buffer) {
1653 kfree(usbduxsub_tmp->
1654 urbOut[i]->transfer_buffer);
1655 usbduxsub_tmp->urbOut[i]->transfer_buffer =
1658 if (usbduxsub_tmp->urbOut[i]) {
1659 usb_free_urb(usbduxsub_tmp->urbOut[i]);
1660 usbduxsub_tmp->urbOut[i] = NULL;
1663 kfree(usbduxsub_tmp->urbOut);
1664 usbduxsub_tmp->urbOut = NULL;
1666 if (usbduxsub_tmp->urbPwm) {
1667 /* force unlink urb */
1668 usbdux_pwm_stop(usbduxsub_tmp, 1);
1669 kfree(usbduxsub_tmp->urbPwm->transfer_buffer);
1670 usbduxsub_tmp->urbPwm->transfer_buffer = NULL;
1671 usb_free_urb(usbduxsub_tmp->urbPwm);
1672 usbduxsub_tmp->urbPwm = NULL;
1674 kfree(usbduxsub_tmp->inBuffer);
1675 usbduxsub_tmp->inBuffer = NULL;
1676 kfree(usbduxsub_tmp->insnBuffer);
1677 usbduxsub_tmp->insnBuffer = NULL;
1678 kfree(usbduxsub_tmp->outBuffer);
1679 usbduxsub_tmp->outBuffer = NULL;
1680 kfree(usbduxsub_tmp->dac_commands);
1681 usbduxsub_tmp->dac_commands = NULL;
1682 kfree(usbduxsub_tmp->dux_commands);
1683 usbduxsub_tmp->dux_commands = NULL;
1686 static int usbduxsigma_attach_common(struct comedi_device *dev)
1688 struct usbduxsigma_private *uds = dev->private;
1690 struct comedi_subdevice *s;
1696 /* set number of subdevices */
1697 if (uds->high_speed)
1698 n_subdevs = 4; /* with pwm */
1700 n_subdevs = 3; /* without pwm */
1701 ret = comedi_alloc_subdevices(dev, n_subdevs);
1706 /* the first subdevice is the A/D converter */
1707 s = &dev->subdevices[SUBDEV_AD];
1708 /* the URBs get the comedi subdevice */
1709 /* which is responsible for reading */
1710 /* this is the subdevice which reads data */
1711 dev->read_subdev = s;
1712 /* the subdevice receives as private structure the */
1716 s->type = COMEDI_SUBD_AI;
1717 /* readable and ref is to ground, 32 bit wide data! */
1718 s->subdev_flags = SDF_READABLE | SDF_GROUND |
1719 SDF_CMD_READ | SDF_LSAMPL;
1720 /* 16 A/D channels */
1721 s->n_chan = NUMCHANNELS;
1722 /* length of the channellist */
1723 s->len_chanlist = NUMCHANNELS;
1724 /* callback functions */
1725 s->insn_read = usbdux_ai_insn_read;
1726 s->do_cmdtest = usbdux_ai_cmdtest;
1727 s->do_cmd = usbdux_ai_cmd;
1728 s->cancel = usbdux_ai_cancel;
1729 /* max value from the A/D converter (24bit) */
1730 s->maxdata = 0x00FFFFFF;
1731 /* range table to convert to physical units */
1732 s->range_table = (&range_usbdux_ai_range);
1733 /* analog output subdevice */
1734 s = &dev->subdevices[SUBDEV_DA];
1736 s->type = COMEDI_SUBD_AO;
1737 /* backward pointer */
1738 dev->write_subdev = s;
1739 /* the subdevice receives as private structure the */
1743 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1746 /* length of the channellist */
1747 s->len_chanlist = 4;
1748 /* 8 bit resolution */
1749 s->maxdata = 0x00ff;
1750 /* unipolar range */
1751 s->range_table = &range_unipolar2_5;
1753 s->do_cmdtest = usbdux_ao_cmdtest;
1754 s->do_cmd = usbdux_ao_cmd;
1755 s->cancel = usbdux_ao_cancel;
1756 s->insn_read = usbdux_ao_insn_read;
1757 s->insn_write = usbdux_ao_insn_write;
1758 /* digital I/O subdevice */
1759 s = &dev->subdevices[SUBDEV_DIO];
1760 s->type = COMEDI_SUBD_DIO;
1761 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1762 /* 8 external and 16 internal channels */
1765 s->range_table = (&range_digital);
1766 s->insn_bits = usbdux_dio_insn_bits;
1767 s->insn_config = usbdux_dio_insn_config;
1768 /* we don't use it */
1770 if (uds->high_speed) {
1771 /* timer / pwm subdevice */
1772 s = &dev->subdevices[SUBDEV_PWM];
1773 s->type = COMEDI_SUBD_PWM;
1774 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1776 /* this defines the max duty cycle resolution */
1777 s->maxdata = uds->sizePwmBuf;
1778 s->insn_write = usbdux_pwm_write;
1779 s->insn_read = usbdux_pwm_read;
1780 s->insn_config = usbdux_pwm_config;
1781 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1784 offset = usbdux_getstatusinfo(dev, 0);
1786 dev_err(&uds->interface->dev,
1787 "Communication to USBDUXSIGMA failed! Check firmware and cabling.");
1788 dev_info(&uds->interface->dev,
1789 "comedi%d: attached, ADC_zero = %x\n", dev->minor, offset);
1793 static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev)
1795 struct usb_device *usb = comedi_to_usb_dev(dev);
1796 struct usbduxsigma_private *devpriv = dev->private;
1800 devpriv->dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
1801 devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1802 devpriv->inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1803 devpriv->insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1804 devpriv->outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1805 devpriv->urbIn = kcalloc(devpriv->numOfInBuffers, sizeof(*urb),
1807 devpriv->urbOut = kcalloc(devpriv->numOfOutBuffers, sizeof(*urb),
1809 if (!devpriv->dac_commands || !devpriv->dux_commands ||
1810 !devpriv->inBuffer || !devpriv->insnBuffer ||
1811 !devpriv->outBuffer || !devpriv->urbIn || !devpriv->urbOut)
1814 for (i = 0; i < devpriv->numOfInBuffers; i++) {
1815 /* one frame: 1ms */
1816 urb = usb_alloc_urb(1, GFP_KERNEL);
1819 devpriv->urbIn[i] = urb;
1821 /* will be filled later with a pointer to the comedi-device */
1822 /* and ONLY then the urb should be submitted */
1823 urb->context = NULL;
1824 urb->pipe = usb_rcvisocpipe(usb, ISOINEP);
1825 urb->transfer_flags = URB_ISO_ASAP;
1826 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1827 if (!urb->transfer_buffer)
1829 urb->complete = usbduxsub_ai_IsocIrq;
1830 urb->number_of_packets = 1;
1831 urb->transfer_buffer_length = SIZEINBUF;
1832 urb->iso_frame_desc[0].offset = 0;
1833 urb->iso_frame_desc[0].length = SIZEINBUF;
1836 for (i = 0; i < devpriv->numOfOutBuffers; i++) {
1837 /* one frame: 1ms */
1838 urb = usb_alloc_urb(1, GFP_KERNEL);
1841 devpriv->urbOut[i] = urb;
1843 /* will be filled later with a pointer to the comedi-device */
1844 /* and ONLY then the urb should be submitted */
1845 urb->context = NULL;
1846 urb->pipe = usb_sndisocpipe(usb, ISOOUTEP);
1847 urb->transfer_flags = URB_ISO_ASAP;
1848 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1849 if (!urb->transfer_buffer)
1851 urb->complete = usbduxsub_ao_IsocIrq;
1852 urb->number_of_packets = 1;
1853 urb->transfer_buffer_length = SIZEOUTBUF;
1854 urb->iso_frame_desc[0].offset = 0;
1855 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1856 if (devpriv->high_speed)
1857 urb->interval = 8; /* uframes */
1859 urb->interval = 1; /* frames */
1862 if (devpriv->high_speed) {
1863 /* max bulk ep size in high speed */
1864 devpriv->sizePwmBuf = 512;
1865 urb = usb_alloc_urb(0, GFP_KERNEL);
1868 devpriv->urbPwm = urb;
1869 urb->transfer_buffer = kzalloc(devpriv->sizePwmBuf, GFP_KERNEL);
1870 if (!urb->transfer_buffer)
1873 devpriv->urbPwm = NULL;
1874 devpriv->sizePwmBuf = 0;
1880 static int usbduxsigma_auto_attach(struct comedi_device *dev,
1881 unsigned long context_unused)
1883 struct usb_interface *intf = comedi_to_usb_interface(dev);
1884 struct usb_device *usb = comedi_to_usb_dev(dev);
1885 struct usbduxsigma_private *devpriv;
1888 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1891 dev->private = devpriv;
1893 sema_init(&devpriv->sem, 1);
1894 devpriv->interface = intf;
1895 usb_set_intfdata(intf, devpriv);
1897 ret = usb_set_interface(usb,
1898 intf->altsetting->desc.bInterfaceNumber, 3);
1900 dev_err(dev->class_dev,
1901 "could not set alternate setting 3 in high speed\n");
1905 /* test if it is high speed (USB 2.0) */
1906 devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1907 if (devpriv->high_speed) {
1908 devpriv->numOfInBuffers = NUMOFINBUFFERSHIGH;
1909 devpriv->numOfOutBuffers = NUMOFOUTBUFFERSHIGH;
1911 devpriv->numOfInBuffers = NUMOFINBUFFERSFULL;
1912 devpriv->numOfOutBuffers = NUMOFOUTBUFFERSFULL;
1915 ret = usbduxsigma_alloc_usb_buffers(dev);
1921 ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1922 usbduxsigma_firmware_upload, 0);
1926 return usbduxsigma_attach_common(dev);
1929 static void usbduxsigma_detach(struct comedi_device *dev)
1931 struct usbduxsigma_private *devpriv = dev->private;
1936 /* stop any running commands */
1937 usbdux_ai_stop(devpriv, devpriv->ai_cmd_running);
1938 usbdux_ao_stop(devpriv, devpriv->ao_cmd_running);
1940 down(&devpriv->sem);
1945 static struct comedi_driver usbduxsigma_driver = {
1946 .driver_name = "usbduxsigma",
1947 .module = THIS_MODULE,
1948 .auto_attach = usbduxsigma_auto_attach,
1949 .detach = usbduxsigma_detach,
1952 static int usbduxsigma_usb_probe(struct usb_interface *intf,
1953 const struct usb_device_id *id)
1955 return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0);;
1958 static const struct usb_device_id usbduxsigma_usb_table[] = {
1959 { USB_DEVICE(0x13d8, 0x0020) },
1960 { USB_DEVICE(0x13d8, 0x0021) },
1961 { USB_DEVICE(0x13d8, 0x0022) },
1964 MODULE_DEVICE_TABLE(usb, usbduxsigma_usb_table);
1966 static struct usb_driver usbduxsigma_usb_driver = {
1967 .name = "usbduxsigma",
1968 .probe = usbduxsigma_usb_probe,
1969 .disconnect = comedi_usb_auto_unconfig,
1970 .id_table = usbduxsigma_usb_table,
1972 module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver);
1974 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1975 MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com");
1976 MODULE_LICENSE("GPL");
1977 MODULE_FIRMWARE(FIRMWARE);