]> Pileus Git - ~andy/linux/blob - drivers/staging/comedi/drivers/usbduxsigma.c
staging: comedi: usbduxsigma: tidy up usbdux_ao_inttrig()
[~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 usbdux_ai_inttrig(struct comedi_device *dev,
758                              struct comedi_subdevice *s, unsigned int trignum)
759 {
760         struct usbduxsigma_private *this_usbduxsub = dev->private;
761         int ret;
762
763         down(&this_usbduxsub->sem);
764         if (trignum != 0) {
765                 dev_err(&this_usbduxsub->interface->dev,
766                         "comedi%d: usbdux_ai_inttrig: invalid trignum\n",
767                         dev->minor);
768                 up(&this_usbduxsub->sem);
769                 return -EINVAL;
770         }
771         if (!this_usbduxsub->ai_cmd_running) {
772                 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbIn,
773                                               this_usbduxsub->numOfInBuffers,
774                                               1);
775                 if (ret < 0) {
776                         up(&this_usbduxsub->sem);
777                         return ret;
778                 }
779                 this_usbduxsub->ai_cmd_running = 1;
780                 s->async->inttrig = NULL;
781         } else {
782                 dev_err(&this_usbduxsub->interface->dev,
783                         "comedi%d: ai_inttrig but acqu is already running\n",
784                         dev->minor);
785         }
786         up(&this_usbduxsub->sem);
787         return 1;
788 }
789
790 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
791 {
792         struct usbduxsigma_private *this_usbduxsub = dev->private;
793         struct comedi_cmd *cmd = &s->async->cmd;
794         unsigned int chan;
795         int i, ret;
796         int result;
797         uint8_t muxsg0 = 0;
798         uint8_t muxsg1 = 0;
799         uint8_t sysred = 0;
800
801         /* block other CPUs from starting an ai_cmd */
802         down(&this_usbduxsub->sem);
803         if (this_usbduxsub->ai_cmd_running) {
804                 dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
805                         "ai_cmd not possible. Another ai_cmd is running.\n",
806                         dev->minor);
807                 up(&this_usbduxsub->sem);
808                 return -EBUSY;
809         }
810         /* set current channel of the running acquisition to zero */
811         s->async->cur_chan = 0;
812
813         /* first the number of channels per time step */
814         this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
815
816         /* CONFIG0 */
817         this_usbduxsub->dux_commands[2] = 0x12;
818
819         /* CONFIG1: 23kHz sampling rate, delay = 0us,  */
820         this_usbduxsub->dux_commands[3] = 0x03;
821
822         /* CONFIG3: differential channels off */
823         this_usbduxsub->dux_commands[4] = 0x00;
824
825         for (i = 0; i < cmd->chanlist_len; i++) {
826                 chan = CR_CHAN(cmd->chanlist[i]);
827                 create_adc_command(chan, &muxsg0, &muxsg1);
828                 if (i >= NUMCHANNELS) {
829                         dev_err(&this_usbduxsub->interface->dev,
830                                 "comedi%d: channel list too long\n",
831                                 dev->minor);
832                         break;
833                 }
834         }
835         this_usbduxsub->dux_commands[5] = muxsg0;
836         this_usbduxsub->dux_commands[6] = muxsg1;
837         this_usbduxsub->dux_commands[7] = sysred;
838
839         result = send_dux_commands(dev, SENDADCOMMANDS);
840         if (result < 0) {
841                 up(&this_usbduxsub->sem);
842                 return result;
843         }
844
845         if (this_usbduxsub->high_speed) {
846                 /*
847                  * every 2 channels get a time window of 125us. Thus, if we
848                  * sample all 16 channels we need 1ms. If we sample only one
849                  * channel we need only 125us
850                  */
851                 this_usbduxsub->ai_interval =
852                         chanToInterval(cmd->chanlist_len);
853                 this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
854                                                           (this_usbduxsub->
855                                                            ai_interval));
856         } else {
857                 /* interval always 1ms */
858                 this_usbduxsub->ai_interval = 1;
859                 this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000;
860         }
861         if (this_usbduxsub->ai_timer < 1) {
862                 dev_err(&this_usbduxsub->interface->dev, "comedi%d: ai_cmd: "
863                         "timer=%d, scan_begin_arg=%d. "
864                         "Not properly tested by cmdtest?\n", dev->minor,
865                         this_usbduxsub->ai_timer, cmd->scan_begin_arg);
866                 up(&this_usbduxsub->sem);
867                 return -EINVAL;
868         }
869         this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
870
871         if (cmd->stop_src == TRIG_COUNT) {
872                 /* data arrives as one packet */
873                 this_usbduxsub->ai_sample_count = cmd->stop_arg;
874                 this_usbduxsub->ai_continuous = 0;
875         } else {
876                 /* continuous acquisition */
877                 this_usbduxsub->ai_continuous = 1;
878                 this_usbduxsub->ai_sample_count = 0;
879         }
880
881         if (cmd->start_src == TRIG_NOW) {
882                 /* enable this acquisition operation */
883                 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbIn,
884                                               this_usbduxsub->numOfInBuffers,
885                                               1);
886                 if (ret < 0) {
887                         up(&this_usbduxsub->sem);
888                         return ret;
889                 }
890                 this_usbduxsub->ai_cmd_running = 1;
891                 s->async->inttrig = NULL;
892         } else {
893                 /* TRIG_INT */
894                 /* don't enable the acquision operation */
895                 /* wait for an internal signal */
896                 s->async->inttrig = usbdux_ai_inttrig;
897         }
898         up(&this_usbduxsub->sem);
899         return 0;
900 }
901
902 /* Mode 0 is used to get a single conversion on demand */
903 static int usbdux_ai_insn_read(struct comedi_device *dev,
904                                struct comedi_subdevice *s,
905                                struct comedi_insn *insn, unsigned int *data)
906 {
907         struct usbduxsigma_private *this_usbduxsub = dev->private;
908         int i;
909         int32_t one = 0;
910         int chan;
911         int err;
912         uint8_t muxsg0 = 0;
913         uint8_t muxsg1 = 0;
914         uint8_t sysred = 0;
915
916         down(&this_usbduxsub->sem);
917         if (this_usbduxsub->ai_cmd_running) {
918                 dev_err(&this_usbduxsub->interface->dev,
919                         "comedi%d: ai_insn_read not possible. "
920                         "Async Command is running.\n", dev->minor);
921                 up(&this_usbduxsub->sem);
922                 return 0;
923         }
924
925         /* sample one channel */
926         /* CONFIG0: chopper on */
927         this_usbduxsub->dux_commands[1] = 0x16;
928
929         /* CONFIG1: 2kHz sampling rate */
930         this_usbduxsub->dux_commands[2] = 0x80;
931
932         /* CONFIG3: differential channels off */
933         this_usbduxsub->dux_commands[3] = 0x00;
934
935         chan = CR_CHAN(insn->chanspec);
936         create_adc_command(chan, &muxsg0, &muxsg1);
937
938         this_usbduxsub->dux_commands[4] = muxsg0;
939         this_usbduxsub->dux_commands[5] = muxsg1;
940         this_usbduxsub->dux_commands[6] = sysred;
941
942         /* adc commands */
943         err = send_dux_commands(dev, SENDSINGLEAD);
944         if (err < 0) {
945                 up(&this_usbduxsub->sem);
946                 return err;
947         }
948
949         for (i = 0; i < insn->n; i++) {
950                 err = receive_dux_commands(dev, SENDSINGLEAD);
951                 if (err < 0) {
952                         up(&this_usbduxsub->sem);
953                         return 0;
954                 }
955                 /* 32 bits big endian from the A/D converter */
956                 one = be32_to_cpu(*((int32_t *)
957                                     ((this_usbduxsub->insnBuffer)+1)));
958                 /* mask out the status byte */
959                 one = one & 0x00ffffff;
960                 /* turn it into an unsigned integer */
961                 one = one ^ 0x00800000;
962                 data[i] = one;
963         }
964         up(&this_usbduxsub->sem);
965         return i;
966 }
967
968
969
970
971 static int usbdux_getstatusinfo(struct comedi_device *dev, int chan)
972 {
973         struct usbduxsigma_private *this_usbduxsub = dev->private;
974         uint8_t sysred = 0;
975         uint32_t one;
976         int err;
977
978         if (this_usbduxsub->ai_cmd_running) {
979                 dev_err(&this_usbduxsub->interface->dev,
980                         "comedi%d: status read not possible. "
981                         "Async Command is running.\n", dev->minor);
982                 return 0;
983         }
984
985         /* CONFIG0 */
986         this_usbduxsub->dux_commands[1] = 0x12;
987
988         /* CONFIG1: 2kHz sampling rate */
989         this_usbduxsub->dux_commands[2] = 0x80;
990
991         /* CONFIG3: differential channels off */
992         this_usbduxsub->dux_commands[3] = 0x00;
993
994         if (chan == 1) {
995                 /* ADC offset */
996                 sysred = sysred | 1;
997         } else if (chan == 2) {
998                 /* VCC */
999                 sysred = sysred | 4;
1000         } else if (chan == 3) {
1001                 /* temperature */
1002                 sysred = sysred | 8;
1003         } else if (chan == 4) {
1004                 /* gain */
1005                 sysred = sysred | 16;
1006         } else if (chan == 5) {
1007                 /* ref */
1008                 sysred = sysred | 32;
1009         }
1010
1011         this_usbduxsub->dux_commands[4] = 0;
1012         this_usbduxsub->dux_commands[5] = 0;
1013         this_usbduxsub->dux_commands[6] = sysred;
1014
1015         /* adc commands */
1016         err = send_dux_commands(dev, SENDSINGLEAD);
1017         if (err < 0)
1018                 return err;
1019
1020         err = receive_dux_commands(dev, SENDSINGLEAD);
1021         if (err < 0)
1022                 return err;
1023
1024         /* 32 bits big endian from the A/D converter */
1025         one = be32_to_cpu(*((int32_t *)((this_usbduxsub->insnBuffer)+1)));
1026         /* mask out the status byte */
1027         one = one & 0x00ffffff;
1028         one = one ^ 0x00800000;
1029
1030         return (int)one;
1031 }
1032
1033
1034
1035
1036
1037
1038 /************************************/
1039 /* analog out */
1040
1041 static int usbdux_ao_insn_read(struct comedi_device *dev,
1042                                struct comedi_subdevice *s,
1043                                struct comedi_insn *insn, unsigned int *data)
1044 {
1045         struct usbduxsigma_private *this_usbduxsub = dev->private;
1046         int i;
1047         int chan = CR_CHAN(insn->chanspec);
1048
1049         down(&this_usbduxsub->sem);
1050         for (i = 0; i < insn->n; i++)
1051                 data[i] = this_usbduxsub->outBuffer[chan];
1052
1053         up(&this_usbduxsub->sem);
1054         return i;
1055 }
1056
1057 static int usbdux_ao_insn_write(struct comedi_device *dev,
1058                                 struct comedi_subdevice *s,
1059                                 struct comedi_insn *insn, unsigned int *data)
1060 {
1061         struct usbduxsigma_private *this_usbduxsub = dev->private;
1062         int i, err;
1063         int chan = CR_CHAN(insn->chanspec);
1064
1065         down(&this_usbduxsub->sem);
1066         if (this_usbduxsub->ao_cmd_running) {
1067                 dev_err(&this_usbduxsub->interface->dev,
1068                         "comedi%d: ao_insn_write: "
1069                         "ERROR: asynchronous ao_cmd is running\n", dev->minor);
1070                 up(&this_usbduxsub->sem);
1071                 return 0;
1072         }
1073
1074         for (i = 0; i < insn->n; i++) {
1075                 dev_dbg(&this_usbduxsub->interface->dev,
1076                         "comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n",
1077                         dev->minor, chan, i, data[i]);
1078
1079                 /* number of channels: 1 */
1080                 this_usbduxsub->dux_commands[1] = 1;
1081                 /* channel number */
1082                 this_usbduxsub->dux_commands[2] = data[i];
1083                 this_usbduxsub->outBuffer[chan] = data[i];
1084                 this_usbduxsub->dux_commands[3] = chan;
1085                 err = send_dux_commands(dev, SENDDACOMMANDS);
1086                 if (err < 0) {
1087                         up(&this_usbduxsub->sem);
1088                         return err;
1089                 }
1090         }
1091         up(&this_usbduxsub->sem);
1092
1093         return i;
1094 }
1095
1096 static int usbduxsigma_ao_inttrig(struct comedi_device *dev,
1097                                   struct comedi_subdevice *s,
1098                                   unsigned int trignum)
1099 {
1100         struct usbduxsigma_private *devpriv = dev->private;
1101         int ret;
1102
1103         if (trignum != 0)
1104                 return -EINVAL;
1105
1106         down(&devpriv->sem);
1107         if (!devpriv->ao_cmd_running) {
1108                 ret = usbduxsigma_submit_urbs(dev, devpriv->urbOut,
1109                                               devpriv->numOfOutBuffers, 0);
1110                 if (ret < 0) {
1111                         up(&devpriv->sem);
1112                         return ret;
1113                 }
1114                 devpriv->ao_cmd_running = 1;
1115                 s->async->inttrig = NULL;
1116         }
1117         up(&devpriv->sem);
1118
1119         return 1;
1120 }
1121
1122 static int usbdux_ao_cmdtest(struct comedi_device *dev,
1123                              struct comedi_subdevice *s,
1124                              struct comedi_cmd *cmd)
1125 {
1126         int err = 0;
1127         unsigned int flags;
1128
1129         /* Step 1 : check if triggers are trivially valid */
1130
1131         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
1132
1133         if (0) {                /* (this_usbduxsub->high_speed) */
1134                 /*
1135                  * start immediately a new scan
1136                  * the sampling rate is set by the coversion rate
1137                  */
1138                 flags = TRIG_FOLLOW;
1139         } else {
1140                 /* start a new scan (output at once) with a timer */
1141                 flags = TRIG_TIMER;
1142         }
1143         err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
1144
1145         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1146         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1147         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1148
1149         if (err)
1150                 return 1;
1151
1152         /* Step 2a : make sure trigger sources are unique */
1153
1154         err |= cfc_check_trigger_is_unique(cmd->start_src);
1155         err |= cfc_check_trigger_is_unique(cmd->stop_src);
1156
1157         /* Step 2b : and mutually compatible */
1158
1159         if (err)
1160                 return 2;
1161
1162         /* Step 3: check if arguments are trivially valid */
1163
1164         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1165
1166         if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
1167                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1168
1169         if (cmd->scan_begin_src == TRIG_TIMER)
1170                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1171                                                  1000000);
1172
1173         /* not used now, is for later use */
1174         if (cmd->convert_src == TRIG_TIMER)
1175                 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
1176
1177         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1178
1179         if (cmd->stop_src == TRIG_COUNT) {
1180                 /* any count is allowed */
1181         } else {
1182                 /* TRIG_NONE */
1183                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1184         }
1185
1186         if (err)
1187                 return 3;
1188
1189         return 0;
1190 }
1191
1192 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1193 {
1194         struct usbduxsigma_private *this_usbduxsub = dev->private;
1195         struct comedi_cmd *cmd = &s->async->cmd;
1196         unsigned int chan, gain;
1197         int i, ret;
1198
1199         down(&this_usbduxsub->sem);
1200         /* set current channel of the running acquisition to zero */
1201         s->async->cur_chan = 0;
1202         for (i = 0; i < cmd->chanlist_len; ++i) {
1203                 chan = CR_CHAN(cmd->chanlist[i]);
1204                 gain = CR_RANGE(cmd->chanlist[i]);
1205                 if (i >= NUMOUTCHANNELS) {
1206                         dev_err(&this_usbduxsub->interface->dev,
1207                                 "comedi%d: %s: channel list too long\n",
1208                                 dev->minor, __func__);
1209                         break;
1210                 }
1211                 this_usbduxsub->dac_commands[i] = chan;
1212                 dev_dbg(&this_usbduxsub->interface->dev,
1213                         "comedi%d: dac command for ch %d is %x\n",
1214                         dev->minor, i, this_usbduxsub->dac_commands[i]);
1215         }
1216
1217         /* we count in steps of 1ms (125us) */
1218         /* 125us mode not used yet */
1219         if (0) {                /* (this_usbduxsub->high_speed) */
1220                 /* 125us */
1221                 /* timing of the conversion itself: every 125 us */
1222                 this_usbduxsub->ao_timer = cmd->convert_arg / 125000;
1223         } else {
1224                 /* 1ms */
1225                 /* timing of the scan: we get all channels at once */
1226                 this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000;
1227                 dev_dbg(&this_usbduxsub->interface->dev,
1228                         "comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
1229                         "convert_src=%d, convert_arg=%d\n", dev->minor,
1230                         cmd->scan_begin_src, cmd->scan_begin_arg,
1231                         cmd->convert_src, cmd->convert_arg);
1232                 dev_dbg(&this_usbduxsub->interface->dev,
1233                         "comedi%d: ao_timer=%d (ms)\n",
1234                         dev->minor, this_usbduxsub->ao_timer);
1235                 if (this_usbduxsub->ao_timer < 1) {
1236                         dev_err(&this_usbduxsub->interface->dev,
1237                                 "comedi%d: usbdux: ao_timer=%d, "
1238                                 "scan_begin_arg=%d. "
1239                                 "Not properly tested by cmdtest?\n",
1240                                 dev->minor, this_usbduxsub->ao_timer,
1241                                 cmd->scan_begin_arg);
1242                         up(&this_usbduxsub->sem);
1243                         return -EINVAL;
1244                 }
1245         }
1246         this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
1247
1248         if (cmd->stop_src == TRIG_COUNT) {
1249                 /* not continuous */
1250                 /* counter */
1251                 /* high speed also scans everything at once */
1252                 if (0) {        /* (this_usbduxsub->high_speed) */
1253                         this_usbduxsub->ao_sample_count =
1254                             (cmd->stop_arg) * (cmd->scan_end_arg);
1255                 } else {
1256                         /* there's no scan as the scan has been */
1257                         /* perf inside the FX2 */
1258                         /* data arrives as one packet */
1259                         this_usbduxsub->ao_sample_count = cmd->stop_arg;
1260                 }
1261                 this_usbduxsub->ao_continuous = 0;
1262         } else {
1263                 /* continuous acquisition */
1264                 this_usbduxsub->ao_continuous = 1;
1265                 this_usbduxsub->ao_sample_count = 0;
1266         }
1267
1268         if (cmd->start_src == TRIG_NOW) {
1269                 /* enable this acquisition operation */
1270                 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbOut,
1271                                               this_usbduxsub->numOfOutBuffers,
1272                                               0);
1273                 if (ret < 0) {
1274                         up(&this_usbduxsub->sem);
1275                         return ret;
1276                 }
1277                 this_usbduxsub->ao_cmd_running = 1;
1278                 s->async->inttrig = NULL;
1279         } else {
1280                 /* TRIG_INT */
1281                 /* submit the urbs later */
1282                 /* wait for an internal signal */
1283                 s->async->inttrig = usbduxsigma_ao_inttrig;
1284         }
1285
1286         up(&this_usbduxsub->sem);
1287         return 0;
1288 }
1289
1290 static int usbdux_dio_insn_config(struct comedi_device *dev,
1291                                   struct comedi_subdevice *s,
1292                                   struct comedi_insn *insn, unsigned int *data)
1293 {
1294         int chan = CR_CHAN(insn->chanspec);
1295
1296         /* The input or output configuration of each digital line is
1297          * configured by a special insn_config instruction.  chanspec
1298          * contains the channel to be changed, and data[0] contains the
1299          * value COMEDI_INPUT or COMEDI_OUTPUT. */
1300
1301         switch (data[0]) {
1302         case INSN_CONFIG_DIO_OUTPUT:
1303                 s->io_bits |= 1 << chan;        /* 1 means Out */
1304                 break;
1305         case INSN_CONFIG_DIO_INPUT:
1306                 s->io_bits &= ~(1 << chan);
1307                 break;
1308         case INSN_CONFIG_DIO_QUERY:
1309                 data[1] =
1310                     (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1311                 break;
1312         default:
1313                 return -EINVAL;
1314                 break;
1315         }
1316         /* we don't tell the firmware here as it would take 8 frames */
1317         /* to submit the information. We do it in the insn_bits. */
1318         return insn->n;
1319 }
1320
1321 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1322                                 struct comedi_subdevice *s,
1323                                 struct comedi_insn *insn,
1324                                 unsigned int *data)
1325 {
1326         struct usbduxsigma_private *this_usbduxsub = dev->private;
1327         int err;
1328
1329         down(&this_usbduxsub->sem);
1330
1331         /* The insn data is a mask in data[0] and the new data
1332          * in data[1], each channel cooresponding to a bit. */
1333         s->state &= ~data[0];
1334         s->state |= data[0] & data[1];
1335         /* The commands are 8 bits wide */
1336         this_usbduxsub->dux_commands[1] = (s->io_bits) & 0x000000FF;
1337         this_usbduxsub->dux_commands[4] = (s->state) & 0x000000FF;
1338         this_usbduxsub->dux_commands[2] = ((s->io_bits) & 0x0000FF00) >> 8;
1339         this_usbduxsub->dux_commands[5] = ((s->state) & 0x0000FF00) >> 8;
1340         this_usbduxsub->dux_commands[3] = ((s->io_bits) & 0x00FF0000) >> 16;
1341         this_usbduxsub->dux_commands[6] = ((s->state) & 0x00FF0000) >> 16;
1342
1343         /* This command also tells the firmware to return */
1344         /* the digital input lines */
1345         err = send_dux_commands(dev, SENDDIOBITSCOMMAND);
1346         if (err < 0) {
1347                 up(&this_usbduxsub->sem);
1348                 return err;
1349         }
1350         err = receive_dux_commands(dev, SENDDIOBITSCOMMAND);
1351         if (err < 0) {
1352                 up(&this_usbduxsub->sem);
1353                 return err;
1354         }
1355
1356         data[1] = (((unsigned int)(this_usbduxsub->insnBuffer[1]))&0xff) |
1357                 ((((unsigned int)(this_usbduxsub->insnBuffer[2]))&0xff) << 8) |
1358                 ((((unsigned int)(this_usbduxsub->insnBuffer[3]))&0xff) << 16);
1359
1360         s->state = data[1];
1361
1362         up(&this_usbduxsub->sem);
1363         return insn->n;
1364 }
1365
1366 static void usbdux_pwm_stop(struct usbduxsigma_private *devpriv, int do_unlink)
1367 {
1368         if (do_unlink) {
1369                 if (devpriv->urbPwm)
1370                         usb_kill_urb(devpriv->urbPwm);
1371         }
1372
1373         devpriv->pwm_cmd_running = 0;
1374 }
1375
1376 static int usbdux_pwm_cancel(struct comedi_device *dev,
1377                              struct comedi_subdevice *s)
1378 {
1379         struct usbduxsigma_private *devpriv = dev->private;
1380
1381         /* unlink only if it is really running */
1382         usbdux_pwm_stop(devpriv, devpriv->pwm_cmd_running);
1383
1384         return send_dux_commands(dev, SENDPWMOFF);
1385 }
1386
1387 static void usbduxsub_pwm_irq(struct urb *urb)
1388 {
1389         struct comedi_device *dev = urb->context;
1390         struct usbduxsigma_private *devpriv = dev->private;
1391         int ret;
1392
1393         switch (urb->status) {
1394         case 0:
1395                 /* success */
1396                 break;
1397
1398         case -ECONNRESET:
1399         case -ENOENT:
1400         case -ESHUTDOWN:
1401         case -ECONNABORTED:
1402                 /* happens after an unlink command */
1403                 if (devpriv->pwm_cmd_running)
1404                         usbdux_pwm_stop(devpriv, 0);    /* w/o unlink */
1405                 return;
1406
1407         default:
1408                 /* a real error */
1409                 if (devpriv->pwm_cmd_running) {
1410                         dev_err(dev->class_dev,
1411                                 "%s: non-zero urb status (%d)\n",
1412                                 __func__, urb->status);
1413                         usbdux_pwm_stop(devpriv, 0);    /* w/o unlink */
1414                 }
1415                 return;
1416         }
1417
1418         if (!devpriv->pwm_cmd_running)
1419                 return;
1420
1421         urb->transfer_buffer_length = devpriv->sizePwmBuf;
1422         urb->dev = comedi_to_usb_dev(dev);
1423         urb->status = 0;
1424         ret = usb_submit_urb(urb, GFP_ATOMIC);
1425         if (ret < 0) {
1426                 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
1427                         __func__, ret);
1428                 if (ret == EL2NSYNC)
1429                         dev_err(dev->class_dev,
1430                                 "buggy USB host controller or bug in IRQ handler\n");
1431                 usbdux_pwm_stop(devpriv, 0);    /* w/o unlink */
1432         }
1433 }
1434
1435 static int usbduxsigma_submit_pwm_urb(struct comedi_device *dev)
1436 {
1437         struct usb_device *usb = comedi_to_usb_dev(dev);
1438         struct usbduxsigma_private *devpriv = dev->private;
1439         struct urb *urb = devpriv->urbPwm;
1440
1441         /* in case of a resubmission after an unlink... */
1442         usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, PWM_EP),
1443                           urb->transfer_buffer, devpriv->sizePwmBuf,
1444                           usbduxsub_pwm_irq, dev);
1445
1446         return usb_submit_urb(urb, GFP_ATOMIC);
1447 }
1448
1449 static int usbdux_pwm_period(struct comedi_device *dev,
1450                              struct comedi_subdevice *s, unsigned int period)
1451 {
1452         struct usbduxsigma_private *this_usbduxsub = dev->private;
1453         int fx2delay = 255;
1454
1455         if (period < MIN_PWM_PERIOD) {
1456                 dev_err(&this_usbduxsub->interface->dev,
1457                         "comedi%d: illegal period setting for pwm.\n",
1458                         dev->minor);
1459                 return -EAGAIN;
1460         } else {
1461                 fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
1462                 if (fx2delay > 255) {
1463                         dev_err(&this_usbduxsub->interface->dev,
1464                                 "comedi%d: period %d for pwm is too low.\n",
1465                                 dev->minor, period);
1466                         return -EAGAIN;
1467                 }
1468         }
1469         this_usbduxsub->pwmDelay = fx2delay;
1470         this_usbduxsub->pwmPeriod = period;
1471         return 0;
1472 }
1473
1474 /* is called from insn so there's no need to do all the sanity checks */
1475 static int usbdux_pwm_start(struct comedi_device *dev,
1476                             struct comedi_subdevice *s)
1477 {
1478         struct usbduxsigma_private *this_usbduxsub = dev->private;
1479         int ret, i;
1480
1481         if (this_usbduxsub->pwm_cmd_running) {
1482                 /* already running */
1483                 return 0;
1484         }
1485
1486         this_usbduxsub->dux_commands[1] = ((uint8_t) this_usbduxsub->pwmDelay);
1487         ret = send_dux_commands(dev, SENDPWMON);
1488         if (ret < 0)
1489                 return ret;
1490
1491         /* initialise the buffer */
1492         for (i = 0; i < this_usbduxsub->sizePwmBuf; i++)
1493                 ((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0;
1494
1495         ret = usbduxsigma_submit_pwm_urb(dev);
1496         if (ret < 0)
1497                 return ret;
1498         this_usbduxsub->pwm_cmd_running = 1;
1499
1500         return 0;
1501 }
1502
1503 /* generates the bit pattern for PWM with the optional sign bit */
1504 static int usbdux_pwm_pattern(struct comedi_device *dev,
1505                               struct comedi_subdevice *s, int channel,
1506                               unsigned int value, unsigned int sign)
1507 {
1508         struct usbduxsigma_private *this_usbduxsub = dev->private;
1509         int i, szbuf;
1510         char *pBuf;
1511         char pwm_mask;
1512         char sgn_mask;
1513         char c;
1514
1515         /* this is the DIO bit which carries the PWM data */
1516         pwm_mask = (1 << channel);
1517         /* this is the DIO bit which carries the optional direction bit */
1518         sgn_mask = (16 << channel);
1519         /* this is the buffer which will be filled with the with bit */
1520         /* pattern for one period */
1521         szbuf = this_usbduxsub->sizePwmBuf;
1522         pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer);
1523         for (i = 0; i < szbuf; i++) {
1524                 c = *pBuf;
1525                 /* reset bits */
1526                 c = c & (~pwm_mask);
1527                 /* set the bit as long as the index is lower than the value */
1528                 if (i < value)
1529                         c = c | pwm_mask;
1530                 /* set the optional sign bit for a relay */
1531                 if (!sign) {
1532                         /* positive value */
1533                         c = c & (~sgn_mask);
1534                 } else {
1535                         /* negative value */
1536                         c = c | sgn_mask;
1537                 }
1538                 *(pBuf++) = c;
1539         }
1540         return 1;
1541 }
1542
1543 static int usbdux_pwm_write(struct comedi_device *dev,
1544                             struct comedi_subdevice *s,
1545                             struct comedi_insn *insn, unsigned int *data)
1546 {
1547         if ((insn->n) != 1) {
1548                 /*
1549                  * doesn't make sense to have more than one value here because
1550                  * it would just overwrite the PWM buffer a couple of times
1551                  */
1552                 return -EINVAL;
1553         }
1554
1555         /*
1556          * the sign is set via a special INSN only, this gives us 8 bits for
1557          * normal operation
1558          * relay sign 0 by default
1559          */
1560         return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
1561 }
1562
1563 static int usbdux_pwm_read(struct comedi_device *x1,
1564                            struct comedi_subdevice *x2, struct comedi_insn *x3,
1565                            unsigned int *x4)
1566 {
1567         /* not needed */
1568         return -EINVAL;
1569 };
1570
1571 /* switches on/off PWM */
1572 static int usbdux_pwm_config(struct comedi_device *dev,
1573                              struct comedi_subdevice *s,
1574                              struct comedi_insn *insn, unsigned int *data)
1575 {
1576         struct usbduxsigma_private *this_usbduxsub = dev->private;
1577         switch (data[0]) {
1578         case INSN_CONFIG_ARM:
1579                 /* switch it on */
1580                 /*
1581                  * if not zero the PWM is limited to a certain time which is
1582                  * not supported here
1583                  */
1584                 if (data[1] != 0)
1585                         return -EINVAL;
1586                 return usbdux_pwm_start(dev, s);
1587         case INSN_CONFIG_DISARM:
1588                 return usbdux_pwm_cancel(dev, s);
1589         case INSN_CONFIG_GET_PWM_STATUS:
1590                 /*
1591                  * to check if the USB transmission has failed or in case PWM
1592                  * was limited to n cycles to check if it has terminated
1593                  */
1594                 data[1] = this_usbduxsub->pwm_cmd_running;
1595                 return 0;
1596         case INSN_CONFIG_PWM_SET_PERIOD:
1597                 return usbdux_pwm_period(dev, s, data[1]);
1598         case INSN_CONFIG_PWM_GET_PERIOD:
1599                 data[1] = this_usbduxsub->pwmPeriod;
1600                 return 0;
1601         case INSN_CONFIG_PWM_SET_H_BRIDGE:
1602                 /* value in the first byte and the sign in the second for a
1603                    relay */
1604                 return usbdux_pwm_pattern(dev, s,
1605                                           /* the channel number */
1606                                           CR_CHAN(insn->chanspec),
1607                                           /* actual PWM data */
1608                                           data[1],
1609                                           /* just a sign */
1610                                           (data[2] != 0));
1611         case INSN_CONFIG_PWM_GET_H_BRIDGE:
1612                 /* values are not kept in this driver, nothing to return */
1613                 return -EINVAL;
1614         }
1615         return -EINVAL;
1616 }
1617
1618 /* end of PWM */
1619 /*****************************************************************/
1620
1621 static void tidy_up(struct usbduxsigma_private *usbduxsub_tmp)
1622 {
1623         int i;
1624
1625         /* shows the usb subsystem that the driver is down */
1626         if (usbduxsub_tmp->interface)
1627                 usb_set_intfdata(usbduxsub_tmp->interface, NULL);
1628
1629         if (usbduxsub_tmp->urbIn) {
1630                 /* force unlink all urbs */
1631                 usbdux_ai_stop(usbduxsub_tmp, 1);
1632                 for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
1633                         kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer);
1634                         usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL;
1635                         usb_free_urb(usbduxsub_tmp->urbIn[i]);
1636                         usbduxsub_tmp->urbIn[i] = NULL;
1637                 }
1638                 kfree(usbduxsub_tmp->urbIn);
1639                 usbduxsub_tmp->urbIn = NULL;
1640         }
1641         if (usbduxsub_tmp->urbOut) {
1642                 /* force unlink all urbs */
1643                 usbdux_ao_stop(usbduxsub_tmp, 1);
1644                 for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
1645                         if (usbduxsub_tmp->urbOut[i]->transfer_buffer) {
1646                                 kfree(usbduxsub_tmp->
1647                                       urbOut[i]->transfer_buffer);
1648                                 usbduxsub_tmp->urbOut[i]->transfer_buffer =
1649                                     NULL;
1650                         }
1651                         if (usbduxsub_tmp->urbOut[i]) {
1652                                 usb_free_urb(usbduxsub_tmp->urbOut[i]);
1653                                 usbduxsub_tmp->urbOut[i] = NULL;
1654                         }
1655                 }
1656                 kfree(usbduxsub_tmp->urbOut);
1657                 usbduxsub_tmp->urbOut = NULL;
1658         }
1659         if (usbduxsub_tmp->urbPwm) {
1660                 /* force unlink urb */
1661                 usbdux_pwm_stop(usbduxsub_tmp, 1);
1662                 kfree(usbduxsub_tmp->urbPwm->transfer_buffer);
1663                 usbduxsub_tmp->urbPwm->transfer_buffer = NULL;
1664                 usb_free_urb(usbduxsub_tmp->urbPwm);
1665                 usbduxsub_tmp->urbPwm = NULL;
1666         }
1667         kfree(usbduxsub_tmp->inBuffer);
1668         usbduxsub_tmp->inBuffer = NULL;
1669         kfree(usbduxsub_tmp->insnBuffer);
1670         usbduxsub_tmp->insnBuffer = NULL;
1671         kfree(usbduxsub_tmp->outBuffer);
1672         usbduxsub_tmp->outBuffer = NULL;
1673         kfree(usbduxsub_tmp->dac_commands);
1674         usbduxsub_tmp->dac_commands = NULL;
1675         kfree(usbduxsub_tmp->dux_commands);
1676         usbduxsub_tmp->dux_commands = NULL;
1677 }
1678
1679 static int usbduxsigma_attach_common(struct comedi_device *dev)
1680 {
1681         struct usbduxsigma_private *uds = dev->private;
1682         int ret;
1683         struct comedi_subdevice *s;
1684         int n_subdevs;
1685         int offset;
1686
1687         down(&uds->sem);
1688
1689         /* set number of subdevices */
1690         if (uds->high_speed)
1691                 n_subdevs = 4;  /* with pwm */
1692         else
1693                 n_subdevs = 3;  /* without pwm */
1694         ret = comedi_alloc_subdevices(dev, n_subdevs);
1695         if (ret) {
1696                 up(&uds->sem);
1697                 return ret;
1698         }
1699         /* the first subdevice is the A/D converter */
1700         s = &dev->subdevices[SUBDEV_AD];
1701         /* the URBs get the comedi subdevice */
1702         /* which is responsible for reading */
1703         /* this is the subdevice which reads data */
1704         dev->read_subdev = s;
1705         /* the subdevice receives as private structure the */
1706         /* usb-structure */
1707         s->private = NULL;
1708         /* analog input */
1709         s->type = COMEDI_SUBD_AI;
1710         /* readable and ref is to ground, 32 bit wide data! */
1711         s->subdev_flags = SDF_READABLE | SDF_GROUND |
1712                 SDF_CMD_READ | SDF_LSAMPL;
1713         /* 16 A/D channels */
1714         s->n_chan = NUMCHANNELS;
1715         /* length of the channellist */
1716         s->len_chanlist = NUMCHANNELS;
1717         /* callback functions */
1718         s->insn_read = usbdux_ai_insn_read;
1719         s->do_cmdtest = usbdux_ai_cmdtest;
1720         s->do_cmd = usbdux_ai_cmd;
1721         s->cancel = usbdux_ai_cancel;
1722         /* max value from the A/D converter (24bit) */
1723         s->maxdata = 0x00FFFFFF;
1724         /* range table to convert to physical units */
1725         s->range_table = (&range_usbdux_ai_range);
1726         /* analog output subdevice */
1727         s = &dev->subdevices[SUBDEV_DA];
1728         /* analog out */
1729         s->type = COMEDI_SUBD_AO;
1730         /* backward pointer */
1731         dev->write_subdev = s;
1732         /* the subdevice receives as private structure the */
1733         /* usb-structure */
1734         s->private = NULL;
1735         /* are writable */
1736         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1737         /* 4 channels */
1738         s->n_chan = 4;
1739         /* length of the channellist */
1740         s->len_chanlist = 4;
1741         /* 8 bit resolution */
1742         s->maxdata = 0x00ff;
1743         /* unipolar range */
1744         s->range_table = &range_unipolar2_5;
1745         /* callback */
1746         s->do_cmdtest = usbdux_ao_cmdtest;
1747         s->do_cmd = usbdux_ao_cmd;
1748         s->cancel = usbdux_ao_cancel;
1749         s->insn_read = usbdux_ao_insn_read;
1750         s->insn_write = usbdux_ao_insn_write;
1751         /* digital I/O subdevice */
1752         s = &dev->subdevices[SUBDEV_DIO];
1753         s->type = COMEDI_SUBD_DIO;
1754         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1755         /* 8 external and 16 internal channels */
1756         s->n_chan = 24;
1757         s->maxdata = 1;
1758         s->range_table = (&range_digital);
1759         s->insn_bits = usbdux_dio_insn_bits;
1760         s->insn_config = usbdux_dio_insn_config;
1761         /* we don't use it */
1762         s->private = NULL;
1763         if (uds->high_speed) {
1764                 /* timer / pwm subdevice */
1765                 s = &dev->subdevices[SUBDEV_PWM];
1766                 s->type = COMEDI_SUBD_PWM;
1767                 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1768                 s->n_chan = 8;
1769                 /* this defines the max duty cycle resolution */
1770                 s->maxdata = uds->sizePwmBuf;
1771                 s->insn_write = usbdux_pwm_write;
1772                 s->insn_read = usbdux_pwm_read;
1773                 s->insn_config = usbdux_pwm_config;
1774                 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1775         }
1776         up(&uds->sem);
1777         offset = usbdux_getstatusinfo(dev, 0);
1778         if (offset < 0)
1779                 dev_err(&uds->interface->dev,
1780                         "Communication to USBDUXSIGMA failed! Check firmware and cabling.");
1781         dev_info(&uds->interface->dev,
1782                  "comedi%d: attached, ADC_zero = %x\n", dev->minor, offset);
1783         return 0;
1784 }
1785
1786 static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev)
1787 {
1788         struct usb_device *usb = comedi_to_usb_dev(dev);
1789         struct usbduxsigma_private *devpriv = dev->private;
1790         struct urb *urb;
1791         int i;
1792
1793         devpriv->dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
1794         devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1795         devpriv->inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1796         devpriv->insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1797         devpriv->outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1798         devpriv->urbIn = kcalloc(devpriv->numOfInBuffers, sizeof(*urb),
1799                                  GFP_KERNEL);
1800         devpriv->urbOut = kcalloc(devpriv->numOfOutBuffers, sizeof(*urb),
1801                                   GFP_KERNEL);
1802         if (!devpriv->dac_commands || !devpriv->dux_commands ||
1803             !devpriv->inBuffer || !devpriv->insnBuffer ||
1804             !devpriv->outBuffer || !devpriv->urbIn || !devpriv->urbOut)
1805                 return -ENOMEM;
1806
1807         for (i = 0; i < devpriv->numOfInBuffers; i++) {
1808                 /* one frame: 1ms */
1809                 urb = usb_alloc_urb(1, GFP_KERNEL);
1810                 if (!urb)
1811                         return -ENOMEM;
1812                 devpriv->urbIn[i] = urb;
1813                 urb->dev = usb;
1814                 /* will be filled later with a pointer to the comedi-device */
1815                 /* and ONLY then the urb should be submitted */
1816                 urb->context = NULL;
1817                 urb->pipe = usb_rcvisocpipe(usb, ISOINEP);
1818                 urb->transfer_flags = URB_ISO_ASAP;
1819                 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1820                 if (!urb->transfer_buffer)
1821                         return -ENOMEM;
1822                 urb->complete = usbduxsub_ai_IsocIrq;
1823                 urb->number_of_packets = 1;
1824                 urb->transfer_buffer_length = SIZEINBUF;
1825                 urb->iso_frame_desc[0].offset = 0;
1826                 urb->iso_frame_desc[0].length = SIZEINBUF;
1827         }
1828
1829         for (i = 0; i < devpriv->numOfOutBuffers; i++) {
1830                 /* one frame: 1ms */
1831                 urb = usb_alloc_urb(1, GFP_KERNEL);
1832                 if (!urb)
1833                         return -ENOMEM;
1834                 devpriv->urbOut[i] = urb;
1835                 urb->dev = usb;
1836                 /* will be filled later with a pointer to the comedi-device */
1837                 /* and ONLY then the urb should be submitted */
1838                 urb->context = NULL;
1839                 urb->pipe = usb_sndisocpipe(usb, ISOOUTEP);
1840                 urb->transfer_flags = URB_ISO_ASAP;
1841                 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1842                 if (!urb->transfer_buffer)
1843                         return -ENOMEM;
1844                 urb->complete = usbduxsub_ao_IsocIrq;
1845                 urb->number_of_packets = 1;
1846                 urb->transfer_buffer_length = SIZEOUTBUF;
1847                 urb->iso_frame_desc[0].offset = 0;
1848                 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1849                 if (devpriv->high_speed)
1850                         urb->interval = 8;      /* uframes */
1851                 else
1852                         urb->interval = 1;      /* frames */
1853         }
1854
1855         if (devpriv->high_speed) {
1856                 /* max bulk ep size in high speed */
1857                 devpriv->sizePwmBuf = 512;
1858                 urb = usb_alloc_urb(0, GFP_KERNEL);
1859                 if (!urb)
1860                         return -ENOMEM;
1861                 devpriv->urbPwm = urb;
1862                 urb->transfer_buffer = kzalloc(devpriv->sizePwmBuf, GFP_KERNEL);
1863                 if (!urb->transfer_buffer)
1864                         return -ENOMEM;
1865         } else {
1866                 devpriv->urbPwm = NULL;
1867                 devpriv->sizePwmBuf = 0;
1868         }
1869
1870         return 0;
1871 }
1872
1873 static int usbduxsigma_auto_attach(struct comedi_device *dev,
1874                                    unsigned long context_unused)
1875 {
1876         struct usb_interface *intf = comedi_to_usb_interface(dev);
1877         struct usb_device *usb = comedi_to_usb_dev(dev);
1878         struct usbduxsigma_private *devpriv;
1879         int ret;
1880
1881         devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1882         if (!devpriv)
1883                 return -ENOMEM;
1884         dev->private = devpriv;
1885
1886         sema_init(&devpriv->sem, 1);
1887         devpriv->interface = intf;
1888         usb_set_intfdata(intf, devpriv);
1889
1890         ret = usb_set_interface(usb,
1891                                 intf->altsetting->desc.bInterfaceNumber, 3);
1892         if (ret < 0) {
1893                 dev_err(dev->class_dev,
1894                         "could not set alternate setting 3 in high speed\n");
1895                 return -ENODEV;
1896         }
1897
1898         /* test if it is high speed (USB 2.0) */
1899         devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1900         if (devpriv->high_speed) {
1901                 devpriv->numOfInBuffers = NUMOFINBUFFERSHIGH;
1902                 devpriv->numOfOutBuffers = NUMOFOUTBUFFERSHIGH;
1903         } else {
1904                 devpriv->numOfInBuffers = NUMOFINBUFFERSFULL;
1905                 devpriv->numOfOutBuffers = NUMOFOUTBUFFERSFULL;
1906         }
1907
1908         ret = usbduxsigma_alloc_usb_buffers(dev);
1909         if (ret) {
1910                 tidy_up(devpriv);
1911                 return ret;
1912         }
1913
1914         ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1915                                    usbduxsigma_firmware_upload, 0);
1916         if (ret)
1917                 return ret;
1918
1919         return usbduxsigma_attach_common(dev);
1920 }
1921
1922 static void usbduxsigma_detach(struct comedi_device *dev)
1923 {
1924         struct usbduxsigma_private *devpriv = dev->private;
1925
1926         if (!devpriv)
1927                 return;
1928
1929         /* stop any running commands */
1930         usbdux_ai_stop(devpriv, devpriv->ai_cmd_running);
1931         usbdux_ao_stop(devpriv, devpriv->ao_cmd_running);
1932
1933         down(&devpriv->sem);
1934         tidy_up(devpriv);
1935         up(&devpriv->sem);
1936 }
1937
1938 static struct comedi_driver usbduxsigma_driver = {
1939         .driver_name    = "usbduxsigma",
1940         .module         = THIS_MODULE,
1941         .auto_attach    = usbduxsigma_auto_attach,
1942         .detach         = usbduxsigma_detach,
1943 };
1944
1945 static int usbduxsigma_usb_probe(struct usb_interface *intf,
1946                                  const struct usb_device_id *id)
1947 {
1948         return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0);;
1949 }
1950
1951 static const struct usb_device_id usbduxsigma_usb_table[] = {
1952         { USB_DEVICE(0x13d8, 0x0020) },
1953         { USB_DEVICE(0x13d8, 0x0021) },
1954         { USB_DEVICE(0x13d8, 0x0022) },
1955         { }
1956 };
1957 MODULE_DEVICE_TABLE(usb, usbduxsigma_usb_table);
1958
1959 static struct usb_driver usbduxsigma_usb_driver = {
1960         .name           = "usbduxsigma",
1961         .probe          = usbduxsigma_usb_probe,
1962         .disconnect     = comedi_usb_auto_unconfig,
1963         .id_table       = usbduxsigma_usb_table,
1964 };
1965 module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver);
1966
1967 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1968 MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com");
1969 MODULE_LICENSE("GPL");
1970 MODULE_FIRMWARE(FIRMWARE);