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