]> Pileus Git - ~andy/linux/blob - drivers/staging/comedi/drivers/usbduxsigma.c
e9dfbb3e7de3b1954e8beb9c9943c032029ec324
[~andy/linux] / drivers / staging / comedi / drivers / usbduxsigma.c
1 /*
2    comedi/drivers/usbdux.c
3    Copyright (C) 2011 Bernd Porr, Bernd.Porr@f2s.com
4
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.
9
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.
14  */
15 /*
16 Driver: usbduxsigma
17 Description: University of Stirling USB DAQ & INCITE Technology Limited
18 Devices: [ITL] USB-DUX (usbduxsigma.o)
19 Author: Bernd Porr <BerndPorr@f2s.com>
20 Updated: 8 Nov 2011
21 Status: testing
22 */
23 /*
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.
28  *
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
31  *
32  *
33  * Revision history:
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
40  */
41
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>
50
51 #include "comedi_fc.h"
52 #include "../comedidev.h"
53
54 /* timeout for the USB-transfer in ms*/
55 #define BULK_TIMEOUT 1000
56
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
62
63 /* internal addresses of the 8051 processor */
64 #define USBDUXSUB_CPUCS 0xE600
65
66 /*
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
70  */
71 #define USBDUXSUB_MINOR 32
72
73 /* max lenghth of the transfer-buffer for software upload */
74 #define TB_LEN 0x2000
75
76 /* Input endpoint number: ISO/IRQ */
77 #define ISOINEP           6
78
79 /* Output endpoint number: ISO/IRQ */
80 #define ISOOUTEP          2
81
82 /* This EP sends DUX commands to USBDUX */
83 #define COMMAND_OUT_EP     1
84
85 /* This EP receives the DUX commands from USBDUX */
86 #define COMMAND_IN_EP        8
87
88 /* Output endpoint for PWM */
89 #define PWM_EP         4
90
91 /* 300Hz max frequ under PWM */
92 #define MIN_PWM_PERIOD  ((long)(1E9/300))
93
94 /* Default PWM frequency */
95 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
96
97 /* Number of channels (16 AD and offset)*/
98 #define NUMCHANNELS 16
99
100 /* Size of one A/D value */
101 #define SIZEADIN          ((sizeof(int32_t)))
102
103 /*
104  * Size of the async input-buffer IN BYTES, the DIO state is transmitted
105  * as the first byte.
106  */
107 #define SIZEINBUF         (((NUMCHANNELS+1)*SIZEADIN))
108
109 /* 16 bytes. */
110 #define SIZEINSNBUF       16
111
112 /* Number of DA channels */
113 #define NUMOUTCHANNELS    8
114
115 /* size of one value for the D/A converter: channel and value */
116 #define SIZEDAOUT          ((sizeof(uint8_t)+sizeof(int16_t)))
117
118 /*
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).
122  */
123 #define SIZEOUTBUF         ((8*SIZEDAOUT))
124
125 /*
126  * Size of the buffer for the dux commands: just now max size is determined
127  * by the analogue out + command byte + panic bytes...
128  */
129 #define SIZEOFDUXBUFFER    ((8*SIZEDAOUT+2))
130
131 /* Number of in-URBs which receive the data: min=2 */
132 #define NUMOFINBUFFERSFULL     5
133
134 /* Number of out-URBs which send the data: min=2 */
135 #define NUMOFOUTBUFFERSFULL    5
136
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
140
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
144
145 /* Analogue in subdevice */
146 #define SUBDEV_AD             0
147
148 /* Analogue out subdevice */
149 #define SUBDEV_DA             1
150
151 /* Digital I/O */
152 #define SUBDEV_DIO            2
153
154 /* timer aka pwm output */
155 #define SUBDEV_PWM            3
156
157 /* number of retries to get the right dux command */
158 #define RETRIES 10
159
160 /**************************************************/
161 /* comedi constants */
162 static const struct comedi_lrange range_usbdux_ai_range = { 1, {
163                                                                 BIP_RANGE
164                                                                 (2.65/2.0)
165                                                                 }
166 };
167
168 struct usbduxsigma_private {
169         /* actual number of in-buffers */
170         int numOfInBuffers;
171         /* actual number of out-buffers */
172         int numOfOutBuffers;
173         /* ISO-transfer handling: buffers */
174         struct urb **urbIn;
175         struct urb **urbOut;
176         /* pwm-transfer handling */
177         struct urb *urbPwm;
178         /* PWM period */
179         unsigned int pwmPeriod;
180         /* PWM internal delay for the GPIF in the FX2 */
181         uint8_t pwmDelay;
182         /* size of the PWM buffer which holds the bit pattern */
183         int sizePwmBuf;
184         /* input buffer for the ISO-transfer */
185         int32_t *inBuffer;
186         /* input buffer for single insn */
187         int8_t *insnBuffer;
188         /* output buffer for single DA outputs */
189         int16_t *outBuffer;
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;
197         /* pwm is 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 */
203         int ai_sample_count;
204         int ao_sample_count;
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;
213         /* D/A commands */
214         uint8_t *dac_commands;
215         /* commands */
216         uint8_t *dux_commands;
217         struct semaphore sem;
218 };
219
220 static void usbdux_ai_stop(struct usbduxsigma_private *devpriv, int do_unlink)
221 {
222         if (do_unlink) {
223                 int i;
224
225                 for (i = 0; i < devpriv->numOfInBuffers; i++) {
226                         if (devpriv->urbIn[i])
227                                 usb_kill_urb(devpriv->urbIn[i]);
228                 }
229         }
230
231         devpriv->ai_cmd_running = 0;
232 }
233
234 static int usbdux_ai_cancel(struct comedi_device *dev,
235                             struct comedi_subdevice *s)
236 {
237         struct usbduxsigma_private *devpriv = dev->private;
238
239         down(&devpriv->sem);
240         /* unlink only if it is really running */
241         usbdux_ai_stop(devpriv, devpriv->ai_cmd_running);
242         up(&devpriv->sem);
243
244         return 0;
245 }
246
247 static void usbduxsub_ai_IsocIrq(struct urb *urb)
248 {
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;
253         int32_t val;
254         int ret;
255         int i;
256
257         /* first we test if something unusual has just happened */
258         switch (urb->status) {
259         case 0:
260                 /* copy the result in the transfer buffer */
261                 memcpy(devpriv->inBuffer, urb->transfer_buffer, SIZEINBUF);
262                 break;
263         case -EILSEQ:
264                 /*
265                  * error in the ISOchronous data
266                  * we don't copy the data into the transfer buffer
267                  * and recycle the last data byte
268                  */
269                 dev_dbg(dev->class_dev,"CRC error in ISO IN stream\n");
270
271                 break;
272
273         case -ECONNRESET:
274         case -ENOENT:
275         case -ESHUTDOWN:
276         case -ECONNABORTED:
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);
283                 }
284                 return;
285
286         default:
287                 /*
288                  * a real error on the bus
289                  * pass error to comedi if we are really running a command
290                  */
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);
298                 }
299                 return;
300         }
301
302         if (unlikely(!devpriv->ai_cmd_running))
303                 return;
304
305         urb->dev = comedi_to_usb_dev(dev);
306
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",
310                         __func__, ret);
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);
317                 return;
318         }
319
320         /* get the state of the dio pins to allow external trigger */
321         dio_state = be32_to_cpu(devpriv->inBuffer[0]);
322
323         devpriv->ai_counter--;
324         if (likely(devpriv->ai_counter > 0))
325                 return;
326
327         /* timer zero, transfer measurements to comedi */
328         devpriv->ai_counter = devpriv->ai_timer;
329
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);
338                         return;
339                 }
340         }
341
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 */
348
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 */
353                         return;
354                 }
355         }
356         /* tell comedi that data is there */
357         s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
358         comedi_event(dev, s);
359 }
360
361 static void usbdux_ao_stop(struct usbduxsigma_private *devpriv, int do_unlink)
362 {
363         if (do_unlink) {
364                 int i;
365
366                 for (i = 0; i < devpriv->numOfOutBuffers; i++) {
367                         if (devpriv->urbOut[i])
368                                 usb_kill_urb(devpriv->urbOut[i]);
369                 }
370         }
371
372         devpriv->ao_cmd_running = 0;
373 }
374
375 static int usbdux_ao_cancel(struct comedi_device *dev,
376                             struct comedi_subdevice *s)
377 {
378         struct usbduxsigma_private *devpriv = dev->private;
379
380         down(&devpriv->sem);
381         /* unlink only if it is really running */
382         usbdux_ao_stop(devpriv, devpriv->ao_cmd_running);
383         up(&devpriv->sem);
384
385         return 0;
386 }
387
388 static void usbduxsub_ao_IsocIrq(struct urb *urb)
389 {
390         struct comedi_device *dev = urb->context;
391         struct usbduxsigma_private *devpriv = dev->private;
392         struct comedi_subdevice *s = dev->write_subdev;
393         uint8_t *datap;
394         int len;
395         int ret;
396         int i;
397
398         switch (urb->status) {
399         case 0:
400                 /* success */
401                 break;
402
403         case -ECONNRESET:
404         case -ENOENT:
405         case -ESHUTDOWN:
406         case -ECONNABORTED:
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);
412                 }
413                 return;
414
415         default:
416                 /* a real error */
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);
424                 }
425                 return;
426         }
427
428         if (!devpriv->ao_cmd_running)
429                 return;
430
431         devpriv->ao_counter--;
432         if ((int)devpriv->ao_counter <= 0) {
433                 /* timer zero, transfer from comedi */
434                 devpriv->ao_counter = devpriv->ao_timer;
435
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);
444                                 return;
445                         }
446                 }
447
448                 /* transmit data to the USB bus */
449                 datap = urb->transfer_buffer;
450                 len = s->async->cmd.chanlist_len;
451                 *datap++ = len;
452                 for (i = 0; i < len; i++) {
453                         short val;
454
455                         if (i >= NUMOUTCHANNELS)
456                                 break;
457
458                         ret = comedi_buf_get(s->async, &val);
459                         if (ret < 0) {
460                                 dev_err(dev->class_dev, "buffer underflow\n");
461                                 s->async->events |= (COMEDI_CB_EOA |
462                                                      COMEDI_CB_OVERFLOW);
463                         }
464                         *datap++ = val;
465                         *datap++ = devpriv->dac_commands[i];
466
467                         s->async->events |= COMEDI_CB_BLOCK;
468                         comedi_event(dev, s);
469                 }
470         }
471
472         urb->transfer_buffer_length = SIZEOUTBUF;
473         urb->dev = comedi_to_usb_dev(dev);
474         urb->status = 0;
475         if (devpriv->high_speed)
476                 urb->interval = 8;      /* uframes */
477         else
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);
484         if (ret < 0) {
485                 dev_err(dev->class_dev,
486                         "%s: urb resubmit failed (%d)\n",
487                         __func__, ret);
488                 if (ret == EL2NSYNC)
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);
494         }
495 }
496
497 /* the FX2LP has twice as much as the standard FX2 */
498 #define FIRMWARE_MAX_LEN 0x4000
499
500 static int usbduxsigma_firmware_upload(struct comedi_device *dev,
501                                        const u8 *data, size_t size,
502                                        unsigned long context)
503 {
504         struct usb_device *usb = comedi_to_usb_dev(dev);
505         uint8_t *buf;
506         uint8_t *tmp;
507         int ret;
508
509         if (!data)
510                 return 0;
511
512         if (size > FIRMWARE_MAX_LEN) {
513                 dev_err(dev->class_dev, "firmware binary too large for FX2\n");
514                 return -ENOMEM;
515         }
516
517         /* we generate a local buffer for the firmware */
518         buf = kmemdup(data, size, GFP_KERNEL);
519         if (!buf)
520                 return -ENOMEM;
521
522         /* we need a malloc'ed buffer for usb_control_msg() */
523         tmp = kmalloc(1, GFP_KERNEL);
524         if (!tmp) {
525                 kfree(buf);
526                 return -ENOMEM;
527         }
528
529         /* stop the current firmware on the device */
530         *tmp = 1;       /* 7f92 to one */
531         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
532                               USBDUXSUB_FIRMWARE,
533                               VENDOR_DIR_OUT,
534                               USBDUXSUB_CPUCS, 0x0000,
535                               tmp, 1,
536                               BULK_TIMEOUT);
537         if (ret < 0) {
538                 dev_err(dev->class_dev, "can not stop firmware\n");
539                 goto done;
540         }
541
542         /* upload the new firmware to the device */
543         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
544                               USBDUXSUB_FIRMWARE,
545                               VENDOR_DIR_OUT,
546                               0, 0x0000,
547                               buf, size,
548                               BULK_TIMEOUT);
549         if (ret < 0) {
550                 dev_err(dev->class_dev, "firmware upload failed\n");
551                 goto done;
552         }
553
554         /* start the new firmware on the device */
555         *tmp = 0;       /* 7f92 to zero */
556         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
557                               USBDUXSUB_FIRMWARE,
558                               VENDOR_DIR_OUT,
559                               USBDUXSUB_CPUCS, 0x0000,
560                               tmp, 1,
561                               BULK_TIMEOUT);
562         if (ret < 0)
563                 dev_err(dev->class_dev, "can not start firmware\n");
564
565 done:
566         kfree(tmp);
567         kfree(buf);
568         return ret;
569 }
570
571 static int usbduxsigma_submit_urbs(struct comedi_device *dev,
572                                    struct urb **urbs, int num_urbs,
573                                    int input_urb)
574 {
575         struct usb_device *usb = comedi_to_usb_dev(dev);
576         struct usbduxsigma_private *devpriv = dev->private;
577         struct urb *urb;
578         int ret;
579         int i;
580
581         /* Submit all URBs and start the transfer on the bus */
582         for (i = 0; i < num_urbs; i++) {
583                 urb = urbs[i];
584
585                 /* in case of a resubmission after an unlink... */
586                 if (input_urb)
587                         urb->interval = devpriv->ai_interval;
588                 urb->context = dev;
589                 urb->dev = usb;
590                 urb->status = 0;
591                 urb->transfer_flags = URB_ISO_ASAP;
592
593                 ret = usb_submit_urb(urb, GFP_ATOMIC);
594                 if (ret)
595                         return ret;
596         }
597         return 0;
598 }
599
600 static int chanToInterval(int nChannels)
601 {
602         if (nChannels <= 2)
603                 /* 4kHz */
604                 return 2;
605         if (nChannels <= 8)
606                 /* 2kHz */
607                 return 4;
608         /* 1kHz */
609         return 8;
610 }
611
612 static int usbdux_ai_cmdtest(struct comedi_device *dev,
613                              struct comedi_subdevice *s,
614                              struct comedi_cmd *cmd)
615 {
616         struct usbduxsigma_private *this_usbduxsub = dev->private;
617         int err = 0, i;
618         unsigned int tmpTimer;
619
620         /* Step 1 : check if triggers are trivially valid */
621
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);
627
628         if (err)
629                 return 1;
630
631         /* Step 2a : make sure trigger sources are unique */
632
633         err |= cfc_check_trigger_is_unique(cmd->start_src);
634         err |= cfc_check_trigger_is_unique(cmd->stop_src);
635
636         /* Step 2b : and mutually compatible */
637
638         if (err)
639                 return 2;
640
641         /* Step 3: check if arguments are trivially valid */
642
643         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
644
645         if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
646                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
647
648         if (cmd->scan_begin_src == TRIG_TIMER) {
649                 if (this_usbduxsub->high_speed) {
650                         /*
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.
655                          */
656                         i = chanToInterval(cmd->chanlist_len);
657                         err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
658                                                          (1000000 / 8 * i));
659                         /* now calc the real sampling rate with all the
660                          * rounding errors */
661                         tmpTimer =
662                             ((unsigned int)(cmd->scan_begin_arg / 125000)) *
663                             125000;
664                 } else {
665                         /* full speed */
666                         /* 1kHz scans every USB frame */
667                         err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
668                                                          1000000);
669                         /*
670                          * calc the real sampling rate with the rounding errors
671                          */
672                         tmpTimer = ((unsigned int)(cmd->scan_begin_arg /
673                                                    1000000)) * 1000000;
674                 }
675                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
676                                                 tmpTimer);
677         }
678
679         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
680
681         if (cmd->stop_src == TRIG_COUNT) {
682                 /* any count is allowed */
683         } else {
684                 /* TRIG_NONE */
685                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
686         }
687
688         if (err)
689                 return 3;
690
691         return 0;
692 }
693
694 /*
695  * creates the ADC command for the MAX1271
696  * range is the range value from comedi
697  */
698 static void create_adc_command(unsigned int chan,
699                                uint8_t *muxsg0,
700                                uint8_t *muxsg1)
701 {
702         if (chan < 8)
703                 (*muxsg0) = (*muxsg0) | (1 << chan);
704         else if (chan < 16)
705                 (*muxsg1) = (*muxsg1) | (1 << (chan-8));
706 }
707
708
709 /* bulk transfers to usbdux */
710
711 #define SENDADCOMMANDS            0
712 #define SENDDACOMMANDS            1
713 #define SENDDIOCONFIGCOMMAND      2
714 #define SENDDIOBITSCOMMAND        3
715 #define SENDSINGLEAD              4
716 #define SENDPWMON                 7
717 #define SENDPWMOFF                8
718
719 static int send_dux_commands(struct comedi_device *dev, int cmd_type)
720 {
721         struct usb_device *usb = comedi_to_usb_dev(dev);
722         struct usbduxsigma_private *devpriv = dev->private;
723         int nsent;
724
725         devpriv->dux_commands[0] = cmd_type;
726
727         return usb_bulk_msg(usb, usb_sndbulkpipe(usb, COMMAND_OUT_EP),
728                             devpriv->dux_commands, SIZEOFDUXBUFFER,
729                             &nsent, BULK_TIMEOUT);
730 }
731
732 static int receive_dux_commands(struct comedi_device *dev, int command)
733 {
734         struct usb_device *usb = comedi_to_usb_dev(dev);
735         struct usbduxsigma_private *devpriv = dev->private;
736         int nrec;
737         int ret;
738         int i;
739
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);
744                 if (ret < 0)
745                         return ret;
746
747                 if (devpriv->insnBuffer[0] == command)
748                         return 0;
749         }
750         /*
751          * This is only reached if the data has been requested a
752          * couple of times and the command was not received.
753          */
754         return -EFAULT;
755 }
756
757 static int usbduxsigma_ai_inttrig(struct comedi_device *dev,
758                                   struct comedi_subdevice *s,
759                                   unsigned int trignum)
760 {
761         struct usbduxsigma_private *devpriv= dev->private;
762         int ret;
763
764         if (trignum != 0)
765                 return -EINVAL;
766
767         down(&devpriv->sem);
768         if (!devpriv->ai_cmd_running) {
769                 ret = usbduxsigma_submit_urbs(dev, devpriv->urbIn,
770                                               devpriv->numOfInBuffers, 1);
771                 if (ret < 0) {
772                         up(&devpriv->sem);
773                         return ret;
774                 }
775                 devpriv->ai_cmd_running = 1;
776                 s->async->inttrig = NULL;
777         }
778         up(&devpriv->sem);
779
780         return 1;
781 }
782
783 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
784 {
785         struct usbduxsigma_private *this_usbduxsub = dev->private;
786         struct comedi_cmd *cmd = &s->async->cmd;
787         unsigned int chan;
788         int i, ret;
789         int result;
790         uint8_t muxsg0 = 0;
791         uint8_t muxsg1 = 0;
792         uint8_t sysred = 0;
793
794         /* block other CPUs from starting an ai_cmd */
795         down(&this_usbduxsub->sem);
796         if (this_usbduxsub->ai_cmd_running) {
797                 dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
798                         "ai_cmd not possible. Another ai_cmd is running.\n",
799                         dev->minor);
800                 up(&this_usbduxsub->sem);
801                 return -EBUSY;
802         }
803         /* set current channel of the running acquisition to zero */
804         s->async->cur_chan = 0;
805
806         /* first the number of channels per time step */
807         this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
808
809         /* CONFIG0 */
810         this_usbduxsub->dux_commands[2] = 0x12;
811
812         /* CONFIG1: 23kHz sampling rate, delay = 0us,  */
813         this_usbduxsub->dux_commands[3] = 0x03;
814
815         /* CONFIG3: differential channels off */
816         this_usbduxsub->dux_commands[4] = 0x00;
817
818         for (i = 0; i < cmd->chanlist_len; i++) {
819                 chan = CR_CHAN(cmd->chanlist[i]);
820                 create_adc_command(chan, &muxsg0, &muxsg1);
821         }
822         this_usbduxsub->dux_commands[5] = muxsg0;
823         this_usbduxsub->dux_commands[6] = muxsg1;
824         this_usbduxsub->dux_commands[7] = sysred;
825
826         result = send_dux_commands(dev, SENDADCOMMANDS);
827         if (result < 0) {
828                 up(&this_usbduxsub->sem);
829                 return result;
830         }
831
832         if (this_usbduxsub->high_speed) {
833                 /*
834                  * every 2 channels get a time window of 125us. Thus, if we
835                  * sample all 16 channels we need 1ms. If we sample only one
836                  * channel we need only 125us
837                  */
838                 this_usbduxsub->ai_interval =
839                         chanToInterval(cmd->chanlist_len);
840                 this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
841                                                           (this_usbduxsub->
842                                                            ai_interval));
843         } else {
844                 /* interval always 1ms */
845                 this_usbduxsub->ai_interval = 1;
846                 this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000;
847         }
848         if (this_usbduxsub->ai_timer < 1) {
849                 dev_err(&this_usbduxsub->interface->dev, "comedi%d: ai_cmd: "
850                         "timer=%d, scan_begin_arg=%d. "
851                         "Not properly tested by cmdtest?\n", dev->minor,
852                         this_usbduxsub->ai_timer, cmd->scan_begin_arg);
853                 up(&this_usbduxsub->sem);
854                 return -EINVAL;
855         }
856         this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
857
858         if (cmd->stop_src == TRIG_COUNT) {
859                 /* data arrives as one packet */
860                 this_usbduxsub->ai_sample_count = cmd->stop_arg;
861                 this_usbduxsub->ai_continuous = 0;
862         } else {
863                 /* continuous acquisition */
864                 this_usbduxsub->ai_continuous = 1;
865                 this_usbduxsub->ai_sample_count = 0;
866         }
867
868         if (cmd->start_src == TRIG_NOW) {
869                 /* enable this acquisition operation */
870                 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbIn,
871                                               this_usbduxsub->numOfInBuffers,
872                                               1);
873                 if (ret < 0) {
874                         up(&this_usbduxsub->sem);
875                         return ret;
876                 }
877                 this_usbduxsub->ai_cmd_running = 1;
878                 s->async->inttrig = NULL;
879         } else {
880                 /* TRIG_INT */
881                 /* don't enable the acquision operation */
882                 /* wait for an internal signal */
883                 s->async->inttrig = usbduxsigma_ai_inttrig;
884         }
885         up(&this_usbduxsub->sem);
886         return 0;
887 }
888
889 /* Mode 0 is used to get a single conversion on demand */
890 static int usbdux_ai_insn_read(struct comedi_device *dev,
891                                struct comedi_subdevice *s,
892                                struct comedi_insn *insn, unsigned int *data)
893 {
894         struct usbduxsigma_private *this_usbduxsub = dev->private;
895         int i;
896         int32_t one = 0;
897         int chan;
898         int err;
899         uint8_t muxsg0 = 0;
900         uint8_t muxsg1 = 0;
901         uint8_t sysred = 0;
902
903         down(&this_usbduxsub->sem);
904         if (this_usbduxsub->ai_cmd_running) {
905                 dev_err(&this_usbduxsub->interface->dev,
906                         "comedi%d: ai_insn_read not possible. "
907                         "Async Command is running.\n", dev->minor);
908                 up(&this_usbduxsub->sem);
909                 return 0;
910         }
911
912         /* sample one channel */
913         /* CONFIG0: chopper on */
914         this_usbduxsub->dux_commands[1] = 0x16;
915
916         /* CONFIG1: 2kHz sampling rate */
917         this_usbduxsub->dux_commands[2] = 0x80;
918
919         /* CONFIG3: differential channels off */
920         this_usbduxsub->dux_commands[3] = 0x00;
921
922         chan = CR_CHAN(insn->chanspec);
923         create_adc_command(chan, &muxsg0, &muxsg1);
924
925         this_usbduxsub->dux_commands[4] = muxsg0;
926         this_usbduxsub->dux_commands[5] = muxsg1;
927         this_usbduxsub->dux_commands[6] = sysred;
928
929         /* adc commands */
930         err = send_dux_commands(dev, SENDSINGLEAD);
931         if (err < 0) {
932                 up(&this_usbduxsub->sem);
933                 return err;
934         }
935
936         for (i = 0; i < insn->n; i++) {
937                 err = receive_dux_commands(dev, SENDSINGLEAD);
938                 if (err < 0) {
939                         up(&this_usbduxsub->sem);
940                         return 0;
941                 }
942                 /* 32 bits big endian from the A/D converter */
943                 one = be32_to_cpu(*((int32_t *)
944                                     ((this_usbduxsub->insnBuffer)+1)));
945                 /* mask out the status byte */
946                 one = one & 0x00ffffff;
947                 /* turn it into an unsigned integer */
948                 one = one ^ 0x00800000;
949                 data[i] = one;
950         }
951         up(&this_usbduxsub->sem);
952         return i;
953 }
954
955
956
957
958 static int usbdux_getstatusinfo(struct comedi_device *dev, int chan)
959 {
960         struct usbduxsigma_private *this_usbduxsub = dev->private;
961         uint8_t sysred = 0;
962         uint32_t one;
963         int err;
964
965         if (this_usbduxsub->ai_cmd_running) {
966                 dev_err(&this_usbduxsub->interface->dev,
967                         "comedi%d: status read not possible. "
968                         "Async Command is running.\n", dev->minor);
969                 return 0;
970         }
971
972         /* CONFIG0 */
973         this_usbduxsub->dux_commands[1] = 0x12;
974
975         /* CONFIG1: 2kHz sampling rate */
976         this_usbduxsub->dux_commands[2] = 0x80;
977
978         /* CONFIG3: differential channels off */
979         this_usbduxsub->dux_commands[3] = 0x00;
980
981         if (chan == 1) {
982                 /* ADC offset */
983                 sysred = sysred | 1;
984         } else if (chan == 2) {
985                 /* VCC */
986                 sysred = sysred | 4;
987         } else if (chan == 3) {
988                 /* temperature */
989                 sysred = sysred | 8;
990         } else if (chan == 4) {
991                 /* gain */
992                 sysred = sysred | 16;
993         } else if (chan == 5) {
994                 /* ref */
995                 sysred = sysred | 32;
996         }
997
998         this_usbduxsub->dux_commands[4] = 0;
999         this_usbduxsub->dux_commands[5] = 0;
1000         this_usbduxsub->dux_commands[6] = sysred;
1001
1002         /* adc commands */
1003         err = send_dux_commands(dev, SENDSINGLEAD);
1004         if (err < 0)
1005                 return err;
1006
1007         err = receive_dux_commands(dev, SENDSINGLEAD);
1008         if (err < 0)
1009                 return err;
1010
1011         /* 32 bits big endian from the A/D converter */
1012         one = be32_to_cpu(*((int32_t *)((this_usbduxsub->insnBuffer)+1)));
1013         /* mask out the status byte */
1014         one = one & 0x00ffffff;
1015         one = one ^ 0x00800000;
1016
1017         return (int)one;
1018 }
1019
1020
1021
1022
1023
1024
1025 /************************************/
1026 /* analog out */
1027
1028 static int usbdux_ao_insn_read(struct comedi_device *dev,
1029                                struct comedi_subdevice *s,
1030                                struct comedi_insn *insn, unsigned int *data)
1031 {
1032         struct usbduxsigma_private *this_usbduxsub = dev->private;
1033         int i;
1034         int chan = CR_CHAN(insn->chanspec);
1035
1036         down(&this_usbduxsub->sem);
1037         for (i = 0; i < insn->n; i++)
1038                 data[i] = this_usbduxsub->outBuffer[chan];
1039
1040         up(&this_usbduxsub->sem);
1041         return i;
1042 }
1043
1044 static int usbdux_ao_insn_write(struct comedi_device *dev,
1045                                 struct comedi_subdevice *s,
1046                                 struct comedi_insn *insn, unsigned int *data)
1047 {
1048         struct usbduxsigma_private *this_usbduxsub = dev->private;
1049         int i, err;
1050         int chan = CR_CHAN(insn->chanspec);
1051
1052         down(&this_usbduxsub->sem);
1053         if (this_usbduxsub->ao_cmd_running) {
1054                 dev_err(&this_usbduxsub->interface->dev,
1055                         "comedi%d: ao_insn_write: "
1056                         "ERROR: asynchronous ao_cmd is running\n", dev->minor);
1057                 up(&this_usbduxsub->sem);
1058                 return 0;
1059         }
1060
1061         for (i = 0; i < insn->n; i++) {
1062                 dev_dbg(&this_usbduxsub->interface->dev,
1063                         "comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n",
1064                         dev->minor, chan, i, data[i]);
1065
1066                 /* number of channels: 1 */
1067                 this_usbduxsub->dux_commands[1] = 1;
1068                 /* channel number */
1069                 this_usbduxsub->dux_commands[2] = data[i];
1070                 this_usbduxsub->outBuffer[chan] = data[i];
1071                 this_usbduxsub->dux_commands[3] = chan;
1072                 err = send_dux_commands(dev, SENDDACOMMANDS);
1073                 if (err < 0) {
1074                         up(&this_usbduxsub->sem);
1075                         return err;
1076                 }
1077         }
1078         up(&this_usbduxsub->sem);
1079
1080         return i;
1081 }
1082
1083 static int usbduxsigma_ao_inttrig(struct comedi_device *dev,
1084                                   struct comedi_subdevice *s,
1085                                   unsigned int trignum)
1086 {
1087         struct usbduxsigma_private *devpriv = dev->private;
1088         int ret;
1089
1090         if (trignum != 0)
1091                 return -EINVAL;
1092
1093         down(&devpriv->sem);
1094         if (!devpriv->ao_cmd_running) {
1095                 ret = usbduxsigma_submit_urbs(dev, devpriv->urbOut,
1096                                               devpriv->numOfOutBuffers, 0);
1097                 if (ret < 0) {
1098                         up(&devpriv->sem);
1099                         return ret;
1100                 }
1101                 devpriv->ao_cmd_running = 1;
1102                 s->async->inttrig = NULL;
1103         }
1104         up(&devpriv->sem);
1105
1106         return 1;
1107 }
1108
1109 static int usbdux_ao_cmdtest(struct comedi_device *dev,
1110                              struct comedi_subdevice *s,
1111                              struct comedi_cmd *cmd)
1112 {
1113         int err = 0;
1114         unsigned int flags;
1115
1116         /* Step 1 : check if triggers are trivially valid */
1117
1118         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
1119
1120         if (0) {                /* (this_usbduxsub->high_speed) */
1121                 /*
1122                  * start immediately a new scan
1123                  * the sampling rate is set by the coversion rate
1124                  */
1125                 flags = TRIG_FOLLOW;
1126         } else {
1127                 /* start a new scan (output at once) with a timer */
1128                 flags = TRIG_TIMER;
1129         }
1130         err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
1131
1132         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1133         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1134         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1135
1136         if (err)
1137                 return 1;
1138
1139         /* Step 2a : make sure trigger sources are unique */
1140
1141         err |= cfc_check_trigger_is_unique(cmd->start_src);
1142         err |= cfc_check_trigger_is_unique(cmd->stop_src);
1143
1144         /* Step 2b : and mutually compatible */
1145
1146         if (err)
1147                 return 2;
1148
1149         /* Step 3: check if arguments are trivially valid */
1150
1151         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1152
1153         if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
1154                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1155
1156         if (cmd->scan_begin_src == TRIG_TIMER)
1157                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1158                                                  1000000);
1159
1160         /* not used now, is for later use */
1161         if (cmd->convert_src == TRIG_TIMER)
1162                 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
1163
1164         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1165
1166         if (cmd->stop_src == TRIG_COUNT) {
1167                 /* any count is allowed */
1168         } else {
1169                 /* TRIG_NONE */
1170                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1171         }
1172
1173         if (err)
1174                 return 3;
1175
1176         return 0;
1177 }
1178
1179 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1180 {
1181         struct usbduxsigma_private *this_usbduxsub = dev->private;
1182         struct comedi_cmd *cmd = &s->async->cmd;
1183         unsigned int chan, gain;
1184         int i, ret;
1185
1186         down(&this_usbduxsub->sem);
1187         /* set current channel of the running acquisition to zero */
1188         s->async->cur_chan = 0;
1189         for (i = 0; i < cmd->chanlist_len; ++i) {
1190                 chan = CR_CHAN(cmd->chanlist[i]);
1191                 gain = CR_RANGE(cmd->chanlist[i]);
1192                 this_usbduxsub->dac_commands[i] = chan;
1193                 dev_dbg(&this_usbduxsub->interface->dev,
1194                         "comedi%d: dac command for ch %d is %x\n",
1195                         dev->minor, i, this_usbduxsub->dac_commands[i]);
1196         }
1197
1198         /* we count in steps of 1ms (125us) */
1199         /* 125us mode not used yet */
1200         if (0) {                /* (this_usbduxsub->high_speed) */
1201                 /* 125us */
1202                 /* timing of the conversion itself: every 125 us */
1203                 this_usbduxsub->ao_timer = cmd->convert_arg / 125000;
1204         } else {
1205                 /* 1ms */
1206                 /* timing of the scan: we get all channels at once */
1207                 this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000;
1208                 dev_dbg(&this_usbduxsub->interface->dev,
1209                         "comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
1210                         "convert_src=%d, convert_arg=%d\n", dev->minor,
1211                         cmd->scan_begin_src, cmd->scan_begin_arg,
1212                         cmd->convert_src, cmd->convert_arg);
1213                 dev_dbg(&this_usbduxsub->interface->dev,
1214                         "comedi%d: ao_timer=%d (ms)\n",
1215                         dev->minor, this_usbduxsub->ao_timer);
1216                 if (this_usbduxsub->ao_timer < 1) {
1217                         dev_err(&this_usbduxsub->interface->dev,
1218                                 "comedi%d: usbdux: ao_timer=%d, "
1219                                 "scan_begin_arg=%d. "
1220                                 "Not properly tested by cmdtest?\n",
1221                                 dev->minor, this_usbduxsub->ao_timer,
1222                                 cmd->scan_begin_arg);
1223                         up(&this_usbduxsub->sem);
1224                         return -EINVAL;
1225                 }
1226         }
1227         this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
1228
1229         if (cmd->stop_src == TRIG_COUNT) {
1230                 /* not continuous */
1231                 /* counter */
1232                 /* high speed also scans everything at once */
1233                 if (0) {        /* (this_usbduxsub->high_speed) */
1234                         this_usbduxsub->ao_sample_count =
1235                             (cmd->stop_arg) * (cmd->scan_end_arg);
1236                 } else {
1237                         /* there's no scan as the scan has been */
1238                         /* perf inside the FX2 */
1239                         /* data arrives as one packet */
1240                         this_usbduxsub->ao_sample_count = cmd->stop_arg;
1241                 }
1242                 this_usbduxsub->ao_continuous = 0;
1243         } else {
1244                 /* continuous acquisition */
1245                 this_usbduxsub->ao_continuous = 1;
1246                 this_usbduxsub->ao_sample_count = 0;
1247         }
1248
1249         if (cmd->start_src == TRIG_NOW) {
1250                 /* enable this acquisition operation */
1251                 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbOut,
1252                                               this_usbduxsub->numOfOutBuffers,
1253                                               0);
1254                 if (ret < 0) {
1255                         up(&this_usbduxsub->sem);
1256                         return ret;
1257                 }
1258                 this_usbduxsub->ao_cmd_running = 1;
1259                 s->async->inttrig = NULL;
1260         } else {
1261                 /* TRIG_INT */
1262                 /* submit the urbs later */
1263                 /* wait for an internal signal */
1264                 s->async->inttrig = usbduxsigma_ao_inttrig;
1265         }
1266
1267         up(&this_usbduxsub->sem);
1268         return 0;
1269 }
1270
1271 static int usbdux_dio_insn_config(struct comedi_device *dev,
1272                                   struct comedi_subdevice *s,
1273                                   struct comedi_insn *insn, unsigned int *data)
1274 {
1275         int chan = CR_CHAN(insn->chanspec);
1276
1277         /* The input or output configuration of each digital line is
1278          * configured by a special insn_config instruction.  chanspec
1279          * contains the channel to be changed, and data[0] contains the
1280          * value COMEDI_INPUT or COMEDI_OUTPUT. */
1281
1282         switch (data[0]) {
1283         case INSN_CONFIG_DIO_OUTPUT:
1284                 s->io_bits |= 1 << chan;        /* 1 means Out */
1285                 break;
1286         case INSN_CONFIG_DIO_INPUT:
1287                 s->io_bits &= ~(1 << chan);
1288                 break;
1289         case INSN_CONFIG_DIO_QUERY:
1290                 data[1] =
1291                     (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1292                 break;
1293         default:
1294                 return -EINVAL;
1295                 break;
1296         }
1297         /* we don't tell the firmware here as it would take 8 frames */
1298         /* to submit the information. We do it in the insn_bits. */
1299         return insn->n;
1300 }
1301
1302 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1303                                 struct comedi_subdevice *s,
1304                                 struct comedi_insn *insn,
1305                                 unsigned int *data)
1306 {
1307         struct usbduxsigma_private *this_usbduxsub = dev->private;
1308         int err;
1309
1310         down(&this_usbduxsub->sem);
1311
1312         /* The insn data is a mask in data[0] and the new data
1313          * in data[1], each channel cooresponding to a bit. */
1314         s->state &= ~data[0];
1315         s->state |= data[0] & data[1];
1316         /* The commands are 8 bits wide */
1317         this_usbduxsub->dux_commands[1] = (s->io_bits) & 0x000000FF;
1318         this_usbduxsub->dux_commands[4] = (s->state) & 0x000000FF;
1319         this_usbduxsub->dux_commands[2] = ((s->io_bits) & 0x0000FF00) >> 8;
1320         this_usbduxsub->dux_commands[5] = ((s->state) & 0x0000FF00) >> 8;
1321         this_usbduxsub->dux_commands[3] = ((s->io_bits) & 0x00FF0000) >> 16;
1322         this_usbduxsub->dux_commands[6] = ((s->state) & 0x00FF0000) >> 16;
1323
1324         /* This command also tells the firmware to return */
1325         /* the digital input lines */
1326         err = send_dux_commands(dev, SENDDIOBITSCOMMAND);
1327         if (err < 0) {
1328                 up(&this_usbduxsub->sem);
1329                 return err;
1330         }
1331         err = receive_dux_commands(dev, SENDDIOBITSCOMMAND);
1332         if (err < 0) {
1333                 up(&this_usbduxsub->sem);
1334                 return err;
1335         }
1336
1337         data[1] = (((unsigned int)(this_usbduxsub->insnBuffer[1]))&0xff) |
1338                 ((((unsigned int)(this_usbduxsub->insnBuffer[2]))&0xff) << 8) |
1339                 ((((unsigned int)(this_usbduxsub->insnBuffer[3]))&0xff) << 16);
1340
1341         s->state = data[1];
1342
1343         up(&this_usbduxsub->sem);
1344         return insn->n;
1345 }
1346
1347 static void usbdux_pwm_stop(struct usbduxsigma_private *devpriv, int do_unlink)
1348 {
1349         if (do_unlink) {
1350                 if (devpriv->urbPwm)
1351                         usb_kill_urb(devpriv->urbPwm);
1352         }
1353
1354         devpriv->pwm_cmd_running = 0;
1355 }
1356
1357 static int usbdux_pwm_cancel(struct comedi_device *dev,
1358                              struct comedi_subdevice *s)
1359 {
1360         struct usbduxsigma_private *devpriv = dev->private;
1361
1362         /* unlink only if it is really running */
1363         usbdux_pwm_stop(devpriv, devpriv->pwm_cmd_running);
1364
1365         return send_dux_commands(dev, SENDPWMOFF);
1366 }
1367
1368 static void usbduxsub_pwm_irq(struct urb *urb)
1369 {
1370         struct comedi_device *dev = urb->context;
1371         struct usbduxsigma_private *devpriv = dev->private;
1372         int ret;
1373
1374         switch (urb->status) {
1375         case 0:
1376                 /* success */
1377                 break;
1378
1379         case -ECONNRESET:
1380         case -ENOENT:
1381         case -ESHUTDOWN:
1382         case -ECONNABORTED:
1383                 /* happens after an unlink command */
1384                 if (devpriv->pwm_cmd_running)
1385                         usbdux_pwm_stop(devpriv, 0);    /* w/o unlink */
1386                 return;
1387
1388         default:
1389                 /* a real error */
1390                 if (devpriv->pwm_cmd_running) {
1391                         dev_err(dev->class_dev,
1392                                 "%s: non-zero urb status (%d)\n",
1393                                 __func__, urb->status);
1394                         usbdux_pwm_stop(devpriv, 0);    /* w/o unlink */
1395                 }
1396                 return;
1397         }
1398
1399         if (!devpriv->pwm_cmd_running)
1400                 return;
1401
1402         urb->transfer_buffer_length = devpriv->sizePwmBuf;
1403         urb->dev = comedi_to_usb_dev(dev);
1404         urb->status = 0;
1405         ret = usb_submit_urb(urb, GFP_ATOMIC);
1406         if (ret < 0) {
1407                 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
1408                         __func__, ret);
1409                 if (ret == EL2NSYNC)
1410                         dev_err(dev->class_dev,
1411                                 "buggy USB host controller or bug in IRQ handler\n");
1412                 usbdux_pwm_stop(devpriv, 0);    /* w/o unlink */
1413         }
1414 }
1415
1416 static int usbduxsigma_submit_pwm_urb(struct comedi_device *dev)
1417 {
1418         struct usb_device *usb = comedi_to_usb_dev(dev);
1419         struct usbduxsigma_private *devpriv = dev->private;
1420         struct urb *urb = devpriv->urbPwm;
1421
1422         /* in case of a resubmission after an unlink... */
1423         usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, PWM_EP),
1424                           urb->transfer_buffer, devpriv->sizePwmBuf,
1425                           usbduxsub_pwm_irq, dev);
1426
1427         return usb_submit_urb(urb, GFP_ATOMIC);
1428 }
1429
1430 static int usbdux_pwm_period(struct comedi_device *dev,
1431                              struct comedi_subdevice *s, unsigned int period)
1432 {
1433         struct usbduxsigma_private *this_usbduxsub = dev->private;
1434         int fx2delay = 255;
1435
1436         if (period < MIN_PWM_PERIOD) {
1437                 dev_err(&this_usbduxsub->interface->dev,
1438                         "comedi%d: illegal period setting for pwm.\n",
1439                         dev->minor);
1440                 return -EAGAIN;
1441         } else {
1442                 fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
1443                 if (fx2delay > 255) {
1444                         dev_err(&this_usbduxsub->interface->dev,
1445                                 "comedi%d: period %d for pwm is too low.\n",
1446                                 dev->minor, period);
1447                         return -EAGAIN;
1448                 }
1449         }
1450         this_usbduxsub->pwmDelay = fx2delay;
1451         this_usbduxsub->pwmPeriod = period;
1452         return 0;
1453 }
1454
1455 /* is called from insn so there's no need to do all the sanity checks */
1456 static int usbdux_pwm_start(struct comedi_device *dev,
1457                             struct comedi_subdevice *s)
1458 {
1459         struct usbduxsigma_private *this_usbduxsub = dev->private;
1460         int ret, i;
1461
1462         if (this_usbduxsub->pwm_cmd_running) {
1463                 /* already running */
1464                 return 0;
1465         }
1466
1467         this_usbduxsub->dux_commands[1] = ((uint8_t) this_usbduxsub->pwmDelay);
1468         ret = send_dux_commands(dev, SENDPWMON);
1469         if (ret < 0)
1470                 return ret;
1471
1472         /* initialise the buffer */
1473         for (i = 0; i < this_usbduxsub->sizePwmBuf; i++)
1474                 ((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0;
1475
1476         ret = usbduxsigma_submit_pwm_urb(dev);
1477         if (ret < 0)
1478                 return ret;
1479         this_usbduxsub->pwm_cmd_running = 1;
1480
1481         return 0;
1482 }
1483
1484 /* generates the bit pattern for PWM with the optional sign bit */
1485 static int usbdux_pwm_pattern(struct comedi_device *dev,
1486                               struct comedi_subdevice *s, int channel,
1487                               unsigned int value, unsigned int sign)
1488 {
1489         struct usbduxsigma_private *this_usbduxsub = dev->private;
1490         int i, szbuf;
1491         char *pBuf;
1492         char pwm_mask;
1493         char sgn_mask;
1494         char c;
1495
1496         /* this is the DIO bit which carries the PWM data */
1497         pwm_mask = (1 << channel);
1498         /* this is the DIO bit which carries the optional direction bit */
1499         sgn_mask = (16 << channel);
1500         /* this is the buffer which will be filled with the with bit */
1501         /* pattern for one period */
1502         szbuf = this_usbduxsub->sizePwmBuf;
1503         pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer);
1504         for (i = 0; i < szbuf; i++) {
1505                 c = *pBuf;
1506                 /* reset bits */
1507                 c = c & (~pwm_mask);
1508                 /* set the bit as long as the index is lower than the value */
1509                 if (i < value)
1510                         c = c | pwm_mask;
1511                 /* set the optional sign bit for a relay */
1512                 if (!sign) {
1513                         /* positive value */
1514                         c = c & (~sgn_mask);
1515                 } else {
1516                         /* negative value */
1517                         c = c | sgn_mask;
1518                 }
1519                 *(pBuf++) = c;
1520         }
1521         return 1;
1522 }
1523
1524 static int usbdux_pwm_write(struct comedi_device *dev,
1525                             struct comedi_subdevice *s,
1526                             struct comedi_insn *insn, unsigned int *data)
1527 {
1528         if ((insn->n) != 1) {
1529                 /*
1530                  * doesn't make sense to have more than one value here because
1531                  * it would just overwrite the PWM buffer a couple of times
1532                  */
1533                 return -EINVAL;
1534         }
1535
1536         /*
1537          * the sign is set via a special INSN only, this gives us 8 bits for
1538          * normal operation
1539          * relay sign 0 by default
1540          */
1541         return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
1542 }
1543
1544 static int usbdux_pwm_read(struct comedi_device *x1,
1545                            struct comedi_subdevice *x2, struct comedi_insn *x3,
1546                            unsigned int *x4)
1547 {
1548         /* not needed */
1549         return -EINVAL;
1550 };
1551
1552 /* switches on/off PWM */
1553 static int usbdux_pwm_config(struct comedi_device *dev,
1554                              struct comedi_subdevice *s,
1555                              struct comedi_insn *insn, unsigned int *data)
1556 {
1557         struct usbduxsigma_private *this_usbduxsub = dev->private;
1558         switch (data[0]) {
1559         case INSN_CONFIG_ARM:
1560                 /* switch it on */
1561                 /*
1562                  * if not zero the PWM is limited to a certain time which is
1563                  * not supported here
1564                  */
1565                 if (data[1] != 0)
1566                         return -EINVAL;
1567                 return usbdux_pwm_start(dev, s);
1568         case INSN_CONFIG_DISARM:
1569                 return usbdux_pwm_cancel(dev, s);
1570         case INSN_CONFIG_GET_PWM_STATUS:
1571                 /*
1572                  * to check if the USB transmission has failed or in case PWM
1573                  * was limited to n cycles to check if it has terminated
1574                  */
1575                 data[1] = this_usbduxsub->pwm_cmd_running;
1576                 return 0;
1577         case INSN_CONFIG_PWM_SET_PERIOD:
1578                 return usbdux_pwm_period(dev, s, data[1]);
1579         case INSN_CONFIG_PWM_GET_PERIOD:
1580                 data[1] = this_usbduxsub->pwmPeriod;
1581                 return 0;
1582         case INSN_CONFIG_PWM_SET_H_BRIDGE:
1583                 /* value in the first byte and the sign in the second for a
1584                    relay */
1585                 return usbdux_pwm_pattern(dev, s,
1586                                           /* the channel number */
1587                                           CR_CHAN(insn->chanspec),
1588                                           /* actual PWM data */
1589                                           data[1],
1590                                           /* just a sign */
1591                                           (data[2] != 0));
1592         case INSN_CONFIG_PWM_GET_H_BRIDGE:
1593                 /* values are not kept in this driver, nothing to return */
1594                 return -EINVAL;
1595         }
1596         return -EINVAL;
1597 }
1598
1599 /* end of PWM */
1600 /*****************************************************************/
1601
1602 static void tidy_up(struct usbduxsigma_private *usbduxsub_tmp)
1603 {
1604         int i;
1605
1606         /* shows the usb subsystem that the driver is down */
1607         if (usbduxsub_tmp->interface)
1608                 usb_set_intfdata(usbduxsub_tmp->interface, NULL);
1609
1610         if (usbduxsub_tmp->urbIn) {
1611                 /* force unlink all urbs */
1612                 usbdux_ai_stop(usbduxsub_tmp, 1);
1613                 for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
1614                         kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer);
1615                         usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL;
1616                         usb_free_urb(usbduxsub_tmp->urbIn[i]);
1617                         usbduxsub_tmp->urbIn[i] = NULL;
1618                 }
1619                 kfree(usbduxsub_tmp->urbIn);
1620                 usbduxsub_tmp->urbIn = NULL;
1621         }
1622         if (usbduxsub_tmp->urbOut) {
1623                 /* force unlink all urbs */
1624                 usbdux_ao_stop(usbduxsub_tmp, 1);
1625                 for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
1626                         if (usbduxsub_tmp->urbOut[i]->transfer_buffer) {
1627                                 kfree(usbduxsub_tmp->
1628                                       urbOut[i]->transfer_buffer);
1629                                 usbduxsub_tmp->urbOut[i]->transfer_buffer =
1630                                     NULL;
1631                         }
1632                         if (usbduxsub_tmp->urbOut[i]) {
1633                                 usb_free_urb(usbduxsub_tmp->urbOut[i]);
1634                                 usbduxsub_tmp->urbOut[i] = NULL;
1635                         }
1636                 }
1637                 kfree(usbduxsub_tmp->urbOut);
1638                 usbduxsub_tmp->urbOut = NULL;
1639         }
1640         if (usbduxsub_tmp->urbPwm) {
1641                 /* force unlink urb */
1642                 usbdux_pwm_stop(usbduxsub_tmp, 1);
1643                 kfree(usbduxsub_tmp->urbPwm->transfer_buffer);
1644                 usbduxsub_tmp->urbPwm->transfer_buffer = NULL;
1645                 usb_free_urb(usbduxsub_tmp->urbPwm);
1646                 usbduxsub_tmp->urbPwm = NULL;
1647         }
1648         kfree(usbduxsub_tmp->inBuffer);
1649         usbduxsub_tmp->inBuffer = NULL;
1650         kfree(usbduxsub_tmp->insnBuffer);
1651         usbduxsub_tmp->insnBuffer = NULL;
1652         kfree(usbduxsub_tmp->outBuffer);
1653         usbduxsub_tmp->outBuffer = NULL;
1654         kfree(usbduxsub_tmp->dac_commands);
1655         usbduxsub_tmp->dac_commands = NULL;
1656         kfree(usbduxsub_tmp->dux_commands);
1657         usbduxsub_tmp->dux_commands = NULL;
1658 }
1659
1660 static int usbduxsigma_attach_common(struct comedi_device *dev)
1661 {
1662         struct usbduxsigma_private *uds = dev->private;
1663         int ret;
1664         struct comedi_subdevice *s;
1665         int n_subdevs;
1666         int offset;
1667
1668         down(&uds->sem);
1669
1670         /* set number of subdevices */
1671         if (uds->high_speed)
1672                 n_subdevs = 4;  /* with pwm */
1673         else
1674                 n_subdevs = 3;  /* without pwm */
1675         ret = comedi_alloc_subdevices(dev, n_subdevs);
1676         if (ret) {
1677                 up(&uds->sem);
1678                 return ret;
1679         }
1680         /* the first subdevice is the A/D converter */
1681         s = &dev->subdevices[SUBDEV_AD];
1682         /* the URBs get the comedi subdevice */
1683         /* which is responsible for reading */
1684         /* this is the subdevice which reads data */
1685         dev->read_subdev = s;
1686         /* the subdevice receives as private structure the */
1687         /* usb-structure */
1688         s->private = NULL;
1689         /* analog input */
1690         s->type = COMEDI_SUBD_AI;
1691         /* readable and ref is to ground, 32 bit wide data! */
1692         s->subdev_flags = SDF_READABLE | SDF_GROUND |
1693                 SDF_CMD_READ | SDF_LSAMPL;
1694         /* 16 A/D channels */
1695         s->n_chan = NUMCHANNELS;
1696         /* length of the channellist */
1697         s->len_chanlist = NUMCHANNELS;
1698         /* callback functions */
1699         s->insn_read = usbdux_ai_insn_read;
1700         s->do_cmdtest = usbdux_ai_cmdtest;
1701         s->do_cmd = usbdux_ai_cmd;
1702         s->cancel = usbdux_ai_cancel;
1703         /* max value from the A/D converter (24bit) */
1704         s->maxdata = 0x00FFFFFF;
1705         /* range table to convert to physical units */
1706         s->range_table = (&range_usbdux_ai_range);
1707         /* analog output subdevice */
1708         s = &dev->subdevices[SUBDEV_DA];
1709         /* analog out */
1710         s->type = COMEDI_SUBD_AO;
1711         /* backward pointer */
1712         dev->write_subdev = s;
1713         /* the subdevice receives as private structure the */
1714         /* usb-structure */
1715         s->private = NULL;
1716         /* are writable */
1717         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1718         /* 4 channels */
1719         s->n_chan = 4;
1720         /* length of the channellist */
1721         s->len_chanlist = 4;
1722         /* 8 bit resolution */
1723         s->maxdata = 0x00ff;
1724         /* unipolar range */
1725         s->range_table = &range_unipolar2_5;
1726         /* callback */
1727         s->do_cmdtest = usbdux_ao_cmdtest;
1728         s->do_cmd = usbdux_ao_cmd;
1729         s->cancel = usbdux_ao_cancel;
1730         s->insn_read = usbdux_ao_insn_read;
1731         s->insn_write = usbdux_ao_insn_write;
1732         /* digital I/O subdevice */
1733         s = &dev->subdevices[SUBDEV_DIO];
1734         s->type = COMEDI_SUBD_DIO;
1735         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1736         /* 8 external and 16 internal channels */
1737         s->n_chan = 24;
1738         s->maxdata = 1;
1739         s->range_table = (&range_digital);
1740         s->insn_bits = usbdux_dio_insn_bits;
1741         s->insn_config = usbdux_dio_insn_config;
1742         /* we don't use it */
1743         s->private = NULL;
1744         if (uds->high_speed) {
1745                 /* timer / pwm subdevice */
1746                 s = &dev->subdevices[SUBDEV_PWM];
1747                 s->type = COMEDI_SUBD_PWM;
1748                 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1749                 s->n_chan = 8;
1750                 /* this defines the max duty cycle resolution */
1751                 s->maxdata = uds->sizePwmBuf;
1752                 s->insn_write = usbdux_pwm_write;
1753                 s->insn_read = usbdux_pwm_read;
1754                 s->insn_config = usbdux_pwm_config;
1755                 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1756         }
1757         up(&uds->sem);
1758         offset = usbdux_getstatusinfo(dev, 0);
1759         if (offset < 0)
1760                 dev_err(&uds->interface->dev,
1761                         "Communication to USBDUXSIGMA failed! Check firmware and cabling.");
1762         dev_info(&uds->interface->dev,
1763                  "comedi%d: attached, ADC_zero = %x\n", dev->minor, offset);
1764         return 0;
1765 }
1766
1767 static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev)
1768 {
1769         struct usb_device *usb = comedi_to_usb_dev(dev);
1770         struct usbduxsigma_private *devpriv = dev->private;
1771         struct urb *urb;
1772         int i;
1773
1774         devpriv->dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
1775         devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1776         devpriv->inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1777         devpriv->insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1778         devpriv->outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1779         devpriv->urbIn = kcalloc(devpriv->numOfInBuffers, sizeof(*urb),
1780                                  GFP_KERNEL);
1781         devpriv->urbOut = kcalloc(devpriv->numOfOutBuffers, sizeof(*urb),
1782                                   GFP_KERNEL);
1783         if (!devpriv->dac_commands || !devpriv->dux_commands ||
1784             !devpriv->inBuffer || !devpriv->insnBuffer ||
1785             !devpriv->outBuffer || !devpriv->urbIn || !devpriv->urbOut)
1786                 return -ENOMEM;
1787
1788         for (i = 0; i < devpriv->numOfInBuffers; i++) {
1789                 /* one frame: 1ms */
1790                 urb = usb_alloc_urb(1, GFP_KERNEL);
1791                 if (!urb)
1792                         return -ENOMEM;
1793                 devpriv->urbIn[i] = urb;
1794                 urb->dev = usb;
1795                 /* will be filled later with a pointer to the comedi-device */
1796                 /* and ONLY then the urb should be submitted */
1797                 urb->context = NULL;
1798                 urb->pipe = usb_rcvisocpipe(usb, ISOINEP);
1799                 urb->transfer_flags = URB_ISO_ASAP;
1800                 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1801                 if (!urb->transfer_buffer)
1802                         return -ENOMEM;
1803                 urb->complete = usbduxsub_ai_IsocIrq;
1804                 urb->number_of_packets = 1;
1805                 urb->transfer_buffer_length = SIZEINBUF;
1806                 urb->iso_frame_desc[0].offset = 0;
1807                 urb->iso_frame_desc[0].length = SIZEINBUF;
1808         }
1809
1810         for (i = 0; i < devpriv->numOfOutBuffers; i++) {
1811                 /* one frame: 1ms */
1812                 urb = usb_alloc_urb(1, GFP_KERNEL);
1813                 if (!urb)
1814                         return -ENOMEM;
1815                 devpriv->urbOut[i] = urb;
1816                 urb->dev = usb;
1817                 /* will be filled later with a pointer to the comedi-device */
1818                 /* and ONLY then the urb should be submitted */
1819                 urb->context = NULL;
1820                 urb->pipe = usb_sndisocpipe(usb, ISOOUTEP);
1821                 urb->transfer_flags = URB_ISO_ASAP;
1822                 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1823                 if (!urb->transfer_buffer)
1824                         return -ENOMEM;
1825                 urb->complete = usbduxsub_ao_IsocIrq;
1826                 urb->number_of_packets = 1;
1827                 urb->transfer_buffer_length = SIZEOUTBUF;
1828                 urb->iso_frame_desc[0].offset = 0;
1829                 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1830                 if (devpriv->high_speed)
1831                         urb->interval = 8;      /* uframes */
1832                 else
1833                         urb->interval = 1;      /* frames */
1834         }
1835
1836         if (devpriv->high_speed) {
1837                 /* max bulk ep size in high speed */
1838                 devpriv->sizePwmBuf = 512;
1839                 urb = usb_alloc_urb(0, GFP_KERNEL);
1840                 if (!urb)
1841                         return -ENOMEM;
1842                 devpriv->urbPwm = urb;
1843                 urb->transfer_buffer = kzalloc(devpriv->sizePwmBuf, GFP_KERNEL);
1844                 if (!urb->transfer_buffer)
1845                         return -ENOMEM;
1846         } else {
1847                 devpriv->urbPwm = NULL;
1848                 devpriv->sizePwmBuf = 0;
1849         }
1850
1851         return 0;
1852 }
1853
1854 static int usbduxsigma_auto_attach(struct comedi_device *dev,
1855                                    unsigned long context_unused)
1856 {
1857         struct usb_interface *intf = comedi_to_usb_interface(dev);
1858         struct usb_device *usb = comedi_to_usb_dev(dev);
1859         struct usbduxsigma_private *devpriv;
1860         int ret;
1861
1862         devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1863         if (!devpriv)
1864                 return -ENOMEM;
1865         dev->private = devpriv;
1866
1867         sema_init(&devpriv->sem, 1);
1868         devpriv->interface = intf;
1869         usb_set_intfdata(intf, devpriv);
1870
1871         ret = usb_set_interface(usb,
1872                                 intf->altsetting->desc.bInterfaceNumber, 3);
1873         if (ret < 0) {
1874                 dev_err(dev->class_dev,
1875                         "could not set alternate setting 3 in high speed\n");
1876                 return -ENODEV;
1877         }
1878
1879         /* test if it is high speed (USB 2.0) */
1880         devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1881         if (devpriv->high_speed) {
1882                 devpriv->numOfInBuffers = NUMOFINBUFFERSHIGH;
1883                 devpriv->numOfOutBuffers = NUMOFOUTBUFFERSHIGH;
1884         } else {
1885                 devpriv->numOfInBuffers = NUMOFINBUFFERSFULL;
1886                 devpriv->numOfOutBuffers = NUMOFOUTBUFFERSFULL;
1887         }
1888
1889         ret = usbduxsigma_alloc_usb_buffers(dev);
1890         if (ret) {
1891                 tidy_up(devpriv);
1892                 return ret;
1893         }
1894
1895         ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1896                                    usbduxsigma_firmware_upload, 0);
1897         if (ret)
1898                 return ret;
1899
1900         return usbduxsigma_attach_common(dev);
1901 }
1902
1903 static void usbduxsigma_detach(struct comedi_device *dev)
1904 {
1905         struct usbduxsigma_private *devpriv = dev->private;
1906
1907         if (!devpriv)
1908                 return;
1909
1910         /* stop any running commands */
1911         usbdux_ai_stop(devpriv, devpriv->ai_cmd_running);
1912         usbdux_ao_stop(devpriv, devpriv->ao_cmd_running);
1913
1914         down(&devpriv->sem);
1915         tidy_up(devpriv);
1916         up(&devpriv->sem);
1917 }
1918
1919 static struct comedi_driver usbduxsigma_driver = {
1920         .driver_name    = "usbduxsigma",
1921         .module         = THIS_MODULE,
1922         .auto_attach    = usbduxsigma_auto_attach,
1923         .detach         = usbduxsigma_detach,
1924 };
1925
1926 static int usbduxsigma_usb_probe(struct usb_interface *intf,
1927                                  const struct usb_device_id *id)
1928 {
1929         return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0);;
1930 }
1931
1932 static const struct usb_device_id usbduxsigma_usb_table[] = {
1933         { USB_DEVICE(0x13d8, 0x0020) },
1934         { USB_DEVICE(0x13d8, 0x0021) },
1935         { USB_DEVICE(0x13d8, 0x0022) },
1936         { }
1937 };
1938 MODULE_DEVICE_TABLE(usb, usbduxsigma_usb_table);
1939
1940 static struct usb_driver usbduxsigma_usb_driver = {
1941         .name           = "usbduxsigma",
1942         .probe          = usbduxsigma_usb_probe,
1943         .disconnect     = comedi_usb_auto_unconfig,
1944         .id_table       = usbduxsigma_usb_table,
1945 };
1946 module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver);
1947
1948 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1949 MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com");
1950 MODULE_LICENSE("GPL");
1951 MODULE_FIRMWARE(FIRMWARE);