Merge branch 'for-3.11' of git://linux-nfs.org/~bfields/linux
[linux-2.6.git] / drivers / staging / comedi / drivers / usbduxsigma.c
blob898c3c4504066c31af6a44ec87f37b7bfc484aa0
1 /*
2 * usbduxsigma.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 * Driver: usbduxsigma
18 * Description: University of Stirling USB DAQ & INCITE Technology Limited
19 * Devices: (ITL) USB-DUX [usbduxsigma]
20 * Author: Bernd Porr <BerndPorr@f2s.com>
21 * Updated: 8 Nov 2011
22 * Status: testing
26 * I must give credit here to Chris Baugher who
27 * wrote the driver for AT-MIO-16d. I used some parts of this
28 * driver. I also must give credits to David Brownell
29 * who supported me with the USB development.
31 * Note: the raw data from the A/D converter is 24 bit big endian
32 * anything else is little endian to/from the dux board
35 * Revision history:
36 * 0.1: initial version
37 * 0.2: all basic functions implemented, digital I/O only for one port
38 * 0.3: proper vendor ID and driver name
39 * 0.4: fixed D/A voltage range
40 * 0.5: various bug fixes, health check at startup
41 * 0.6: corrected wrong input range
44 #include <linux/kernel.h>
45 #include <linux/module.h>
46 #include <linux/init.h>
47 #include <linux/slab.h>
48 #include <linux/input.h>
49 #include <linux/usb.h>
50 #include <linux/fcntl.h>
51 #include <linux/compiler.h>
53 #include "comedi_fc.h"
54 #include "../comedidev.h"
56 /* timeout for the USB-transfer in ms*/
57 #define BULK_TIMEOUT 1000
59 /* constants for "firmware" upload and download */
60 #define FIRMWARE "usbduxsigma_firmware.bin"
61 #define FIRMWARE_MAX_LEN 0x4000
62 #define USBDUXSUB_FIRMWARE 0xa0
63 #define VENDOR_DIR_IN 0xc0
64 #define VENDOR_DIR_OUT 0x40
66 /* internal addresses of the 8051 processor */
67 #define USBDUXSUB_CPUCS 0xE600
69 /* USB endpoints */
70 #define USBDUXSIGMA_CMD_OUT_EP 1 /* command output */
71 #define USBDUXSIGMA_ISO_OUT_EP 2 /* analog output ISO/IRQ */
72 #define USBDUXSIGMA_PWM_OUT_EP 4 /* pwm output */
73 #define USBDUXSIGMA_ISO_IN_EP 6 /* analog input ISO/IRQ */
74 #define USBDUXSIGMA_CMD_IN_EP 8 /* command input */
76 /* 300Hz max frequ under PWM */
77 #define MIN_PWM_PERIOD ((long)(1E9/300))
79 /* Default PWM frequency */
80 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
82 /* Number of channels (16 AD and offset)*/
83 #define NUMCHANNELS 16
85 #define USBDUXSIGMA_NUM_AO_CHAN 4
87 /* Size of one A/D value */
88 #define SIZEADIN ((sizeof(int32_t)))
91 * Size of the async input-buffer IN BYTES, the DIO state is transmitted
92 * as the first byte.
94 #define SIZEINBUF (((NUMCHANNELS+1)*SIZEADIN))
96 /* 16 bytes. */
97 #define SIZEINSNBUF 16
99 /* Number of DA channels */
100 #define NUMOUTCHANNELS 8
102 /* size of one value for the D/A converter: channel and value */
103 #define SIZEDAOUT ((sizeof(uint8_t)+sizeof(int16_t)))
106 * Size of the output-buffer in bytes
107 * Actually only the first 4 triplets are used but for the
108 * high speed mode we need to pad it to 8 (microframes).
110 #define SIZEOUTBUF ((8*SIZEDAOUT))
113 * Size of the buffer for the dux commands: just now max size is determined
114 * by the analogue out + command byte + panic bytes...
116 #define SIZEOFDUXBUFFER ((8*SIZEDAOUT+2))
118 /* Number of in-URBs which receive the data: min=2 */
119 #define NUMOFINBUFFERSFULL 5
121 /* Number of out-URBs which send the data: min=2 */
122 #define NUMOFOUTBUFFERSFULL 5
124 /* Number of in-URBs which receive the data: min=5 */
125 /* must have more buffers due to buggy USB ctr */
126 #define NUMOFINBUFFERSHIGH 10
128 /* Number of out-URBs which send the data: min=5 */
129 /* must have more buffers due to buggy USB ctr */
130 #define NUMOFOUTBUFFERSHIGH 10
132 /* number of retries to get the right dux command */
133 #define RETRIES 10
135 /* bulk transfer commands to usbduxsigma */
136 #define USBBUXSIGMA_AD_CMD 0
137 #define USBDUXSIGMA_DA_CMD 1
138 #define USBDUXSIGMA_DIO_CFG_CMD 2
139 #define USBDUXSIGMA_DIO_BITS_CMD 3
140 #define USBDUXSIGMA_SINGLE_AD_CMD 4
141 #define USBDUXSIGMA_PWM_ON_CMD 7
142 #define USBDUXSIGMA_PWM_OFF_CMD 8
144 static const struct comedi_lrange usbduxsigma_ai_range = {
145 1, {
146 BIP_RANGE(2.65 / 2.0)
150 struct usbduxsigma_private {
151 /* actual number of in-buffers */
152 int n_ai_urbs;
153 /* actual number of out-buffers */
154 int n_ao_urbs;
155 /* ISO-transfer handling: buffers */
156 struct urb **ai_urbs;
157 struct urb **ao_urbs;
158 /* pwm-transfer handling */
159 struct urb *pwm_urb;
160 /* PWM period */
161 unsigned int pwm_period;
162 /* PWM internal delay for the GPIF in the FX2 */
163 uint8_t pwm_delay;
164 /* size of the PWM buffer which holds the bit pattern */
165 int pwm_buf_sz;
166 /* input buffer for the ISO-transfer */
167 int32_t *in_buf;
168 /* input buffer for single insn */
169 int8_t *insn_buf;
171 unsigned int ao_readback[USBDUXSIGMA_NUM_AO_CHAN];
173 unsigned high_speed:1;
174 unsigned ai_cmd_running:1;
175 unsigned ai_continuous:1;
176 unsigned ao_cmd_running:1;
177 unsigned ao_continuous:1;
178 unsigned pwm_cmd_running:1;
180 /* number of samples to acquire */
181 int ai_sample_count;
182 int ao_sample_count;
183 /* time between samples in units of the timer */
184 unsigned int ai_timer;
185 unsigned int ao_timer;
186 /* counter between acquisitions */
187 unsigned int ai_counter;
188 unsigned int ao_counter;
189 /* interval in frames/uframes */
190 unsigned int ai_interval;
191 /* D/A commands */
192 uint8_t *dac_commands;
193 /* commands */
194 uint8_t *dux_commands;
195 struct semaphore sem;
198 static void usbduxsigma_ai_stop(struct comedi_device *dev, int do_unlink)
200 struct usbduxsigma_private *devpriv = dev->private;
202 if (do_unlink) {
203 int i;
205 for (i = 0; i < devpriv->n_ai_urbs; i++) {
206 if (devpriv->ai_urbs[i])
207 usb_kill_urb(devpriv->ai_urbs[i]);
211 devpriv->ai_cmd_running = 0;
214 static int usbduxsigma_ai_cancel(struct comedi_device *dev,
215 struct comedi_subdevice *s)
217 struct usbduxsigma_private *devpriv = dev->private;
219 down(&devpriv->sem);
220 /* unlink only if it is really running */
221 usbduxsigma_ai_stop(dev, devpriv->ai_cmd_running);
222 up(&devpriv->sem);
224 return 0;
227 static void usbduxsigma_ai_urb_complete(struct urb *urb)
229 struct comedi_device *dev = urb->context;
230 struct usbduxsigma_private *devpriv = dev->private;
231 struct comedi_subdevice *s = dev->read_subdev;
232 unsigned int dio_state;
233 int32_t val;
234 int ret;
235 int i;
237 /* first we test if something unusual has just happened */
238 switch (urb->status) {
239 case 0:
240 /* copy the result in the transfer buffer */
241 memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF);
242 break;
243 case -EILSEQ:
245 * error in the ISOchronous data
246 * we don't copy the data into the transfer buffer
247 * and recycle the last data byte
249 dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
251 break;
253 case -ECONNRESET:
254 case -ENOENT:
255 case -ESHUTDOWN:
256 case -ECONNABORTED:
257 /* happens after an unlink command */
258 if (devpriv->ai_cmd_running) {
259 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
260 /* we are still running a command, tell comedi */
261 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
262 comedi_event(dev, s);
264 return;
266 default:
268 * a real error on the bus
269 * pass error to comedi if we are really running a command
271 if (devpriv->ai_cmd_running) {
272 dev_err(dev->class_dev,
273 "%s: non-zero urb status (%d)\n",
274 __func__, urb->status);
275 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
276 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
277 comedi_event(dev, s);
279 return;
282 if (unlikely(!devpriv->ai_cmd_running))
283 return;
285 urb->dev = comedi_to_usb_dev(dev);
287 ret = usb_submit_urb(urb, GFP_ATOMIC);
288 if (unlikely(ret < 0)) {
289 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
290 __func__, ret);
291 if (ret == -EL2NSYNC)
292 dev_err(dev->class_dev,
293 "buggy USB host controller or bug in IRQ handler\n");
294 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
295 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
296 comedi_event(dev, s);
297 return;
300 /* get the state of the dio pins to allow external trigger */
301 dio_state = be32_to_cpu(devpriv->in_buf[0]);
303 devpriv->ai_counter--;
304 if (likely(devpriv->ai_counter > 0))
305 return;
307 /* timer zero, transfer measurements to comedi */
308 devpriv->ai_counter = devpriv->ai_timer;
310 if (!devpriv->ai_continuous) {
311 /* not continuous, fixed number of samples */
312 devpriv->ai_sample_count--;
313 if (devpriv->ai_sample_count < 0) {
314 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
315 /* acquistion is over, tell comedi */
316 s->async->events |= COMEDI_CB_EOA;
317 comedi_event(dev, s);
318 return;
322 /* get the data from the USB bus and hand it over to comedi */
323 for (i = 0; i < s->async->cmd.chanlist_len; i++) {
324 /* transfer data, note first byte is the DIO state */
325 val = be32_to_cpu(devpriv->in_buf[i+1]);
326 val &= 0x00ffffff; /* strip status byte */
327 val ^= 0x00800000; /* convert to unsigned */
329 ret = cfc_write_array_to_buffer(s, &val, sizeof(uint32_t));
330 if (unlikely(ret == 0)) {
331 /* buffer overflow */
332 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
333 return;
336 /* tell comedi that data is there */
337 s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
338 comedi_event(dev, s);
341 static void usbduxsigma_ao_stop(struct comedi_device *dev, int do_unlink)
343 struct usbduxsigma_private *devpriv = dev->private;
345 if (do_unlink) {
346 int i;
348 for (i = 0; i < devpriv->n_ao_urbs; i++) {
349 if (devpriv->ao_urbs[i])
350 usb_kill_urb(devpriv->ao_urbs[i]);
354 devpriv->ao_cmd_running = 0;
357 static int usbduxsigma_ao_cancel(struct comedi_device *dev,
358 struct comedi_subdevice *s)
360 struct usbduxsigma_private *devpriv = dev->private;
362 down(&devpriv->sem);
363 /* unlink only if it is really running */
364 usbduxsigma_ao_stop(dev, devpriv->ao_cmd_running);
365 up(&devpriv->sem);
367 return 0;
370 static void usbduxsigma_ao_urb_complete(struct urb *urb)
372 struct comedi_device *dev = urb->context;
373 struct usbduxsigma_private *devpriv = dev->private;
374 struct comedi_subdevice *s = dev->write_subdev;
375 uint8_t *datap;
376 int len;
377 int ret;
378 int i;
380 switch (urb->status) {
381 case 0:
382 /* success */
383 break;
385 case -ECONNRESET:
386 case -ENOENT:
387 case -ESHUTDOWN:
388 case -ECONNABORTED:
389 /* happens after an unlink command */
390 if (devpriv->ao_cmd_running) {
391 usbduxsigma_ao_stop(dev, 0); /* w/o unlink */
392 s->async->events |= COMEDI_CB_EOA;
393 comedi_event(dev, s);
395 return;
397 default:
398 /* a real error */
399 if (devpriv->ao_cmd_running) {
400 dev_err(dev->class_dev,
401 "%s: non-zero urb status (%d)\n",
402 __func__, urb->status);
403 usbduxsigma_ao_stop(dev, 0); /* w/o unlink */
404 s->async->events |= (COMEDI_CB_ERROR | COMEDI_CB_EOA);
405 comedi_event(dev, s);
407 return;
410 if (!devpriv->ao_cmd_running)
411 return;
413 devpriv->ao_counter--;
414 if ((int)devpriv->ao_counter <= 0) {
415 /* timer zero, transfer from comedi */
416 devpriv->ao_counter = devpriv->ao_timer;
418 if (!devpriv->ao_continuous) {
419 /* not continuous, fixed number of samples */
420 devpriv->ao_sample_count--;
421 if (devpriv->ao_sample_count < 0) {
422 usbduxsigma_ao_stop(dev, 0); /* w/o unlink */
423 /* acquistion is over, tell comedi */
424 s->async->events |= COMEDI_CB_EOA;
425 comedi_event(dev, s);
426 return;
430 /* transmit data to the USB bus */
431 datap = urb->transfer_buffer;
432 len = s->async->cmd.chanlist_len;
433 *datap++ = len;
434 for (i = 0; i < len; i++) {
435 unsigned int chan = devpriv->dac_commands[i];
436 short val;
438 ret = comedi_buf_get(s->async, &val);
439 if (ret < 0) {
440 dev_err(dev->class_dev, "buffer underflow\n");
441 s->async->events |= (COMEDI_CB_EOA |
442 COMEDI_CB_OVERFLOW);
444 *datap++ = val;
445 *datap++ = chan;
446 devpriv->ao_readback[chan] = val;
448 s->async->events |= COMEDI_CB_BLOCK;
449 comedi_event(dev, s);
453 urb->transfer_buffer_length = SIZEOUTBUF;
454 urb->dev = comedi_to_usb_dev(dev);
455 urb->status = 0;
456 if (devpriv->high_speed)
457 urb->interval = 8; /* uframes */
458 else
459 urb->interval = 1; /* frames */
460 urb->number_of_packets = 1;
461 urb->iso_frame_desc[0].offset = 0;
462 urb->iso_frame_desc[0].length = SIZEOUTBUF;
463 urb->iso_frame_desc[0].status = 0;
464 ret = usb_submit_urb(urb, GFP_ATOMIC);
465 if (ret < 0) {
466 dev_err(dev->class_dev,
467 "%s: urb resubmit failed (%d)\n",
468 __func__, ret);
469 if (ret == EL2NSYNC)
470 dev_err(dev->class_dev,
471 "buggy USB host controller or bug in IRQ handler\n");
472 usbduxsigma_ao_stop(dev, 0); /* w/o unlink */
473 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
474 comedi_event(dev, s);
478 static int usbduxsigma_submit_urbs(struct comedi_device *dev,
479 struct urb **urbs, int num_urbs,
480 int input_urb)
482 struct usb_device *usb = comedi_to_usb_dev(dev);
483 struct usbduxsigma_private *devpriv = dev->private;
484 struct urb *urb;
485 int ret;
486 int i;
488 /* Submit all URBs and start the transfer on the bus */
489 for (i = 0; i < num_urbs; i++) {
490 urb = urbs[i];
492 /* in case of a resubmission after an unlink... */
493 if (input_urb)
494 urb->interval = devpriv->ai_interval;
495 urb->context = dev;
496 urb->dev = usb;
497 urb->status = 0;
498 urb->transfer_flags = URB_ISO_ASAP;
500 ret = usb_submit_urb(urb, GFP_ATOMIC);
501 if (ret)
502 return ret;
504 return 0;
507 static int usbduxsigma_chans_to_interval(int num_chan)
509 if (num_chan <= 2)
510 return 2; /* 4kHz */
511 if (num_chan <= 8)
512 return 4; /* 2kHz */
513 return 8; /* 1kHz */
516 static int usbduxsigma_ai_cmdtest(struct comedi_device *dev,
517 struct comedi_subdevice *s,
518 struct comedi_cmd *cmd)
520 struct usbduxsigma_private *devpriv = dev->private;
521 int high_speed = devpriv->high_speed;
522 int interval = usbduxsigma_chans_to_interval(cmd->chanlist_len);
523 int err = 0;
525 /* Step 1 : check if triggers are trivially valid */
527 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
528 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
529 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
530 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
531 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
533 if (err)
534 return 1;
536 /* Step 2a : make sure trigger sources are unique */
538 err |= cfc_check_trigger_is_unique(cmd->start_src);
539 err |= cfc_check_trigger_is_unique(cmd->stop_src);
541 /* Step 2b : and mutually compatible */
543 if (err)
544 return 2;
546 /* Step 3: check if arguments are trivially valid */
548 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
550 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
551 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
553 if (cmd->scan_begin_src == TRIG_TIMER) {
554 unsigned int tmp;
556 if (high_speed) {
558 * In high speed mode microframes are possible.
559 * However, during one microframe we can roughly
560 * sample two channels. Thus, the more channels
561 * are in the channel list the more time we need.
563 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
564 (1000000 / 8 * interval));
566 tmp = (cmd->scan_begin_arg / 125000) * 125000;
567 } else {
568 /* full speed */
569 /* 1kHz scans every USB frame */
570 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
571 1000000);
573 tmp = (cmd->scan_begin_arg / 1000000) * 1000000;
575 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, tmp);
578 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
580 if (cmd->stop_src == TRIG_COUNT) {
581 /* any count is allowed */
582 } else {
583 /* TRIG_NONE */
584 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
587 if (err)
588 return 3;
590 /* Step 4: fix up any arguments */
592 if (high_speed) {
594 * every 2 channels get a time window of 125us. Thus, if we
595 * sample all 16 channels we need 1ms. If we sample only one
596 * channel we need only 125us
598 devpriv->ai_interval = interval;
599 devpriv->ai_timer = cmd->scan_begin_arg / (125000 * interval);
600 } else {
601 /* interval always 1ms */
602 devpriv->ai_interval = 1;
603 devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
605 if (devpriv->ai_timer < 1)
606 err |= -EINVAL;
608 if (cmd->stop_src == TRIG_COUNT) {
609 /* data arrives as one packet */
610 devpriv->ai_sample_count = cmd->stop_arg;
611 devpriv->ai_continuous = 0;
612 } else {
613 /* continuous acquisition */
614 devpriv->ai_continuous = 1;
615 devpriv->ai_sample_count = 0;
618 if (err)
619 return 4;
621 return 0;
625 * creates the ADC command for the MAX1271
626 * range is the range value from comedi
628 static void create_adc_command(unsigned int chan,
629 uint8_t *muxsg0,
630 uint8_t *muxsg1)
632 if (chan < 8)
633 (*muxsg0) = (*muxsg0) | (1 << chan);
634 else if (chan < 16)
635 (*muxsg1) = (*muxsg1) | (1 << (chan-8));
638 static int usbbuxsigma_send_cmd(struct comedi_device *dev, int cmd_type)
640 struct usb_device *usb = comedi_to_usb_dev(dev);
641 struct usbduxsigma_private *devpriv = dev->private;
642 int nsent;
644 devpriv->dux_commands[0] = cmd_type;
646 return usb_bulk_msg(usb, usb_sndbulkpipe(usb, USBDUXSIGMA_CMD_OUT_EP),
647 devpriv->dux_commands, SIZEOFDUXBUFFER,
648 &nsent, BULK_TIMEOUT);
651 static int usbduxsigma_receive_cmd(struct comedi_device *dev, int command)
653 struct usb_device *usb = comedi_to_usb_dev(dev);
654 struct usbduxsigma_private *devpriv = dev->private;
655 int nrec;
656 int ret;
657 int i;
659 for (i = 0; i < RETRIES; i++) {
660 ret = usb_bulk_msg(usb,
661 usb_rcvbulkpipe(usb, USBDUXSIGMA_CMD_IN_EP),
662 devpriv->insn_buf, SIZEINSNBUF,
663 &nrec, BULK_TIMEOUT);
664 if (ret < 0)
665 return ret;
667 if (devpriv->insn_buf[0] == command)
668 return 0;
671 * This is only reached if the data has been requested a
672 * couple of times and the command was not received.
674 return -EFAULT;
677 static int usbduxsigma_ai_inttrig(struct comedi_device *dev,
678 struct comedi_subdevice *s,
679 unsigned int trignum)
681 struct usbduxsigma_private *devpriv = dev->private;
682 int ret;
684 if (trignum != 0)
685 return -EINVAL;
687 down(&devpriv->sem);
688 if (!devpriv->ai_cmd_running) {
689 ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
690 devpriv->n_ai_urbs, 1);
691 if (ret < 0) {
692 up(&devpriv->sem);
693 return ret;
695 devpriv->ai_cmd_running = 1;
696 s->async->inttrig = NULL;
698 up(&devpriv->sem);
700 return 1;
703 static int usbduxsigma_ai_cmd(struct comedi_device *dev,
704 struct comedi_subdevice *s)
706 struct usbduxsigma_private *devpriv = dev->private;
707 struct comedi_cmd *cmd = &s->async->cmd;
708 unsigned int len = cmd->chanlist_len;
709 uint8_t muxsg0 = 0;
710 uint8_t muxsg1 = 0;
711 uint8_t sysred = 0;
712 int ret;
713 int i;
715 down(&devpriv->sem);
717 /* set current channel of the running acquisition to zero */
718 s->async->cur_chan = 0;
719 for (i = 0; i < len; i++) {
720 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
722 create_adc_command(chan, &muxsg0, &muxsg1);
725 devpriv->dux_commands[1] = len; /* num channels per time step */
726 devpriv->dux_commands[2] = 0x12; /* CONFIG0 */
727 devpriv->dux_commands[3] = 0x03; /* CONFIG1: 23kHz sample, delay 0us */
728 devpriv->dux_commands[4] = 0x00; /* CONFIG3: diff. channels off */
729 devpriv->dux_commands[5] = muxsg0;
730 devpriv->dux_commands[6] = muxsg1;
731 devpriv->dux_commands[7] = sysred;
733 ret = usbbuxsigma_send_cmd(dev, USBBUXSIGMA_AD_CMD);
734 if (ret < 0) {
735 up(&devpriv->sem);
736 return ret;
739 devpriv->ai_counter = devpriv->ai_timer;
741 if (cmd->start_src == TRIG_NOW) {
742 /* enable this acquisition operation */
743 ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
744 devpriv->n_ai_urbs, 1);
745 if (ret < 0) {
746 up(&devpriv->sem);
747 return ret;
749 s->async->inttrig = NULL;
750 devpriv->ai_cmd_running = 1;
751 } else { /* TRIG_INT */
752 /* wait for an internal signal and submit the urbs later */
753 s->async->inttrig = usbduxsigma_ai_inttrig;
756 up(&devpriv->sem);
758 return 0;
761 static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
762 struct comedi_subdevice *s,
763 struct comedi_insn *insn,
764 unsigned int *data)
766 struct usbduxsigma_private *devpriv = dev->private;
767 unsigned int chan = CR_CHAN(insn->chanspec);
768 uint8_t muxsg0 = 0;
769 uint8_t muxsg1 = 0;
770 uint8_t sysred = 0;
771 int ret;
772 int i;
774 down(&devpriv->sem);
775 if (devpriv->ai_cmd_running) {
776 up(&devpriv->sem);
777 return -EBUSY;
780 create_adc_command(chan, &muxsg0, &muxsg1);
782 /* Mode 0 is used to get a single conversion on demand */
783 devpriv->dux_commands[1] = 0x16; /* CONFIG0: chopper on */
784 devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
785 devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
786 devpriv->dux_commands[4] = muxsg0;
787 devpriv->dux_commands[5] = muxsg1;
788 devpriv->dux_commands[6] = sysred;
790 /* adc commands */
791 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
792 if (ret < 0) {
793 up(&devpriv->sem);
794 return ret;
797 for (i = 0; i < insn->n; i++) {
798 int32_t val;
800 ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
801 if (ret < 0) {
802 up(&devpriv->sem);
803 return ret;
806 /* 32 bits big endian from the A/D converter */
807 val = be32_to_cpu(*((int32_t *)((devpriv->insn_buf) + 1)));
808 val &= 0x00ffffff; /* strip status byte */
809 val ^= 0x00800000; /* convert to unsigned */
811 data[i] = val;
813 up(&devpriv->sem);
815 return insn->n;
818 static int usbduxsigma_ao_insn_read(struct comedi_device *dev,
819 struct comedi_subdevice *s,
820 struct comedi_insn *insn,
821 unsigned int *data)
823 struct usbduxsigma_private *devpriv = dev->private;
824 unsigned int chan = CR_CHAN(insn->chanspec);
825 int i;
827 down(&devpriv->sem);
828 for (i = 0; i < insn->n; i++)
829 data[i] = devpriv->ao_readback[chan];
830 up(&devpriv->sem);
832 return insn->n;
835 static int usbduxsigma_ao_insn_write(struct comedi_device *dev,
836 struct comedi_subdevice *s,
837 struct comedi_insn *insn,
838 unsigned int *data)
840 struct usbduxsigma_private *devpriv = dev->private;
841 unsigned int chan = CR_CHAN(insn->chanspec);
842 int ret;
843 int i;
845 down(&devpriv->sem);
846 if (devpriv->ao_cmd_running) {
847 up(&devpriv->sem);
848 return -EBUSY;
851 for (i = 0; i < insn->n; i++) {
852 devpriv->dux_commands[1] = 1; /* num channels */
853 devpriv->dux_commands[2] = data[i]; /* value */
854 devpriv->dux_commands[3] = chan; /* channel number */
855 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DA_CMD);
856 if (ret < 0) {
857 up(&devpriv->sem);
858 return ret;
860 devpriv->ao_readback[chan] = data[i];
862 up(&devpriv->sem);
864 return insn->n;
867 static int usbduxsigma_ao_inttrig(struct comedi_device *dev,
868 struct comedi_subdevice *s,
869 unsigned int trignum)
871 struct usbduxsigma_private *devpriv = dev->private;
872 int ret;
874 if (trignum != 0)
875 return -EINVAL;
877 down(&devpriv->sem);
878 if (!devpriv->ao_cmd_running) {
879 ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
880 devpriv->n_ao_urbs, 0);
881 if (ret < 0) {
882 up(&devpriv->sem);
883 return ret;
885 devpriv->ao_cmd_running = 1;
886 s->async->inttrig = NULL;
888 up(&devpriv->sem);
890 return 1;
893 static int usbduxsigma_ao_cmdtest(struct comedi_device *dev,
894 struct comedi_subdevice *s,
895 struct comedi_cmd *cmd)
897 struct usbduxsigma_private *devpriv = dev->private;
898 int err = 0;
899 int high_speed;
900 unsigned int flags;
902 /* high speed conversions are not used yet */
903 high_speed = 0; /* (devpriv->high_speed) */
905 /* Step 1 : check if triggers are trivially valid */
907 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
909 if (high_speed) {
911 * start immediately a new scan
912 * the sampling rate is set by the coversion rate
914 flags = TRIG_FOLLOW;
915 } else {
916 /* start a new scan (output at once) with a timer */
917 flags = TRIG_TIMER;
919 err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
921 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
922 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
923 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
925 if (err) {
926 up(&devpriv->sem);
927 return 1;
930 /* Step 2a : make sure trigger sources are unique */
932 err |= cfc_check_trigger_is_unique(cmd->start_src);
933 err |= cfc_check_trigger_is_unique(cmd->stop_src);
935 /* Step 2b : and mutually compatible */
937 if (err)
938 return 2;
940 /* Step 3: check if arguments are trivially valid */
942 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
944 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
945 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
947 if (cmd->scan_begin_src == TRIG_TIMER)
948 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
949 1000000);
951 /* not used now, is for later use */
952 if (cmd->convert_src == TRIG_TIMER)
953 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
955 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
957 if (cmd->stop_src == TRIG_COUNT) {
958 /* any count is allowed */
959 } else {
960 /* TRIG_NONE */
961 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
964 if (err)
965 return 3;
967 /* Step 4: fix up any arguments */
969 /* we count in timer steps */
970 if (high_speed) {
971 /* timing of the conversion itself: every 125 us */
972 devpriv->ao_timer = cmd->convert_arg / 125000;
973 } else {
975 * timing of the scan: every 1ms
976 * we get all channels at once
978 devpriv->ao_timer = cmd->scan_begin_arg / 1000000;
980 if (devpriv->ao_timer < 1)
981 err |= -EINVAL;
983 if (cmd->stop_src == TRIG_COUNT) {
984 /* not continuous, use counter */
985 if (high_speed) {
986 /* high speed also scans everything at once */
987 devpriv->ao_sample_count = cmd->stop_arg *
988 cmd->scan_end_arg;
989 } else {
991 * There's no scan as the scan has been
992 * handled inside the FX2. Data arrives as
993 * one packet.
995 devpriv->ao_sample_count = cmd->stop_arg;
997 devpriv->ao_continuous = 0;
998 } else {
999 /* continuous acquisition */
1000 devpriv->ao_continuous = 1;
1001 devpriv->ao_sample_count = 0;
1004 if (err)
1005 return 4;
1007 return 0;
1010 static int usbduxsigma_ao_cmd(struct comedi_device *dev,
1011 struct comedi_subdevice *s)
1013 struct usbduxsigma_private *devpriv = dev->private;
1014 struct comedi_cmd *cmd = &s->async->cmd;
1015 int ret;
1016 int i;
1018 down(&devpriv->sem);
1020 /* set current channel of the running acquisition to zero */
1021 s->async->cur_chan = 0;
1022 for (i = 0; i < cmd->chanlist_len; ++i)
1023 devpriv->dac_commands[i] = CR_CHAN(cmd->chanlist[i]);
1025 devpriv->ao_counter = devpriv->ao_timer;
1027 if (cmd->start_src == TRIG_NOW) {
1028 /* enable this acquisition operation */
1029 ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
1030 devpriv->n_ao_urbs, 0);
1031 if (ret < 0) {
1032 up(&devpriv->sem);
1033 return ret;
1035 s->async->inttrig = NULL;
1036 devpriv->ao_cmd_running = 1;
1037 } else { /* TRIG_INT */
1038 /* wait for an internal signal and submit the urbs later */
1039 s->async->inttrig = usbduxsigma_ao_inttrig;
1042 up(&devpriv->sem);
1044 return 0;
1047 static int usbduxsigma_dio_insn_config(struct comedi_device *dev,
1048 struct comedi_subdevice *s,
1049 struct comedi_insn *insn,
1050 unsigned int *data)
1052 unsigned int chan = CR_CHAN(insn->chanspec);
1053 unsigned int mask = 1 << chan;
1055 switch (data[0]) {
1056 case INSN_CONFIG_DIO_OUTPUT:
1057 s->io_bits |= mask;
1058 break;
1059 case INSN_CONFIG_DIO_INPUT:
1060 s->io_bits &= ~mask;
1061 break;
1062 case INSN_CONFIG_DIO_QUERY:
1063 data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
1064 break;
1065 default:
1066 return -EINVAL;
1067 break;
1071 * We don't tell the firmware here as it would take 8 frames
1072 * to submit the information. We do it in the (*insn_bits).
1074 return insn->n;
1077 static int usbduxsigma_dio_insn_bits(struct comedi_device *dev,
1078 struct comedi_subdevice *s,
1079 struct comedi_insn *insn,
1080 unsigned int *data)
1082 struct usbduxsigma_private *devpriv = dev->private;
1083 unsigned int mask = data[0];
1084 unsigned int bits = data[1];
1085 int ret;
1087 down(&devpriv->sem);
1089 s->state &= ~mask;
1090 s->state |= (bits & mask);
1092 devpriv->dux_commands[1] = s->io_bits & 0xff;
1093 devpriv->dux_commands[4] = s->state & 0xff;
1094 devpriv->dux_commands[2] = (s->io_bits >> 8) & 0xff;
1095 devpriv->dux_commands[5] = (s->state >> 8) & 0xff;
1096 devpriv->dux_commands[3] = (s->io_bits >> 16) & 0xff;
1097 devpriv->dux_commands[6] = (s->state >> 16) & 0xff;
1099 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
1100 if (ret < 0)
1101 goto done;
1102 ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
1103 if (ret < 0)
1104 goto done;
1106 s->state = devpriv->insn_buf[1] |
1107 (devpriv->insn_buf[2] << 8) |
1108 (devpriv->insn_buf[3] << 16);
1110 data[1] = s->state;
1111 ret = insn->n;
1113 done:
1114 up(&devpriv->sem);
1116 return ret;
1119 static void usbduxsigma_pwm_stop(struct comedi_device *dev, int do_unlink)
1121 struct usbduxsigma_private *devpriv = dev->private;
1123 if (do_unlink) {
1124 if (devpriv->pwm_urb)
1125 usb_kill_urb(devpriv->pwm_urb);
1128 devpriv->pwm_cmd_running = 0;
1131 static int usbduxsigma_pwm_cancel(struct comedi_device *dev,
1132 struct comedi_subdevice *s)
1134 struct usbduxsigma_private *devpriv = dev->private;
1136 /* unlink only if it is really running */
1137 usbduxsigma_pwm_stop(dev, devpriv->pwm_cmd_running);
1139 return usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_OFF_CMD);
1142 static void usbduxsigma_pwm_urb_complete(struct urb *urb)
1144 struct comedi_device *dev = urb->context;
1145 struct usbduxsigma_private *devpriv = dev->private;
1146 int ret;
1148 switch (urb->status) {
1149 case 0:
1150 /* success */
1151 break;
1153 case -ECONNRESET:
1154 case -ENOENT:
1155 case -ESHUTDOWN:
1156 case -ECONNABORTED:
1157 /* happens after an unlink command */
1158 if (devpriv->pwm_cmd_running)
1159 usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */
1160 return;
1162 default:
1163 /* a real error */
1164 if (devpriv->pwm_cmd_running) {
1165 dev_err(dev->class_dev,
1166 "%s: non-zero urb status (%d)\n",
1167 __func__, urb->status);
1168 usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */
1170 return;
1173 if (!devpriv->pwm_cmd_running)
1174 return;
1176 urb->transfer_buffer_length = devpriv->pwm_buf_sz;
1177 urb->dev = comedi_to_usb_dev(dev);
1178 urb->status = 0;
1179 ret = usb_submit_urb(urb, GFP_ATOMIC);
1180 if (ret < 0) {
1181 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
1182 __func__, ret);
1183 if (ret == EL2NSYNC)
1184 dev_err(dev->class_dev,
1185 "buggy USB host controller or bug in IRQ handler\n");
1186 usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */
1190 static int usbduxsigma_submit_pwm_urb(struct comedi_device *dev)
1192 struct usb_device *usb = comedi_to_usb_dev(dev);
1193 struct usbduxsigma_private *devpriv = dev->private;
1194 struct urb *urb = devpriv->pwm_urb;
1196 /* in case of a resubmission after an unlink... */
1197 usb_fill_bulk_urb(urb,
1198 usb, usb_sndbulkpipe(usb, USBDUXSIGMA_PWM_OUT_EP),
1199 urb->transfer_buffer, devpriv->pwm_buf_sz,
1200 usbduxsigma_pwm_urb_complete, dev);
1202 return usb_submit_urb(urb, GFP_ATOMIC);
1205 static int usbduxsigma_pwm_period(struct comedi_device *dev,
1206 struct comedi_subdevice *s,
1207 unsigned int period)
1209 struct usbduxsigma_private *devpriv = dev->private;
1210 int fx2delay = 255;
1212 if (period < MIN_PWM_PERIOD) {
1213 return -EAGAIN;
1214 } else {
1215 fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
1216 if (fx2delay > 255)
1217 return -EAGAIN;
1219 devpriv->pwm_delay = fx2delay;
1220 devpriv->pwm_period = period;
1221 return 0;
1224 static int usbduxsigma_pwm_start(struct comedi_device *dev,
1225 struct comedi_subdevice *s)
1227 struct usbduxsigma_private *devpriv = dev->private;
1228 int ret;
1230 if (devpriv->pwm_cmd_running)
1231 return 0;
1233 devpriv->dux_commands[1] = devpriv->pwm_delay;
1234 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_ON_CMD);
1235 if (ret < 0)
1236 return ret;
1238 memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);
1240 ret = usbduxsigma_submit_pwm_urb(dev);
1241 if (ret < 0)
1242 return ret;
1243 devpriv->pwm_cmd_running = 1;
1245 return 0;
1248 static int usbduxsigma_pwm_pattern(struct comedi_device *dev,
1249 struct comedi_subdevice *s,
1250 unsigned int chan,
1251 unsigned int value,
1252 unsigned int sign)
1254 struct usbduxsigma_private *devpriv = dev->private;
1255 char pwm_mask = (1 << chan); /* DIO bit for the PWM data */
1256 char sgn_mask = (16 << chan); /* DIO bit for the sign */
1257 char *buf = (char *)(devpriv->pwm_urb->transfer_buffer);
1258 int szbuf = devpriv->pwm_buf_sz;
1259 int i;
1261 for (i = 0; i < szbuf; i++) {
1262 char c = *buf;
1264 c &= ~pwm_mask;
1265 if (i < value)
1266 c |= pwm_mask;
1267 if (!sign)
1268 c &= ~sgn_mask;
1269 else
1270 c |= sgn_mask;
1271 *buf++ = c;
1273 return 1;
1276 static int usbduxsigma_pwm_write(struct comedi_device *dev,
1277 struct comedi_subdevice *s,
1278 struct comedi_insn *insn,
1279 unsigned int *data)
1281 unsigned int chan = CR_CHAN(insn->chanspec);
1284 * It doesn't make sense to support more than one value here
1285 * because it would just overwrite the PWM buffer.
1287 if (insn->n != 1)
1288 return -EINVAL;
1291 * The sign is set via a special INSN only, this gives us 8 bits
1292 * for normal operation, sign is 0 by default.
1294 return usbduxsigma_pwm_pattern(dev, s, chan, data[0], 0);
1297 static int usbduxsigma_pwm_config(struct comedi_device *dev,
1298 struct comedi_subdevice *s,
1299 struct comedi_insn *insn,
1300 unsigned int *data)
1302 struct usbduxsigma_private *devpriv = dev->private;
1303 unsigned int chan = CR_CHAN(insn->chanspec);
1305 switch (data[0]) {
1306 case INSN_CONFIG_ARM:
1308 * if not zero the PWM is limited to a certain time which is
1309 * not supported here
1311 if (data[1] != 0)
1312 return -EINVAL;
1313 return usbduxsigma_pwm_start(dev, s);
1314 case INSN_CONFIG_DISARM:
1315 return usbduxsigma_pwm_cancel(dev, s);
1316 case INSN_CONFIG_GET_PWM_STATUS:
1317 data[1] = devpriv->pwm_cmd_running;
1318 return 0;
1319 case INSN_CONFIG_PWM_SET_PERIOD:
1320 return usbduxsigma_pwm_period(dev, s, data[1]);
1321 case INSN_CONFIG_PWM_GET_PERIOD:
1322 data[1] = devpriv->pwm_period;
1323 return 0;
1324 case INSN_CONFIG_PWM_SET_H_BRIDGE:
1326 * data[1] = value
1327 * data[2] = sign (for a relay)
1329 return usbduxsigma_pwm_pattern(dev, s, chan,
1330 data[1], (data[2] != 0));
1331 case INSN_CONFIG_PWM_GET_H_BRIDGE:
1332 /* values are not kept in this driver, nothing to return */
1333 return -EINVAL;
1335 return -EINVAL;
1338 static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan)
1340 struct usbduxsigma_private *devpriv = dev->private;
1341 uint8_t sysred;
1342 uint32_t val;
1343 int ret;
1345 switch (chan) {
1346 default:
1347 case 0:
1348 sysred = 0; /* ADC zero */
1349 break;
1350 case 1:
1351 sysred = 1; /* ADC offset */
1352 break;
1353 case 2:
1354 sysred = 4; /* VCC */
1355 break;
1356 case 3:
1357 sysred = 8; /* temperature */
1358 break;
1359 case 4:
1360 sysred = 16; /* gain */
1361 break;
1362 case 5:
1363 sysred = 32; /* ref */
1364 break;
1367 devpriv->dux_commands[1] = 0x12; /* CONFIG0 */
1368 devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
1369 devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
1370 devpriv->dux_commands[4] = 0;
1371 devpriv->dux_commands[5] = 0;
1372 devpriv->dux_commands[6] = sysred;
1373 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
1374 if (ret < 0)
1375 return ret;
1377 ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
1378 if (ret < 0)
1379 return ret;
1381 /* 32 bits big endian from the A/D converter */
1382 val = be32_to_cpu(*((int32_t *)((devpriv->insn_buf)+1)));
1383 val &= 0x00ffffff; /* strip status byte */
1384 val ^= 0x00800000; /* convert to unsigned */
1386 return (int)val;
1389 static int usbduxsigma_attach_common(struct comedi_device *dev)
1391 struct usbduxsigma_private *devpriv = dev->private;
1392 struct comedi_subdevice *s;
1393 int n_subdevs;
1394 int offset;
1395 int ret;
1397 down(&devpriv->sem);
1399 if (devpriv->high_speed)
1400 n_subdevs = 4; /* with pwm */
1401 else
1402 n_subdevs = 3; /* without pwm */
1403 ret = comedi_alloc_subdevices(dev, n_subdevs);
1404 if (ret) {
1405 up(&devpriv->sem);
1406 return ret;
1409 /* Analog Input subdevice */
1410 s = &dev->subdevices[0];
1411 dev->read_subdev = s;
1412 s->type = COMEDI_SUBD_AI;
1413 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ | SDF_LSAMPL;
1414 s->n_chan = NUMCHANNELS;
1415 s->len_chanlist = NUMCHANNELS;
1416 s->maxdata = 0x00ffffff;
1417 s->range_table = &usbduxsigma_ai_range;
1418 s->insn_read = usbduxsigma_ai_insn_read;
1419 s->do_cmdtest = usbduxsigma_ai_cmdtest;
1420 s->do_cmd = usbduxsigma_ai_cmd;
1421 s->cancel = usbduxsigma_ai_cancel;
1423 /* Analog Output subdevice */
1424 s = &dev->subdevices[1];
1425 dev->write_subdev = s;
1426 s->type = COMEDI_SUBD_AO;
1427 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1428 s->n_chan = USBDUXSIGMA_NUM_AO_CHAN;
1429 s->len_chanlist = s->n_chan;
1430 s->maxdata = 0x00ff;
1431 s->range_table = &range_unipolar2_5;
1432 s->insn_write = usbduxsigma_ao_insn_write;
1433 s->insn_read = usbduxsigma_ao_insn_read;
1434 s->do_cmdtest = usbduxsigma_ao_cmdtest;
1435 s->do_cmd = usbduxsigma_ao_cmd;
1436 s->cancel = usbduxsigma_ao_cancel;
1438 /* Digital I/O subdevice */
1439 s = &dev->subdevices[2];
1440 s->type = COMEDI_SUBD_DIO;
1441 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1442 s->n_chan = 24;
1443 s->maxdata = 1;
1444 s->range_table = &range_digital;
1445 s->insn_bits = usbduxsigma_dio_insn_bits;
1446 s->insn_config = usbduxsigma_dio_insn_config;
1448 if (devpriv->high_speed) {
1449 /* Timer / pwm subdevice */
1450 s = &dev->subdevices[3];
1451 s->type = COMEDI_SUBD_PWM;
1452 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1453 s->n_chan = 8;
1454 s->maxdata = devpriv->pwm_buf_sz;
1455 s->insn_write = usbduxsigma_pwm_write;
1456 s->insn_config = usbduxsigma_pwm_config;
1458 usbduxsigma_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1461 up(&devpriv->sem);
1463 offset = usbduxsigma_getstatusinfo(dev, 0);
1464 if (offset < 0)
1465 dev_err(dev->class_dev,
1466 "Communication to USBDUXSIGMA failed! Check firmware and cabling\n");
1468 dev_info(dev->class_dev, "attached, ADC_zero = %x\n", offset);
1470 return 0;
1473 static int usbduxsigma_firmware_upload(struct comedi_device *dev,
1474 const u8 *data, size_t size,
1475 unsigned long context)
1477 struct usb_device *usb = comedi_to_usb_dev(dev);
1478 uint8_t *buf;
1479 uint8_t *tmp;
1480 int ret;
1482 if (!data)
1483 return 0;
1485 if (size > FIRMWARE_MAX_LEN) {
1486 dev_err(dev->class_dev, "firmware binary too large for FX2\n");
1487 return -ENOMEM;
1490 /* we generate a local buffer for the firmware */
1491 buf = kmemdup(data, size, GFP_KERNEL);
1492 if (!buf)
1493 return -ENOMEM;
1495 /* we need a malloc'ed buffer for usb_control_msg() */
1496 tmp = kmalloc(1, GFP_KERNEL);
1497 if (!tmp) {
1498 kfree(buf);
1499 return -ENOMEM;
1502 /* stop the current firmware on the device */
1503 *tmp = 1; /* 7f92 to one */
1504 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1505 USBDUXSUB_FIRMWARE,
1506 VENDOR_DIR_OUT,
1507 USBDUXSUB_CPUCS, 0x0000,
1508 tmp, 1,
1509 BULK_TIMEOUT);
1510 if (ret < 0) {
1511 dev_err(dev->class_dev, "can not stop firmware\n");
1512 goto done;
1515 /* upload the new firmware to the device */
1516 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1517 USBDUXSUB_FIRMWARE,
1518 VENDOR_DIR_OUT,
1519 0, 0x0000,
1520 buf, size,
1521 BULK_TIMEOUT);
1522 if (ret < 0) {
1523 dev_err(dev->class_dev, "firmware upload failed\n");
1524 goto done;
1527 /* start the new firmware on the device */
1528 *tmp = 0; /* 7f92 to zero */
1529 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1530 USBDUXSUB_FIRMWARE,
1531 VENDOR_DIR_OUT,
1532 USBDUXSUB_CPUCS, 0x0000,
1533 tmp, 1,
1534 BULK_TIMEOUT);
1535 if (ret < 0)
1536 dev_err(dev->class_dev, "can not start firmware\n");
1538 done:
1539 kfree(tmp);
1540 kfree(buf);
1541 return ret;
1544 static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev)
1546 struct usb_device *usb = comedi_to_usb_dev(dev);
1547 struct usbduxsigma_private *devpriv = dev->private;
1548 struct urb *urb;
1549 int i;
1551 devpriv->dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
1552 devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1553 devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL);
1554 devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1555 devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(*urb),
1556 GFP_KERNEL);
1557 devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(*urb),
1558 GFP_KERNEL);
1559 if (!devpriv->dac_commands || !devpriv->dux_commands ||
1560 !devpriv->in_buf || !devpriv->insn_buf ||
1561 !devpriv->ai_urbs || !devpriv->ao_urbs)
1562 return -ENOMEM;
1564 for (i = 0; i < devpriv->n_ai_urbs; i++) {
1565 /* one frame: 1ms */
1566 urb = usb_alloc_urb(1, GFP_KERNEL);
1567 if (!urb)
1568 return -ENOMEM;
1569 devpriv->ai_urbs[i] = urb;
1570 urb->dev = usb;
1571 /* will be filled later with a pointer to the comedi-device */
1572 /* and ONLY then the urb should be submitted */
1573 urb->context = NULL;
1574 urb->pipe = usb_rcvisocpipe(usb, USBDUXSIGMA_ISO_IN_EP);
1575 urb->transfer_flags = URB_ISO_ASAP;
1576 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1577 if (!urb->transfer_buffer)
1578 return -ENOMEM;
1579 urb->complete = usbduxsigma_ai_urb_complete;
1580 urb->number_of_packets = 1;
1581 urb->transfer_buffer_length = SIZEINBUF;
1582 urb->iso_frame_desc[0].offset = 0;
1583 urb->iso_frame_desc[0].length = SIZEINBUF;
1586 for (i = 0; i < devpriv->n_ao_urbs; i++) {
1587 /* one frame: 1ms */
1588 urb = usb_alloc_urb(1, GFP_KERNEL);
1589 if (!urb)
1590 return -ENOMEM;
1591 devpriv->ao_urbs[i] = urb;
1592 urb->dev = usb;
1593 /* will be filled later with a pointer to the comedi-device */
1594 /* and ONLY then the urb should be submitted */
1595 urb->context = NULL;
1596 urb->pipe = usb_sndisocpipe(usb, USBDUXSIGMA_ISO_OUT_EP);
1597 urb->transfer_flags = URB_ISO_ASAP;
1598 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1599 if (!urb->transfer_buffer)
1600 return -ENOMEM;
1601 urb->complete = usbduxsigma_ao_urb_complete;
1602 urb->number_of_packets = 1;
1603 urb->transfer_buffer_length = SIZEOUTBUF;
1604 urb->iso_frame_desc[0].offset = 0;
1605 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1606 if (devpriv->high_speed)
1607 urb->interval = 8; /* uframes */
1608 else
1609 urb->interval = 1; /* frames */
1612 if (devpriv->high_speed) {
1613 /* max bulk ep size in high speed */
1614 devpriv->pwm_buf_sz = 512;
1615 urb = usb_alloc_urb(0, GFP_KERNEL);
1616 if (!urb)
1617 return -ENOMEM;
1618 devpriv->pwm_urb = urb;
1619 urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz, GFP_KERNEL);
1620 if (!urb->transfer_buffer)
1621 return -ENOMEM;
1622 } else {
1623 devpriv->pwm_urb = NULL;
1624 devpriv->pwm_buf_sz = 0;
1627 return 0;
1630 static void usbduxsigma_free_usb_buffers(struct comedi_device *dev)
1632 struct usbduxsigma_private *devpriv = dev->private;
1633 struct urb *urb;
1634 int i;
1636 /* force unlink all urbs */
1637 usbduxsigma_ai_stop(dev, 1);
1638 usbduxsigma_ao_stop(dev, 1);
1639 usbduxsigma_pwm_stop(dev, 1);
1641 urb = devpriv->pwm_urb;
1642 if (urb) {
1643 kfree(urb->transfer_buffer);
1644 usb_free_urb(urb);
1646 if (devpriv->ao_urbs) {
1647 for (i = 0; i < devpriv->n_ao_urbs; i++) {
1648 urb = devpriv->ao_urbs[i];
1649 if (urb) {
1650 kfree(urb->transfer_buffer);
1651 usb_free_urb(urb);
1654 kfree(devpriv->ao_urbs);
1656 if (devpriv->ai_urbs) {
1657 for (i = 0; i < devpriv->n_ai_urbs; i++) {
1658 urb = devpriv->ai_urbs[i];
1659 if (urb) {
1660 kfree(urb->transfer_buffer);
1661 usb_free_urb(urb);
1664 kfree(devpriv->ai_urbs);
1666 kfree(devpriv->insn_buf);
1667 kfree(devpriv->in_buf);
1668 kfree(devpriv->dux_commands);
1669 kfree(devpriv->dac_commands);
1672 static int usbduxsigma_auto_attach(struct comedi_device *dev,
1673 unsigned long context_unused)
1675 struct usb_interface *intf = comedi_to_usb_interface(dev);
1676 struct usb_device *usb = comedi_to_usb_dev(dev);
1677 struct usbduxsigma_private *devpriv;
1678 int ret;
1680 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1681 if (!devpriv)
1682 return -ENOMEM;
1683 dev->private = devpriv;
1685 sema_init(&devpriv->sem, 1);
1686 usb_set_intfdata(intf, devpriv);
1688 ret = usb_set_interface(usb,
1689 intf->altsetting->desc.bInterfaceNumber, 3);
1690 if (ret < 0) {
1691 dev_err(dev->class_dev,
1692 "could not set alternate setting 3 in high speed\n");
1693 return -ENODEV;
1696 /* test if it is high speed (USB 2.0) */
1697 devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1698 if (devpriv->high_speed) {
1699 devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH;
1700 devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH;
1701 } else {
1702 devpriv->n_ai_urbs = NUMOFINBUFFERSFULL;
1703 devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL;
1706 ret = usbduxsigma_alloc_usb_buffers(dev);
1707 if (ret)
1708 return ret;
1710 ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1711 usbduxsigma_firmware_upload, 0);
1712 if (ret)
1713 return ret;
1715 return usbduxsigma_attach_common(dev);
1718 static void usbduxsigma_detach(struct comedi_device *dev)
1720 struct usb_interface *intf = comedi_to_usb_interface(dev);
1721 struct usbduxsigma_private *devpriv = dev->private;
1723 if (!devpriv)
1724 return;
1726 usb_set_intfdata(intf, NULL);
1728 down(&devpriv->sem);
1729 usbduxsigma_free_usb_buffers(dev);
1730 up(&devpriv->sem);
1733 static struct comedi_driver usbduxsigma_driver = {
1734 .driver_name = "usbduxsigma",
1735 .module = THIS_MODULE,
1736 .auto_attach = usbduxsigma_auto_attach,
1737 .detach = usbduxsigma_detach,
1740 static int usbduxsigma_usb_probe(struct usb_interface *intf,
1741 const struct usb_device_id *id)
1743 return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0);
1746 static const struct usb_device_id usbduxsigma_usb_table[] = {
1747 { USB_DEVICE(0x13d8, 0x0020) },
1748 { USB_DEVICE(0x13d8, 0x0021) },
1749 { USB_DEVICE(0x13d8, 0x0022) },
1752 MODULE_DEVICE_TABLE(usb, usbduxsigma_usb_table);
1754 static struct usb_driver usbduxsigma_usb_driver = {
1755 .name = "usbduxsigma",
1756 .probe = usbduxsigma_usb_probe,
1757 .disconnect = comedi_usb_auto_unconfig,
1758 .id_table = usbduxsigma_usb_table,
1760 module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver);
1762 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1763 MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com");
1764 MODULE_LICENSE("GPL");
1765 MODULE_FIRMWARE(FIRMWARE);