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