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