]> Pileus Git - ~andy/linux/blob - drivers/staging/comedi/drivers/usbduxsigma.c
e331ef596ef3e953ff0f5b0d9df55f1da2fee2e9
[~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 usbdux_ao_inttrig(struct comedi_device *dev,
1097                              struct comedi_subdevice *s, unsigned int trignum)
1098 {
1099         struct usbduxsigma_private *this_usbduxsub = dev->private;
1100         int ret;
1101
1102         down(&this_usbduxsub->sem);
1103         if (trignum != 0) {
1104                 dev_err(&this_usbduxsub->interface->dev,
1105                         "comedi%d: usbdux_ao_inttrig: invalid trignum\n",
1106                         dev->minor);
1107                 ret = -EINVAL;
1108                 goto out;
1109         }
1110         if (!(this_usbduxsub->ao_cmd_running)) {
1111                 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbOut,
1112                                               this_usbduxsub->numOfOutBuffers,
1113                                               0);
1114                 if (ret < 0)
1115                         goto out;
1116                 this_usbduxsub->ao_cmd_running = 1;
1117                 s->async->inttrig = NULL;
1118         } else {
1119                 dev_err(&this_usbduxsub->interface->dev,
1120                         "comedi%d: ao_inttrig but acqu is already running.\n",
1121                         dev->minor);
1122         }
1123         ret = 1;
1124 out:
1125         up(&this_usbduxsub->sem);
1126         return ret;
1127 }
1128
1129 static int usbdux_ao_cmdtest(struct comedi_device *dev,
1130                              struct comedi_subdevice *s,
1131                              struct comedi_cmd *cmd)
1132 {
1133         int err = 0;
1134         unsigned int flags;
1135
1136         /* Step 1 : check if triggers are trivially valid */
1137
1138         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
1139
1140         if (0) {                /* (this_usbduxsub->high_speed) */
1141                 /*
1142                  * start immediately a new scan
1143                  * the sampling rate is set by the coversion rate
1144                  */
1145                 flags = TRIG_FOLLOW;
1146         } else {
1147                 /* start a new scan (output at once) with a timer */
1148                 flags = TRIG_TIMER;
1149         }
1150         err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
1151
1152         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1153         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1154         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1155
1156         if (err)
1157                 return 1;
1158
1159         /* Step 2a : make sure trigger sources are unique */
1160
1161         err |= cfc_check_trigger_is_unique(cmd->start_src);
1162         err |= cfc_check_trigger_is_unique(cmd->stop_src);
1163
1164         /* Step 2b : and mutually compatible */
1165
1166         if (err)
1167                 return 2;
1168
1169         /* Step 3: check if arguments are trivially valid */
1170
1171         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1172
1173         if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
1174                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1175
1176         if (cmd->scan_begin_src == TRIG_TIMER)
1177                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1178                                                  1000000);
1179
1180         /* not used now, is for later use */
1181         if (cmd->convert_src == TRIG_TIMER)
1182                 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
1183
1184         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1185
1186         if (cmd->stop_src == TRIG_COUNT) {
1187                 /* any count is allowed */
1188         } else {
1189                 /* TRIG_NONE */
1190                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1191         }
1192
1193         if (err)
1194                 return 3;
1195
1196         return 0;
1197 }
1198
1199 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1200 {
1201         struct usbduxsigma_private *this_usbduxsub = dev->private;
1202         struct comedi_cmd *cmd = &s->async->cmd;
1203         unsigned int chan, gain;
1204         int i, ret;
1205
1206         down(&this_usbduxsub->sem);
1207         /* set current channel of the running acquisition to zero */
1208         s->async->cur_chan = 0;
1209         for (i = 0; i < cmd->chanlist_len; ++i) {
1210                 chan = CR_CHAN(cmd->chanlist[i]);
1211                 gain = CR_RANGE(cmd->chanlist[i]);
1212                 if (i >= NUMOUTCHANNELS) {
1213                         dev_err(&this_usbduxsub->interface->dev,
1214                                 "comedi%d: %s: channel list too long\n",
1215                                 dev->minor, __func__);
1216                         break;
1217                 }
1218                 this_usbduxsub->dac_commands[i] = chan;
1219                 dev_dbg(&this_usbduxsub->interface->dev,
1220                         "comedi%d: dac command for ch %d is %x\n",
1221                         dev->minor, i, this_usbduxsub->dac_commands[i]);
1222         }
1223
1224         /* we count in steps of 1ms (125us) */
1225         /* 125us mode not used yet */
1226         if (0) {                /* (this_usbduxsub->high_speed) */
1227                 /* 125us */
1228                 /* timing of the conversion itself: every 125 us */
1229                 this_usbduxsub->ao_timer = cmd->convert_arg / 125000;
1230         } else {
1231                 /* 1ms */
1232                 /* timing of the scan: we get all channels at once */
1233                 this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000;
1234                 dev_dbg(&this_usbduxsub->interface->dev,
1235                         "comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
1236                         "convert_src=%d, convert_arg=%d\n", dev->minor,
1237                         cmd->scan_begin_src, cmd->scan_begin_arg,
1238                         cmd->convert_src, cmd->convert_arg);
1239                 dev_dbg(&this_usbduxsub->interface->dev,
1240                         "comedi%d: ao_timer=%d (ms)\n",
1241                         dev->minor, this_usbduxsub->ao_timer);
1242                 if (this_usbduxsub->ao_timer < 1) {
1243                         dev_err(&this_usbduxsub->interface->dev,
1244                                 "comedi%d: usbdux: ao_timer=%d, "
1245                                 "scan_begin_arg=%d. "
1246                                 "Not properly tested by cmdtest?\n",
1247                                 dev->minor, this_usbduxsub->ao_timer,
1248                                 cmd->scan_begin_arg);
1249                         up(&this_usbduxsub->sem);
1250                         return -EINVAL;
1251                 }
1252         }
1253         this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
1254
1255         if (cmd->stop_src == TRIG_COUNT) {
1256                 /* not continuous */
1257                 /* counter */
1258                 /* high speed also scans everything at once */
1259                 if (0) {        /* (this_usbduxsub->high_speed) */
1260                         this_usbduxsub->ao_sample_count =
1261                             (cmd->stop_arg) * (cmd->scan_end_arg);
1262                 } else {
1263                         /* there's no scan as the scan has been */
1264                         /* perf inside the FX2 */
1265                         /* data arrives as one packet */
1266                         this_usbduxsub->ao_sample_count = cmd->stop_arg;
1267                 }
1268                 this_usbduxsub->ao_continuous = 0;
1269         } else {
1270                 /* continuous acquisition */
1271                 this_usbduxsub->ao_continuous = 1;
1272                 this_usbduxsub->ao_sample_count = 0;
1273         }
1274
1275         if (cmd->start_src == TRIG_NOW) {
1276                 /* enable this acquisition operation */
1277                 ret = usbduxsigma_submit_urbs(dev, this_usbduxsub->urbOut,
1278                                               this_usbduxsub->numOfOutBuffers,
1279                                               0);
1280                 if (ret < 0) {
1281                         up(&this_usbduxsub->sem);
1282                         return ret;
1283                 }
1284                 this_usbduxsub->ao_cmd_running = 1;
1285                 s->async->inttrig = NULL;
1286         } else {
1287                 /* TRIG_INT */
1288                 /* submit the urbs later */
1289                 /* wait for an internal signal */
1290                 s->async->inttrig = usbdux_ao_inttrig;
1291         }
1292
1293         up(&this_usbduxsub->sem);
1294         return 0;
1295 }
1296
1297 static int usbdux_dio_insn_config(struct comedi_device *dev,
1298                                   struct comedi_subdevice *s,
1299                                   struct comedi_insn *insn, unsigned int *data)
1300 {
1301         int chan = CR_CHAN(insn->chanspec);
1302
1303         /* The input or output configuration of each digital line is
1304          * configured by a special insn_config instruction.  chanspec
1305          * contains the channel to be changed, and data[0] contains the
1306          * value COMEDI_INPUT or COMEDI_OUTPUT. */
1307
1308         switch (data[0]) {
1309         case INSN_CONFIG_DIO_OUTPUT:
1310                 s->io_bits |= 1 << chan;        /* 1 means Out */
1311                 break;
1312         case INSN_CONFIG_DIO_INPUT:
1313                 s->io_bits &= ~(1 << chan);
1314                 break;
1315         case INSN_CONFIG_DIO_QUERY:
1316                 data[1] =
1317                     (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1318                 break;
1319         default:
1320                 return -EINVAL;
1321                 break;
1322         }
1323         /* we don't tell the firmware here as it would take 8 frames */
1324         /* to submit the information. We do it in the insn_bits. */
1325         return insn->n;
1326 }
1327
1328 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1329                                 struct comedi_subdevice *s,
1330                                 struct comedi_insn *insn,
1331                                 unsigned int *data)
1332 {
1333         struct usbduxsigma_private *this_usbduxsub = dev->private;
1334         int err;
1335
1336         down(&this_usbduxsub->sem);
1337
1338         /* The insn data is a mask in data[0] and the new data
1339          * in data[1], each channel cooresponding to a bit. */
1340         s->state &= ~data[0];
1341         s->state |= data[0] & data[1];
1342         /* The commands are 8 bits wide */
1343         this_usbduxsub->dux_commands[1] = (s->io_bits) & 0x000000FF;
1344         this_usbduxsub->dux_commands[4] = (s->state) & 0x000000FF;
1345         this_usbduxsub->dux_commands[2] = ((s->io_bits) & 0x0000FF00) >> 8;
1346         this_usbduxsub->dux_commands[5] = ((s->state) & 0x0000FF00) >> 8;
1347         this_usbduxsub->dux_commands[3] = ((s->io_bits) & 0x00FF0000) >> 16;
1348         this_usbduxsub->dux_commands[6] = ((s->state) & 0x00FF0000) >> 16;
1349
1350         /* This command also tells the firmware to return */
1351         /* the digital input lines */
1352         err = send_dux_commands(dev, SENDDIOBITSCOMMAND);
1353         if (err < 0) {
1354                 up(&this_usbduxsub->sem);
1355                 return err;
1356         }
1357         err = receive_dux_commands(dev, SENDDIOBITSCOMMAND);
1358         if (err < 0) {
1359                 up(&this_usbduxsub->sem);
1360                 return err;
1361         }
1362
1363         data[1] = (((unsigned int)(this_usbduxsub->insnBuffer[1]))&0xff) |
1364                 ((((unsigned int)(this_usbduxsub->insnBuffer[2]))&0xff) << 8) |
1365                 ((((unsigned int)(this_usbduxsub->insnBuffer[3]))&0xff) << 16);
1366
1367         s->state = data[1];
1368
1369         up(&this_usbduxsub->sem);
1370         return insn->n;
1371 }
1372
1373 static void usbdux_pwm_stop(struct usbduxsigma_private *devpriv, int do_unlink)
1374 {
1375         if (do_unlink) {
1376                 if (devpriv->urbPwm)
1377                         usb_kill_urb(devpriv->urbPwm);
1378         }
1379
1380         devpriv->pwm_cmd_running = 0;
1381 }
1382
1383 static int usbdux_pwm_cancel(struct comedi_device *dev,
1384                              struct comedi_subdevice *s)
1385 {
1386         struct usbduxsigma_private *devpriv = dev->private;
1387
1388         /* unlink only if it is really running */
1389         usbdux_pwm_stop(devpriv, devpriv->pwm_cmd_running);
1390
1391         return send_dux_commands(dev, SENDPWMOFF);
1392 }
1393
1394 static void usbduxsub_pwm_irq(struct urb *urb)
1395 {
1396         struct comedi_device *dev = urb->context;
1397         struct usbduxsigma_private *devpriv = dev->private;
1398         int ret;
1399
1400         switch (urb->status) {
1401         case 0:
1402                 /* success */
1403                 break;
1404
1405         case -ECONNRESET:
1406         case -ENOENT:
1407         case -ESHUTDOWN:
1408         case -ECONNABORTED:
1409                 /* happens after an unlink command */
1410                 if (devpriv->pwm_cmd_running)
1411                         usbdux_pwm_stop(devpriv, 0);    /* w/o unlink */
1412                 return;
1413
1414         default:
1415                 /* a real error */
1416                 if (devpriv->pwm_cmd_running) {
1417                         dev_err(dev->class_dev,
1418                                 "%s: non-zero urb status (%d)\n",
1419                                 __func__, urb->status);
1420                         usbdux_pwm_stop(devpriv, 0);    /* w/o unlink */
1421                 }
1422                 return;
1423         }
1424
1425         if (!devpriv->pwm_cmd_running)
1426                 return;
1427
1428         urb->transfer_buffer_length = devpriv->sizePwmBuf;
1429         urb->dev = comedi_to_usb_dev(dev);
1430         urb->status = 0;
1431         ret = usb_submit_urb(urb, GFP_ATOMIC);
1432         if (ret < 0) {
1433                 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
1434                         __func__, ret);
1435                 if (ret == EL2NSYNC)
1436                         dev_err(dev->class_dev,
1437                                 "buggy USB host controller or bug in IRQ handler\n");
1438                 usbdux_pwm_stop(devpriv, 0);    /* w/o unlink */
1439         }
1440 }
1441
1442 static int usbduxsigma_submit_pwm_urb(struct comedi_device *dev)
1443 {
1444         struct usb_device *usb = comedi_to_usb_dev(dev);
1445         struct usbduxsigma_private *devpriv = dev->private;
1446         struct urb *urb = devpriv->urbPwm;
1447
1448         /* in case of a resubmission after an unlink... */
1449         usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, PWM_EP),
1450                           urb->transfer_buffer, devpriv->sizePwmBuf,
1451                           usbduxsub_pwm_irq, dev);
1452
1453         return usb_submit_urb(urb, GFP_ATOMIC);
1454 }
1455
1456 static int usbdux_pwm_period(struct comedi_device *dev,
1457                              struct comedi_subdevice *s, unsigned int period)
1458 {
1459         struct usbduxsigma_private *this_usbduxsub = dev->private;
1460         int fx2delay = 255;
1461
1462         if (period < MIN_PWM_PERIOD) {
1463                 dev_err(&this_usbduxsub->interface->dev,
1464                         "comedi%d: illegal period setting for pwm.\n",
1465                         dev->minor);
1466                 return -EAGAIN;
1467         } else {
1468                 fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
1469                 if (fx2delay > 255) {
1470                         dev_err(&this_usbduxsub->interface->dev,
1471                                 "comedi%d: period %d for pwm is too low.\n",
1472                                 dev->minor, period);
1473                         return -EAGAIN;
1474                 }
1475         }
1476         this_usbduxsub->pwmDelay = fx2delay;
1477         this_usbduxsub->pwmPeriod = period;
1478         return 0;
1479 }
1480
1481 /* is called from insn so there's no need to do all the sanity checks */
1482 static int usbdux_pwm_start(struct comedi_device *dev,
1483                             struct comedi_subdevice *s)
1484 {
1485         struct usbduxsigma_private *this_usbduxsub = dev->private;
1486         int ret, i;
1487
1488         if (this_usbduxsub->pwm_cmd_running) {
1489                 /* already running */
1490                 return 0;
1491         }
1492
1493         this_usbduxsub->dux_commands[1] = ((uint8_t) this_usbduxsub->pwmDelay);
1494         ret = send_dux_commands(dev, SENDPWMON);
1495         if (ret < 0)
1496                 return ret;
1497
1498         /* initialise the buffer */
1499         for (i = 0; i < this_usbduxsub->sizePwmBuf; i++)
1500                 ((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0;
1501
1502         ret = usbduxsigma_submit_pwm_urb(dev);
1503         if (ret < 0)
1504                 return ret;
1505         this_usbduxsub->pwm_cmd_running = 1;
1506
1507         return 0;
1508 }
1509
1510 /* generates the bit pattern for PWM with the optional sign bit */
1511 static int usbdux_pwm_pattern(struct comedi_device *dev,
1512                               struct comedi_subdevice *s, int channel,
1513                               unsigned int value, unsigned int sign)
1514 {
1515         struct usbduxsigma_private *this_usbduxsub = dev->private;
1516         int i, szbuf;
1517         char *pBuf;
1518         char pwm_mask;
1519         char sgn_mask;
1520         char c;
1521
1522         /* this is the DIO bit which carries the PWM data */
1523         pwm_mask = (1 << channel);
1524         /* this is the DIO bit which carries the optional direction bit */
1525         sgn_mask = (16 << channel);
1526         /* this is the buffer which will be filled with the with bit */
1527         /* pattern for one period */
1528         szbuf = this_usbduxsub->sizePwmBuf;
1529         pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer);
1530         for (i = 0; i < szbuf; i++) {
1531                 c = *pBuf;
1532                 /* reset bits */
1533                 c = c & (~pwm_mask);
1534                 /* set the bit as long as the index is lower than the value */
1535                 if (i < value)
1536                         c = c | pwm_mask;
1537                 /* set the optional sign bit for a relay */
1538                 if (!sign) {
1539                         /* positive value */
1540                         c = c & (~sgn_mask);
1541                 } else {
1542                         /* negative value */
1543                         c = c | sgn_mask;
1544                 }
1545                 *(pBuf++) = c;
1546         }
1547         return 1;
1548 }
1549
1550 static int usbdux_pwm_write(struct comedi_device *dev,
1551                             struct comedi_subdevice *s,
1552                             struct comedi_insn *insn, unsigned int *data)
1553 {
1554         if ((insn->n) != 1) {
1555                 /*
1556                  * doesn't make sense to have more than one value here because
1557                  * it would just overwrite the PWM buffer a couple of times
1558                  */
1559                 return -EINVAL;
1560         }
1561
1562         /*
1563          * the sign is set via a special INSN only, this gives us 8 bits for
1564          * normal operation
1565          * relay sign 0 by default
1566          */
1567         return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
1568 }
1569
1570 static int usbdux_pwm_read(struct comedi_device *x1,
1571                            struct comedi_subdevice *x2, struct comedi_insn *x3,
1572                            unsigned int *x4)
1573 {
1574         /* not needed */
1575         return -EINVAL;
1576 };
1577
1578 /* switches on/off PWM */
1579 static int usbdux_pwm_config(struct comedi_device *dev,
1580                              struct comedi_subdevice *s,
1581                              struct comedi_insn *insn, unsigned int *data)
1582 {
1583         struct usbduxsigma_private *this_usbduxsub = dev->private;
1584         switch (data[0]) {
1585         case INSN_CONFIG_ARM:
1586                 /* switch it on */
1587                 /*
1588                  * if not zero the PWM is limited to a certain time which is
1589                  * not supported here
1590                  */
1591                 if (data[1] != 0)
1592                         return -EINVAL;
1593                 return usbdux_pwm_start(dev, s);
1594         case INSN_CONFIG_DISARM:
1595                 return usbdux_pwm_cancel(dev, s);
1596         case INSN_CONFIG_GET_PWM_STATUS:
1597                 /*
1598                  * to check if the USB transmission has failed or in case PWM
1599                  * was limited to n cycles to check if it has terminated
1600                  */
1601                 data[1] = this_usbduxsub->pwm_cmd_running;
1602                 return 0;
1603         case INSN_CONFIG_PWM_SET_PERIOD:
1604                 return usbdux_pwm_period(dev, s, data[1]);
1605         case INSN_CONFIG_PWM_GET_PERIOD:
1606                 data[1] = this_usbduxsub->pwmPeriod;
1607                 return 0;
1608         case INSN_CONFIG_PWM_SET_H_BRIDGE:
1609                 /* value in the first byte and the sign in the second for a
1610                    relay */
1611                 return usbdux_pwm_pattern(dev, s,
1612                                           /* the channel number */
1613                                           CR_CHAN(insn->chanspec),
1614                                           /* actual PWM data */
1615                                           data[1],
1616                                           /* just a sign */
1617                                           (data[2] != 0));
1618         case INSN_CONFIG_PWM_GET_H_BRIDGE:
1619                 /* values are not kept in this driver, nothing to return */
1620                 return -EINVAL;
1621         }
1622         return -EINVAL;
1623 }
1624
1625 /* end of PWM */
1626 /*****************************************************************/
1627
1628 static void tidy_up(struct usbduxsigma_private *usbduxsub_tmp)
1629 {
1630         int i;
1631
1632         /* shows the usb subsystem that the driver is down */
1633         if (usbduxsub_tmp->interface)
1634                 usb_set_intfdata(usbduxsub_tmp->interface, NULL);
1635
1636         if (usbduxsub_tmp->urbIn) {
1637                 /* force unlink all urbs */
1638                 usbdux_ai_stop(usbduxsub_tmp, 1);
1639                 for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
1640                         kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer);
1641                         usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL;
1642                         usb_free_urb(usbduxsub_tmp->urbIn[i]);
1643                         usbduxsub_tmp->urbIn[i] = NULL;
1644                 }
1645                 kfree(usbduxsub_tmp->urbIn);
1646                 usbduxsub_tmp->urbIn = NULL;
1647         }
1648         if (usbduxsub_tmp->urbOut) {
1649                 /* force unlink all urbs */
1650                 usbdux_ao_stop(usbduxsub_tmp, 1);
1651                 for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
1652                         if (usbduxsub_tmp->urbOut[i]->transfer_buffer) {
1653                                 kfree(usbduxsub_tmp->
1654                                       urbOut[i]->transfer_buffer);
1655                                 usbduxsub_tmp->urbOut[i]->transfer_buffer =
1656                                     NULL;
1657                         }
1658                         if (usbduxsub_tmp->urbOut[i]) {
1659                                 usb_free_urb(usbduxsub_tmp->urbOut[i]);
1660                                 usbduxsub_tmp->urbOut[i] = NULL;
1661                         }
1662                 }
1663                 kfree(usbduxsub_tmp->urbOut);
1664                 usbduxsub_tmp->urbOut = NULL;
1665         }
1666         if (usbduxsub_tmp->urbPwm) {
1667                 /* force unlink urb */
1668                 usbdux_pwm_stop(usbduxsub_tmp, 1);
1669                 kfree(usbduxsub_tmp->urbPwm->transfer_buffer);
1670                 usbduxsub_tmp->urbPwm->transfer_buffer = NULL;
1671                 usb_free_urb(usbduxsub_tmp->urbPwm);
1672                 usbduxsub_tmp->urbPwm = NULL;
1673         }
1674         kfree(usbduxsub_tmp->inBuffer);
1675         usbduxsub_tmp->inBuffer = NULL;
1676         kfree(usbduxsub_tmp->insnBuffer);
1677         usbduxsub_tmp->insnBuffer = NULL;
1678         kfree(usbduxsub_tmp->outBuffer);
1679         usbduxsub_tmp->outBuffer = NULL;
1680         kfree(usbduxsub_tmp->dac_commands);
1681         usbduxsub_tmp->dac_commands = NULL;
1682         kfree(usbduxsub_tmp->dux_commands);
1683         usbduxsub_tmp->dux_commands = NULL;
1684 }
1685
1686 static int usbduxsigma_attach_common(struct comedi_device *dev)
1687 {
1688         struct usbduxsigma_private *uds = dev->private;
1689         int ret;
1690         struct comedi_subdevice *s;
1691         int n_subdevs;
1692         int offset;
1693
1694         down(&uds->sem);
1695
1696         /* set number of subdevices */
1697         if (uds->high_speed)
1698                 n_subdevs = 4;  /* with pwm */
1699         else
1700                 n_subdevs = 3;  /* without pwm */
1701         ret = comedi_alloc_subdevices(dev, n_subdevs);
1702         if (ret) {
1703                 up(&uds->sem);
1704                 return ret;
1705         }
1706         /* the first subdevice is the A/D converter */
1707         s = &dev->subdevices[SUBDEV_AD];
1708         /* the URBs get the comedi subdevice */
1709         /* which is responsible for reading */
1710         /* this is the subdevice which reads data */
1711         dev->read_subdev = s;
1712         /* the subdevice receives as private structure the */
1713         /* usb-structure */
1714         s->private = NULL;
1715         /* analog input */
1716         s->type = COMEDI_SUBD_AI;
1717         /* readable and ref is to ground, 32 bit wide data! */
1718         s->subdev_flags = SDF_READABLE | SDF_GROUND |
1719                 SDF_CMD_READ | SDF_LSAMPL;
1720         /* 16 A/D channels */
1721         s->n_chan = NUMCHANNELS;
1722         /* length of the channellist */
1723         s->len_chanlist = NUMCHANNELS;
1724         /* callback functions */
1725         s->insn_read = usbdux_ai_insn_read;
1726         s->do_cmdtest = usbdux_ai_cmdtest;
1727         s->do_cmd = usbdux_ai_cmd;
1728         s->cancel = usbdux_ai_cancel;
1729         /* max value from the A/D converter (24bit) */
1730         s->maxdata = 0x00FFFFFF;
1731         /* range table to convert to physical units */
1732         s->range_table = (&range_usbdux_ai_range);
1733         /* analog output subdevice */
1734         s = &dev->subdevices[SUBDEV_DA];
1735         /* analog out */
1736         s->type = COMEDI_SUBD_AO;
1737         /* backward pointer */
1738         dev->write_subdev = s;
1739         /* the subdevice receives as private structure the */
1740         /* usb-structure */
1741         s->private = NULL;
1742         /* are writable */
1743         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1744         /* 4 channels */
1745         s->n_chan = 4;
1746         /* length of the channellist */
1747         s->len_chanlist = 4;
1748         /* 8 bit resolution */
1749         s->maxdata = 0x00ff;
1750         /* unipolar range */
1751         s->range_table = &range_unipolar2_5;
1752         /* callback */
1753         s->do_cmdtest = usbdux_ao_cmdtest;
1754         s->do_cmd = usbdux_ao_cmd;
1755         s->cancel = usbdux_ao_cancel;
1756         s->insn_read = usbdux_ao_insn_read;
1757         s->insn_write = usbdux_ao_insn_write;
1758         /* digital I/O subdevice */
1759         s = &dev->subdevices[SUBDEV_DIO];
1760         s->type = COMEDI_SUBD_DIO;
1761         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1762         /* 8 external and 16 internal channels */
1763         s->n_chan = 24;
1764         s->maxdata = 1;
1765         s->range_table = (&range_digital);
1766         s->insn_bits = usbdux_dio_insn_bits;
1767         s->insn_config = usbdux_dio_insn_config;
1768         /* we don't use it */
1769         s->private = NULL;
1770         if (uds->high_speed) {
1771                 /* timer / pwm subdevice */
1772                 s = &dev->subdevices[SUBDEV_PWM];
1773                 s->type = COMEDI_SUBD_PWM;
1774                 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1775                 s->n_chan = 8;
1776                 /* this defines the max duty cycle resolution */
1777                 s->maxdata = uds->sizePwmBuf;
1778                 s->insn_write = usbdux_pwm_write;
1779                 s->insn_read = usbdux_pwm_read;
1780                 s->insn_config = usbdux_pwm_config;
1781                 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1782         }
1783         up(&uds->sem);
1784         offset = usbdux_getstatusinfo(dev, 0);
1785         if (offset < 0)
1786                 dev_err(&uds->interface->dev,
1787                         "Communication to USBDUXSIGMA failed! Check firmware and cabling.");
1788         dev_info(&uds->interface->dev,
1789                  "comedi%d: attached, ADC_zero = %x\n", dev->minor, offset);
1790         return 0;
1791 }
1792
1793 static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev)
1794 {
1795         struct usb_device *usb = comedi_to_usb_dev(dev);
1796         struct usbduxsigma_private *devpriv = dev->private;
1797         struct urb *urb;
1798         int i;
1799
1800         devpriv->dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
1801         devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1802         devpriv->inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1803         devpriv->insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1804         devpriv->outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1805         devpriv->urbIn = kcalloc(devpriv->numOfInBuffers, sizeof(*urb),
1806                                  GFP_KERNEL);
1807         devpriv->urbOut = kcalloc(devpriv->numOfOutBuffers, sizeof(*urb),
1808                                   GFP_KERNEL);
1809         if (!devpriv->dac_commands || !devpriv->dux_commands ||
1810             !devpriv->inBuffer || !devpriv->insnBuffer ||
1811             !devpriv->outBuffer || !devpriv->urbIn || !devpriv->urbOut)
1812                 return -ENOMEM;
1813
1814         for (i = 0; i < devpriv->numOfInBuffers; i++) {
1815                 /* one frame: 1ms */
1816                 urb = usb_alloc_urb(1, GFP_KERNEL);
1817                 if (!urb)
1818                         return -ENOMEM;
1819                 devpriv->urbIn[i] = urb;
1820                 urb->dev = usb;
1821                 /* will be filled later with a pointer to the comedi-device */
1822                 /* and ONLY then the urb should be submitted */
1823                 urb->context = NULL;
1824                 urb->pipe = usb_rcvisocpipe(usb, ISOINEP);
1825                 urb->transfer_flags = URB_ISO_ASAP;
1826                 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1827                 if (!urb->transfer_buffer)
1828                         return -ENOMEM;
1829                 urb->complete = usbduxsub_ai_IsocIrq;
1830                 urb->number_of_packets = 1;
1831                 urb->transfer_buffer_length = SIZEINBUF;
1832                 urb->iso_frame_desc[0].offset = 0;
1833                 urb->iso_frame_desc[0].length = SIZEINBUF;
1834         }
1835
1836         for (i = 0; i < devpriv->numOfOutBuffers; i++) {
1837                 /* one frame: 1ms */
1838                 urb = usb_alloc_urb(1, GFP_KERNEL);
1839                 if (!urb)
1840                         return -ENOMEM;
1841                 devpriv->urbOut[i] = urb;
1842                 urb->dev = usb;
1843                 /* will be filled later with a pointer to the comedi-device */
1844                 /* and ONLY then the urb should be submitted */
1845                 urb->context = NULL;
1846                 urb->pipe = usb_sndisocpipe(usb, ISOOUTEP);
1847                 urb->transfer_flags = URB_ISO_ASAP;
1848                 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1849                 if (!urb->transfer_buffer)
1850                         return -ENOMEM;
1851                 urb->complete = usbduxsub_ao_IsocIrq;
1852                 urb->number_of_packets = 1;
1853                 urb->transfer_buffer_length = SIZEOUTBUF;
1854                 urb->iso_frame_desc[0].offset = 0;
1855                 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1856                 if (devpriv->high_speed)
1857                         urb->interval = 8;      /* uframes */
1858                 else
1859                         urb->interval = 1;      /* frames */
1860         }
1861
1862         if (devpriv->high_speed) {
1863                 /* max bulk ep size in high speed */
1864                 devpriv->sizePwmBuf = 512;
1865                 urb = usb_alloc_urb(0, GFP_KERNEL);
1866                 if (!urb)
1867                         return -ENOMEM;
1868                 devpriv->urbPwm = urb;
1869                 urb->transfer_buffer = kzalloc(devpriv->sizePwmBuf, GFP_KERNEL);
1870                 if (!urb->transfer_buffer)
1871                         return -ENOMEM;
1872         } else {
1873                 devpriv->urbPwm = NULL;
1874                 devpriv->sizePwmBuf = 0;
1875         }
1876
1877         return 0;
1878 }
1879
1880 static int usbduxsigma_auto_attach(struct comedi_device *dev,
1881                                    unsigned long context_unused)
1882 {
1883         struct usb_interface *intf = comedi_to_usb_interface(dev);
1884         struct usb_device *usb = comedi_to_usb_dev(dev);
1885         struct usbduxsigma_private *devpriv;
1886         int ret;
1887
1888         devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1889         if (!devpriv)
1890                 return -ENOMEM;
1891         dev->private = devpriv;
1892
1893         sema_init(&devpriv->sem, 1);
1894         devpriv->interface = intf;
1895         usb_set_intfdata(intf, devpriv);
1896
1897         ret = usb_set_interface(usb,
1898                                 intf->altsetting->desc.bInterfaceNumber, 3);
1899         if (ret < 0) {
1900                 dev_err(dev->class_dev,
1901                         "could not set alternate setting 3 in high speed\n");
1902                 return -ENODEV;
1903         }
1904
1905         /* test if it is high speed (USB 2.0) */
1906         devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1907         if (devpriv->high_speed) {
1908                 devpriv->numOfInBuffers = NUMOFINBUFFERSHIGH;
1909                 devpriv->numOfOutBuffers = NUMOFOUTBUFFERSHIGH;
1910         } else {
1911                 devpriv->numOfInBuffers = NUMOFINBUFFERSFULL;
1912                 devpriv->numOfOutBuffers = NUMOFOUTBUFFERSFULL;
1913         }
1914
1915         ret = usbduxsigma_alloc_usb_buffers(dev);
1916         if (ret) {
1917                 tidy_up(devpriv);
1918                 return ret;
1919         }
1920
1921         ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1922                                    usbduxsigma_firmware_upload, 0);
1923         if (ret)
1924                 return ret;
1925
1926         return usbduxsigma_attach_common(dev);
1927 }
1928
1929 static void usbduxsigma_detach(struct comedi_device *dev)
1930 {
1931         struct usbduxsigma_private *devpriv = dev->private;
1932
1933         if (!devpriv)
1934                 return;
1935
1936         /* stop any running commands */
1937         usbdux_ai_stop(devpriv, devpriv->ai_cmd_running);
1938         usbdux_ao_stop(devpriv, devpriv->ao_cmd_running);
1939
1940         down(&devpriv->sem);
1941         tidy_up(devpriv);
1942         up(&devpriv->sem);
1943 }
1944
1945 static struct comedi_driver usbduxsigma_driver = {
1946         .driver_name    = "usbduxsigma",
1947         .module         = THIS_MODULE,
1948         .auto_attach    = usbduxsigma_auto_attach,
1949         .detach         = usbduxsigma_detach,
1950 };
1951
1952 static int usbduxsigma_usb_probe(struct usb_interface *intf,
1953                                  const struct usb_device_id *id)
1954 {
1955         return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0);;
1956 }
1957
1958 static const struct usb_device_id usbduxsigma_usb_table[] = {
1959         { USB_DEVICE(0x13d8, 0x0020) },
1960         { USB_DEVICE(0x13d8, 0x0021) },
1961         { USB_DEVICE(0x13d8, 0x0022) },
1962         { }
1963 };
1964 MODULE_DEVICE_TABLE(usb, usbduxsigma_usb_table);
1965
1966 static struct usb_driver usbduxsigma_usb_driver = {
1967         .name           = "usbduxsigma",
1968         .probe          = usbduxsigma_usb_probe,
1969         .disconnect     = comedi_usb_auto_unconfig,
1970         .id_table       = usbduxsigma_usb_table,
1971 };
1972 module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver);
1973
1974 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1975 MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com");
1976 MODULE_LICENSE("GPL");
1977 MODULE_FIRMWARE(FIRMWARE);