]> Pileus Git - ~andy/linux/blob - drivers/staging/comedi/drivers/usbduxsigma.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
[~andy/linux] / drivers / staging / comedi / drivers / usbduxsigma.c
1 #define DRIVER_VERSION "v0.5"
2 #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
3 #define DRIVER_DESC "Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com"
4 /*
5    comedi/drivers/usbdux.c
6    Copyright (C) 2011 Bernd Porr, Bernd.Porr@f2s.com
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22  */
23 /*
24 Driver: usbduxsigma
25 Description: University of Stirling USB DAQ & INCITE Technology Limited
26 Devices: [ITL] USB-DUX (usbduxsigma.o)
27 Author: Bernd Porr <BerndPorr@f2s.com>
28 Updated: 21 Jul 2011
29 Status: testing
30 */
31 /*
32  * I must give credit here to Chris Baugher who
33  * wrote the driver for AT-MIO-16d. I used some parts of this
34  * driver. I also must give credits to David Brownell
35  * who supported me with the USB development.
36  *
37  * Note: the raw data from the A/D converter is 24 bit big endian
38  * anything else is little endian to/from the dux board
39  *
40  *
41  * Revision history:
42  *   0.1: inital version
43  *   0.2: all basic functions implemented, digital I/O only for one port
44  *   0.3: proper vendor ID and driver name
45  *   0.4: fixed D/A voltage range
46  *   0.5: various bug fixes, health check at startup
47  */
48
49 /* generates loads of debug info */
50 /* #define NOISY_DUX_DEBUGBUG */
51
52 #include <linux/kernel.h>
53 #include <linux/module.h>
54 #include <linux/init.h>
55 #include <linux/slab.h>
56 #include <linux/input.h>
57 #include <linux/usb.h>
58 #include <linux/fcntl.h>
59 #include <linux/compiler.h>
60 #include <linux/firmware.h>
61 #include "comedi_fc.h"
62 #include "../comedidev.h"
63
64 #define BOARDNAME "usbduxsigma"
65
66 /* timeout for the USB-transfer in ms*/
67 #define BULK_TIMEOUT 1000
68
69 /* constants for "firmware" upload and download */
70 #define USBDUXSUB_FIRMWARE 0xA0
71 #define VENDOR_DIR_IN  0xC0
72 #define VENDOR_DIR_OUT 0x40
73
74 /* internal addresses of the 8051 processor */
75 #define USBDUXSUB_CPUCS 0xE600
76
77 /*
78  * the minor device number, major is 180 only for debugging purposes and to
79  * upload special firmware (programming the eeprom etc) which is not
80  * compatible with the comedi framwork
81  */
82 #define USBDUXSUB_MINOR 32
83
84 /* max lenghth of the transfer-buffer for software upload */
85 #define TB_LEN 0x2000
86
87 /* Input endpoint number: ISO/IRQ */
88 #define ISOINEP           6
89
90 /* Output endpoint number: ISO/IRQ */
91 #define ISOOUTEP          2
92
93 /* This EP sends DUX commands to USBDUX */
94 #define COMMAND_OUT_EP     1
95
96 /* This EP receives the DUX commands from USBDUX */
97 #define COMMAND_IN_EP        8
98
99 /* Output endpoint for PWM */
100 #define PWM_EP         4
101
102 /* 300Hz max frequ under PWM */
103 #define MIN_PWM_PERIOD  ((long)(1E9/300))
104
105 /* Default PWM frequency */
106 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
107
108 /* Number of channels (16 AD and offset)*/
109 #define NUMCHANNELS 16
110
111 /* Size of one A/D value */
112 #define SIZEADIN          ((sizeof(int32_t)))
113
114 /*
115  * Size of the async input-buffer IN BYTES, the DIO state is transmitted
116  * as the first byte.
117  */
118 #define SIZEINBUF         (((NUMCHANNELS+1)*SIZEADIN))
119
120 /* 16 bytes. */
121 #define SIZEINSNBUF       16
122
123 /* Number of DA channels */
124 #define NUMOUTCHANNELS    8
125
126 /* size of one value for the D/A converter: channel and value */
127 #define SIZEDAOUT          ((sizeof(uint8_t)+sizeof(int16_t)))
128
129 /*
130  * Size of the output-buffer in bytes
131  * Actually only the first 4 triplets are used but for the
132  * high speed mode we need to pad it to 8 (microframes).
133  */
134 #define SIZEOUTBUF         ((8*SIZEDAOUT))
135
136 /*
137  * Size of the buffer for the dux commands: just now max size is determined
138  * by the analogue out + command byte + panic bytes...
139  */
140 #define SIZEOFDUXBUFFER    ((8*SIZEDAOUT+2))
141
142 /* Number of in-URBs which receive the data: min=2 */
143 #define NUMOFINBUFFERSFULL     5
144
145 /* Number of out-URBs which send the data: min=2 */
146 #define NUMOFOUTBUFFERSFULL    5
147
148 /* Number of in-URBs which receive the data: min=5 */
149 /* must have more buffers due to buggy USB ctr */
150 #define NUMOFINBUFFERSHIGH     10
151
152 /* Number of out-URBs which send the data: min=5 */
153 /* must have more buffers due to buggy USB ctr */
154 #define NUMOFOUTBUFFERSHIGH    10
155
156 /* Total number of usbdux devices */
157 #define NUMUSBDUX             16
158
159 /* Analogue in subdevice */
160 #define SUBDEV_AD             0
161
162 /* Analogue out subdevice */
163 #define SUBDEV_DA             1
164
165 /* Digital I/O */
166 #define SUBDEV_DIO            2
167
168 /* timer aka pwm output */
169 #define SUBDEV_PWM            3
170
171 /* number of retries to get the right dux command */
172 #define RETRIES 10
173
174 /**************************************************/
175 /* comedi constants */
176 static const struct comedi_lrange range_usbdux_ai_range = { 1, {
177                                                                 BIP_RANGE
178                                                                 (2.65)
179                                                                 }
180 };
181
182 static const struct comedi_lrange range_usbdux_ao_range = { 1, {
183                                                                 UNI_RANGE
184                                                                 (2.5),
185                                                                }
186 };
187
188 /*
189  * private structure of one subdevice
190  */
191
192 /*
193  * This is the structure which holds all the data of
194  * this driver one sub device just now: A/D
195  */
196 struct usbduxsub {
197         /* attached? */
198         int attached;
199         /* is it associated with a subdevice? */
200         int probed;
201         /* pointer to the usb-device */
202         struct usb_device *usbdev;
203         /* actual number of in-buffers */
204         int numOfInBuffers;
205         /* actual number of out-buffers */
206         int numOfOutBuffers;
207         /* ISO-transfer handling: buffers */
208         struct urb **urbIn;
209         struct urb **urbOut;
210         /* pwm-transfer handling */
211         struct urb *urbPwm;
212         /* PWM period */
213         unsigned int pwmPeriod;
214         /* PWM internal delay for the GPIF in the FX2 */
215         uint8_t pwmDelay;
216         /* size of the PWM buffer which holds the bit pattern */
217         int sizePwmBuf;
218         /* input buffer for the ISO-transfer */
219         int32_t *inBuffer;
220         /* input buffer for single insn */
221         int8_t *insnBuffer;
222         /* output buffer for single DA outputs */
223         int16_t *outBuffer;
224         /* interface number */
225         int ifnum;
226         /* interface structure in 2.6 */
227         struct usb_interface *interface;
228         /* comedi device for the interrupt context */
229         struct comedi_device *comedidev;
230         /* is it USB_SPEED_HIGH or not? */
231         short int high_speed;
232         /* asynchronous command is running */
233         short int ai_cmd_running;
234         short int ao_cmd_running;
235         /* pwm is running */
236         short int pwm_cmd_running;
237         /* continous aquisition */
238         short int ai_continous;
239         short int ao_continous;
240         /* number of samples to acquire */
241         int ai_sample_count;
242         int ao_sample_count;
243         /* time between samples in units of the timer */
244         unsigned int ai_timer;
245         unsigned int ao_timer;
246         /* counter between aquisitions */
247         unsigned int ai_counter;
248         unsigned int ao_counter;
249         /* interval in frames/uframes */
250         unsigned int ai_interval;
251         /* D/A commands */
252         uint8_t *dac_commands;
253         /* commands */
254         uint8_t *dux_commands;
255         struct semaphore sem;
256 };
257
258 /*
259  * The pointer to the private usb-data of the driver is also the private data
260  * for the comedi-device.  This has to be global as the usb subsystem needs
261  * global variables. The other reason is that this structure must be there
262  * _before_ any comedi command is issued. The usb subsystem must be initialised
263  * before comedi can access it.
264  */
265 static struct usbduxsub usbduxsub[NUMUSBDUX];
266
267 static DEFINE_SEMAPHORE(start_stop_sem);
268
269 /*
270  * Stops the data acquision
271  * It should be safe to call this function from any context
272  */
273 static int usbduxsub_unlink_InURBs(struct usbduxsub *usbduxsub_tmp)
274 {
275         int i = 0;
276         int err = 0;
277
278         if (usbduxsub_tmp && usbduxsub_tmp->urbIn) {
279                 for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
280                         if (usbduxsub_tmp->urbIn[i]) {
281                                 /* We wait here until all transfers have been
282                                  * cancelled. */
283                                 usb_kill_urb(usbduxsub_tmp->urbIn[i]);
284                         }
285                         dev_dbg(&usbduxsub_tmp->interface->dev,
286                                 "comedi: usbdux: unlinked InURB %d, err=%d\n",
287                                 i, err);
288                 }
289         }
290         return err;
291 }
292
293 /*
294  * This will stop a running acquisition operation
295  * Is called from within this driver from both the
296  * interrupt context and from comedi
297  */
298 static int usbdux_ai_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
299 {
300         int ret = 0;
301
302         if (!this_usbduxsub) {
303                 pr_err("comedi?: usbdux_ai_stop: this_usbduxsub=NULL!\n");
304                 return -EFAULT;
305         }
306         dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_stop\n");
307
308         if (do_unlink) {
309                 /* stop aquistion */
310                 ret = usbduxsub_unlink_InURBs(this_usbduxsub);
311         }
312
313         this_usbduxsub->ai_cmd_running = 0;
314
315         return ret;
316 }
317
318 /*
319  * This will cancel a running acquisition operation.
320  * This is called by comedi but never from inside the driver.
321  */
322 static int usbdux_ai_cancel(struct comedi_device *dev,
323                             struct comedi_subdevice *s)
324 {
325         struct usbduxsub *this_usbduxsub;
326         int res = 0;
327
328         /* force unlink of all urbs */
329         this_usbduxsub = dev->private;
330         if (!this_usbduxsub)
331                 return -EFAULT;
332
333         dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_cancel\n");
334
335         /* prevent other CPUs from submitting new commands just now */
336         down(&this_usbduxsub->sem);
337         if (!(this_usbduxsub->probed)) {
338                 up(&this_usbduxsub->sem);
339                 return -ENODEV;
340         }
341         /* unlink only if the urb really has been submitted */
342         res = usbdux_ai_stop(this_usbduxsub, this_usbduxsub->ai_cmd_running);
343         up(&this_usbduxsub->sem);
344         return res;
345 }
346
347 /* analogue IN - interrupt service routine */
348 static void usbduxsub_ai_IsocIrq(struct urb *urb)
349 {
350         int i, err, n;
351         struct usbduxsub *this_usbduxsub;
352         struct comedi_device *this_comedidev;
353         struct comedi_subdevice *s;
354         int32_t v;
355         unsigned int dio_state;
356
357         /* the context variable points to the comedi device */
358         this_comedidev = urb->context;
359         /* the private structure of the subdevice is struct usbduxsub */
360         this_usbduxsub = this_comedidev->private;
361         /* subdevice which is the AD converter */
362         s = this_comedidev->subdevices + SUBDEV_AD;
363
364         /* first we test if something unusual has just happened */
365         switch (urb->status) {
366         case 0:
367                 /* copy the result in the transfer buffer */
368                 memcpy(this_usbduxsub->inBuffer,
369                        urb->transfer_buffer, SIZEINBUF);
370                 break;
371         case -EILSEQ:
372                 /* error in the ISOchronous data */
373                 /* we don't copy the data into the transfer buffer */
374                 /* and recycle the last data byte */
375                 dev_dbg(&urb->dev->dev,
376                         "comedi%d: usbdux: CRC error in ISO IN stream.\n",
377                         this_usbduxsub->comedidev->minor);
378
379                 break;
380
381         case -ECONNRESET:
382         case -ENOENT:
383         case -ESHUTDOWN:
384         case -ECONNABORTED:
385                 /* happens after an unlink command */
386                 if (this_usbduxsub->ai_cmd_running) {
387                         /* we are still running a command */
388                         /* tell this comedi */
389                         s->async->events |= COMEDI_CB_EOA;
390                         s->async->events |= COMEDI_CB_ERROR;
391                         comedi_event(this_usbduxsub->comedidev, s);
392                         /* stop the transfer w/o unlink */
393                         usbdux_ai_stop(this_usbduxsub, 0);
394                 }
395                 return;
396
397         default:
398                 /* a real error on the bus */
399                 /* pass error to comedi if we are really running a command */
400                 if (this_usbduxsub->ai_cmd_running) {
401                         dev_err(&urb->dev->dev,
402                                 "Non-zero urb status received in ai intr "
403                                 "context: %d\n", urb->status);
404                         s->async->events |= COMEDI_CB_EOA;
405                         s->async->events |= COMEDI_CB_ERROR;
406                         comedi_event(this_usbduxsub->comedidev, s);
407                         /* don't do an unlink here */
408                         usbdux_ai_stop(this_usbduxsub, 0);
409                 }
410                 return;
411         }
412
413         /*
414          * at this point we are reasonably sure that nothing dodgy has happened
415          * are we running a command?
416          */
417         if (unlikely((!(this_usbduxsub->ai_cmd_running)))) {
418                 /*
419                  * not running a command, do not continue execution if no
420                  * asynchronous command is running in particular not resubmit
421                  */
422                 return;
423         }
424
425         urb->dev = this_usbduxsub->usbdev;
426
427         /* resubmit the urb */
428         err = usb_submit_urb(urb, GFP_ATOMIC);
429         if (unlikely(err < 0)) {
430                 dev_err(&urb->dev->dev,
431                         "comedi_: urb resubmit failed in int-context!"
432                         "err=%d\n",
433                         err);
434                 if (err == -EL2NSYNC)
435                         dev_err(&urb->dev->dev,
436                                 "buggy USB host controller or bug in IRQ "
437                                 "handler!\n");
438                 s->async->events |= COMEDI_CB_EOA;
439                 s->async->events |= COMEDI_CB_ERROR;
440                 comedi_event(this_usbduxsub->comedidev, s);
441                 /* don't do an unlink here */
442                 usbdux_ai_stop(this_usbduxsub, 0);
443                 return;
444         }
445
446         /* get the state of the dio pins to allow external trigger */
447         dio_state = be32_to_cpu(this_usbduxsub->inBuffer[0]);
448
449         this_usbduxsub->ai_counter--;
450         if (likely(this_usbduxsub->ai_counter > 0))
451                 return;
452
453         /* timer zero, transfer measurements to comedi */
454         this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
455
456         /* test, if we transmit only a fixed number of samples */
457         if (!(this_usbduxsub->ai_continous)) {
458                 /* not continous, fixed number of samples */
459                 this_usbduxsub->ai_sample_count--;
460                 /* all samples received? */
461                 if (this_usbduxsub->ai_sample_count < 0) {
462                         /* prevent a resubmit next time */
463                         usbdux_ai_stop(this_usbduxsub, 0);
464                         /* say comedi that the acquistion is over */
465                         s->async->events |= COMEDI_CB_EOA;
466                         comedi_event(this_usbduxsub->comedidev, s);
467                         return;
468                 }
469         }
470         /* get the data from the USB bus and hand it over to comedi */
471         n = s->async->cmd.chanlist_len;
472         for (i = 0; i < n; i++) {
473                 /* transfer data, note first byte is the DIO state */
474                 v = be32_to_cpu(this_usbduxsub->inBuffer[i+1]);
475                 /* strip status byte */
476                 v = v & 0x00ffffff;
477                 /* convert to unsigned */
478                 v = v ^ 0x00800000;
479                 /* write the byte to the buffer */
480                 err = cfc_write_array_to_buffer(s, &v, sizeof(uint32_t));
481                 if (unlikely(err == 0)) {
482                         /* buffer overflow */
483                         usbdux_ai_stop(this_usbduxsub, 0);
484                         return;
485                 }
486         }
487         /* tell comedi that data is there */
488         s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
489         comedi_event(this_usbduxsub->comedidev, s);
490 }
491
492 static int usbduxsub_unlink_OutURBs(struct usbduxsub *usbduxsub_tmp)
493 {
494         int i = 0;
495         int err = 0;
496
497         if (usbduxsub_tmp && usbduxsub_tmp->urbOut) {
498                 for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
499                         if (usbduxsub_tmp->urbOut[i])
500                                 usb_kill_urb(usbduxsub_tmp->urbOut[i]);
501
502                         dev_dbg(&usbduxsub_tmp->interface->dev,
503                                 "comedi: usbdux: unlinked OutURB %d: res=%d\n",
504                                 i, err);
505                 }
506         }
507         return err;
508 }
509
510 /* This will cancel a running acquisition operation
511  * in any context.
512  */
513 static int usbdux_ao_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
514 {
515         int ret = 0;
516
517         if (!this_usbduxsub)
518                 return -EFAULT;
519         dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ao_cancel\n");
520
521         if (do_unlink)
522                 ret = usbduxsub_unlink_OutURBs(this_usbduxsub);
523
524         this_usbduxsub->ao_cmd_running = 0;
525
526         return ret;
527 }
528
529 /* force unlink, is called by comedi */
530 static int usbdux_ao_cancel(struct comedi_device *dev,
531                             struct comedi_subdevice *s)
532 {
533         struct usbduxsub *this_usbduxsub = dev->private;
534         int res = 0;
535
536         if (!this_usbduxsub)
537                 return -EFAULT;
538
539         /* prevent other CPUs from submitting a command just now */
540         down(&this_usbduxsub->sem);
541         if (!(this_usbduxsub->probed)) {
542                 up(&this_usbduxsub->sem);
543                 return -ENODEV;
544         }
545         /* unlink only if it is really running */
546         res = usbdux_ao_stop(this_usbduxsub, this_usbduxsub->ao_cmd_running);
547         up(&this_usbduxsub->sem);
548         return res;
549 }
550
551 static void usbduxsub_ao_IsocIrq(struct urb *urb)
552 {
553         int i, ret;
554         uint8_t *datap;
555         struct usbduxsub *this_usbduxsub;
556         struct comedi_device *this_comedidev;
557         struct comedi_subdevice *s;
558
559         /* the context variable points to the subdevice */
560         this_comedidev = urb->context;
561         /* the private structure of the subdevice is struct usbduxsub */
562         this_usbduxsub = this_comedidev->private;
563
564         s = this_comedidev->subdevices + SUBDEV_DA;
565
566         switch (urb->status) {
567         case 0:
568                 /* success */
569                 break;
570
571         case -ECONNRESET:
572         case -ENOENT:
573         case -ESHUTDOWN:
574         case -ECONNABORTED:
575                 /* after an unlink command, unplug, ... etc */
576                 /* no unlink needed here. Already shutting down. */
577                 if (this_usbduxsub->ao_cmd_running) {
578                         s->async->events |= COMEDI_CB_EOA;
579                         comedi_event(this_usbduxsub->comedidev, s);
580                         usbdux_ao_stop(this_usbduxsub, 0);
581                 }
582                 return;
583
584         default:
585                 /* a real error */
586                 if (this_usbduxsub->ao_cmd_running) {
587                         dev_err(&urb->dev->dev,
588                                 "comedi_: Non-zero urb status received in ao "
589                                 "intr context: %d\n", urb->status);
590                         s->async->events |= COMEDI_CB_ERROR;
591                         s->async->events |= COMEDI_CB_EOA;
592                         comedi_event(this_usbduxsub->comedidev, s);
593                         /* we do an unlink if we are in the high speed mode */
594                         usbdux_ao_stop(this_usbduxsub, 0);
595                 }
596                 return;
597         }
598
599         /* are we actually running? */
600         if (!(this_usbduxsub->ao_cmd_running))
601                 return;
602
603         /* normal operation: executing a command in this subdevice */
604         this_usbduxsub->ao_counter--;
605         if ((int)this_usbduxsub->ao_counter <= 0) {
606                 /* timer zero */
607                 this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
608
609                 /* handle non continous aquisition */
610                 if (!(this_usbduxsub->ao_continous)) {
611                         /* fixed number of samples */
612                         this_usbduxsub->ao_sample_count--;
613                         if (this_usbduxsub->ao_sample_count < 0) {
614                                 /* all samples transmitted */
615                                 usbdux_ao_stop(this_usbduxsub, 0);
616                                 s->async->events |= COMEDI_CB_EOA;
617                                 comedi_event(this_usbduxsub->comedidev, s);
618                                 /* no resubmit of the urb */
619                                 return;
620                         }
621                 }
622                 /* transmit data to the USB bus */
623                 ((uint8_t *) (urb->transfer_buffer))[0] =
624                     s->async->cmd.chanlist_len;
625                 for (i = 0; i < s->async->cmd.chanlist_len; i++) {
626                         short temp;
627                         if (i >= NUMOUTCHANNELS)
628                                 break;
629
630                         /* pointer to the DA */
631                         datap =
632                             (&(((uint8_t *) urb->transfer_buffer)[i * 2 + 1]));
633                         /* get the data from comedi */
634                         ret = comedi_buf_get(s->async, &temp);
635                         datap[0] = temp;
636                         datap[1] = this_usbduxsub->dac_commands[i];
637                         /* printk("data[0]=%x, data[1]=%x, data[2]=%x\n", */
638                         /* datap[0],datap[1],datap[2]); */
639                         if (ret < 0) {
640                                 dev_err(&urb->dev->dev,
641                                         "comedi: buffer underflow\n");
642                                 s->async->events |= COMEDI_CB_EOA;
643                                 s->async->events |= COMEDI_CB_OVERFLOW;
644                         }
645                         /* transmit data to comedi */
646                         s->async->events |= COMEDI_CB_BLOCK;
647                         comedi_event(this_usbduxsub->comedidev, s);
648                 }
649         }
650         urb->transfer_buffer_length = SIZEOUTBUF;
651         urb->dev = this_usbduxsub->usbdev;
652         urb->status = 0;
653         if (this_usbduxsub->ao_cmd_running) {
654                 if (this_usbduxsub->high_speed) {
655                         /* uframes */
656                         urb->interval = 8;
657                 } else {
658                         /* frames */
659                         urb->interval = 1;
660                 }
661                 urb->number_of_packets = 1;
662                 urb->iso_frame_desc[0].offset = 0;
663                 urb->iso_frame_desc[0].length = SIZEOUTBUF;
664                 urb->iso_frame_desc[0].status = 0;
665                 ret = usb_submit_urb(urb, GFP_ATOMIC);
666                 if (ret < 0) {
667                         dev_err(&urb->dev->dev,
668                                 "comedi_: ao urb resubm failed in int-cont. "
669                                 "ret=%d", ret);
670                         if (ret == EL2NSYNC)
671                                 dev_err(&urb->dev->dev,
672                                         "buggy USB host controller or bug in "
673                                         "IRQ handling!\n");
674
675                         s->async->events |= COMEDI_CB_EOA;
676                         s->async->events |= COMEDI_CB_ERROR;
677                         comedi_event(this_usbduxsub->comedidev, s);
678                         /* don't do an unlink here */
679                         usbdux_ao_stop(this_usbduxsub, 0);
680                 }
681         }
682 }
683
684 static int usbduxsub_start(struct usbduxsub *usbduxsub)
685 {
686         int errcode = 0;
687         uint8_t local_transfer_buffer[16];
688
689         /* 7f92 to zero */
690         local_transfer_buffer[0] = 0;
691         errcode = usb_control_msg(usbduxsub->usbdev,
692                                   /* create a pipe for a control transfer */
693                                   usb_sndctrlpipe(usbduxsub->usbdev, 0),
694                                   /* bRequest, "Firmware" */
695                                   USBDUXSUB_FIRMWARE,
696                                   /* bmRequestType */
697                                   VENDOR_DIR_OUT,
698                                   /* Value */
699                                   USBDUXSUB_CPUCS,
700                                   /* Index */
701                                   0x0000,
702                                   /* address of the transfer buffer */
703                                   local_transfer_buffer,
704                                   /* Length */
705                                   1,
706                                   /* Timeout */
707                                   BULK_TIMEOUT);
708         if (errcode < 0) {
709                 dev_err(&usbduxsub->interface->dev,
710                         "comedi_: control msg failed (start)\n");
711                 return errcode;
712         }
713         return 0;
714 }
715
716 static int usbduxsub_stop(struct usbduxsub *usbduxsub)
717 {
718         int errcode = 0;
719
720         uint8_t local_transfer_buffer[16];
721
722         /* 7f92 to one */
723         local_transfer_buffer[0] = 1;
724         errcode = usb_control_msg(usbduxsub->usbdev,
725                                   usb_sndctrlpipe(usbduxsub->usbdev, 0),
726                                   /* bRequest, "Firmware" */
727                                   USBDUXSUB_FIRMWARE,
728                                   /* bmRequestType */
729                                   VENDOR_DIR_OUT,
730                                   /* Value */
731                                   USBDUXSUB_CPUCS,
732                                   /* Index */
733                                   0x0000, local_transfer_buffer,
734                                   /* Length */
735                                   1,
736                                   /* Timeout */
737                                   BULK_TIMEOUT);
738         if (errcode < 0) {
739                 dev_err(&usbduxsub->interface->dev,
740                         "comedi_: control msg failed (stop)\n");
741                 return errcode;
742         }
743         return 0;
744 }
745
746 static int usbduxsub_upload(struct usbduxsub *usbduxsub,
747                             uint8_t *local_transfer_buffer,
748                             unsigned int startAddr, unsigned int len)
749 {
750         int errcode;
751
752         errcode = usb_control_msg(usbduxsub->usbdev,
753                                   usb_sndctrlpipe(usbduxsub->usbdev, 0),
754                                   /* brequest, firmware */
755                                   USBDUXSUB_FIRMWARE,
756                                   /* bmRequestType */
757                                   VENDOR_DIR_OUT,
758                                   /* value */
759                                   startAddr,
760                                   /* index */
761                                   0x0000,
762                                   /* our local safe buffer */
763                                   local_transfer_buffer,
764                                   /* length */
765                                   len,
766                                   /* timeout */
767                                   BULK_TIMEOUT);
768         dev_dbg(&usbduxsub->interface->dev, "comedi_: result=%d\n", errcode);
769         if (errcode < 0) {
770                 dev_err(&usbduxsub->interface->dev,
771                         "comedi_: upload failed\n");
772                 return errcode;
773         }
774         return 0;
775 }
776
777 /* the FX2LP has twice as much as the standard FX2 */
778 #define FIRMWARE_MAX_LEN 0x4000
779
780 static int firmwareUpload(struct usbduxsub *usbduxsub,
781                           const u8 *firmwareBinary, int sizeFirmware)
782 {
783         int ret;
784         uint8_t *fwBuf;
785
786         if (!firmwareBinary)
787                 return 0;
788
789         if (sizeFirmware > FIRMWARE_MAX_LEN) {
790                 dev_err(&usbduxsub->interface->dev,
791                         "usbduxsigma firmware binary it too large for FX2.\n");
792                 return -ENOMEM;
793         }
794
795         /* we generate a local buffer for the firmware */
796         fwBuf = kmemdup(firmwareBinary, sizeFirmware, GFP_KERNEL);
797         if (!fwBuf) {
798                 dev_err(&usbduxsub->interface->dev,
799                         "comedi_: mem alloc for firmware failed\n");
800                 return -ENOMEM;
801         }
802
803         ret = usbduxsub_stop(usbduxsub);
804         if (ret < 0) {
805                 dev_err(&usbduxsub->interface->dev,
806                         "comedi_: can not stop firmware\n");
807                 kfree(fwBuf);
808                 return ret;
809         }
810
811         ret = usbduxsub_upload(usbduxsub, fwBuf, 0, sizeFirmware);
812         if (ret < 0) {
813                 dev_err(&usbduxsub->interface->dev,
814                         "comedi_: firmware upload failed\n");
815                 kfree(fwBuf);
816                 return ret;
817         }
818         ret = usbduxsub_start(usbduxsub);
819         if (ret < 0) {
820                 dev_err(&usbduxsub->interface->dev,
821                         "comedi_: can not start firmware\n");
822                 kfree(fwBuf);
823                 return ret;
824         }
825         kfree(fwBuf);
826         return 0;
827 }
828
829 static int usbduxsub_submit_InURBs(struct usbduxsub *usbduxsub)
830 {
831         int i, errFlag;
832
833         if (!usbduxsub)
834                 return -EFAULT;
835
836         /* Submit all URBs and start the transfer on the bus */
837         for (i = 0; i < usbduxsub->numOfInBuffers; i++) {
838                 /* in case of a resubmission after an unlink... */
839                 usbduxsub->urbIn[i]->interval = usbduxsub->ai_interval;
840                 usbduxsub->urbIn[i]->context = usbduxsub->comedidev;
841                 usbduxsub->urbIn[i]->dev = usbduxsub->usbdev;
842                 usbduxsub->urbIn[i]->status = 0;
843                 usbduxsub->urbIn[i]->transfer_flags = URB_ISO_ASAP;
844                 dev_dbg(&usbduxsub->interface->dev,
845                         "comedi%d: submitting in-urb[%d]: %p,%p intv=%d\n",
846                         usbduxsub->comedidev->minor, i,
847                         (usbduxsub->urbIn[i]->context),
848                         (usbduxsub->urbIn[i]->dev),
849                         (usbduxsub->urbIn[i]->interval));
850                 errFlag = usb_submit_urb(usbduxsub->urbIn[i], GFP_ATOMIC);
851                 if (errFlag) {
852                         dev_err(&usbduxsub->interface->dev,
853                                 "comedi_: ai: usb_submit_urb(%d) error %d\n",
854                                 i, errFlag);
855                         return errFlag;
856                 }
857         }
858         return 0;
859 }
860
861 static int usbduxsub_submit_OutURBs(struct usbduxsub *usbduxsub)
862 {
863         int i, errFlag;
864
865         if (!usbduxsub)
866                 return -EFAULT;
867
868         for (i = 0; i < usbduxsub->numOfOutBuffers; i++) {
869                 dev_dbg(&usbduxsub->interface->dev,
870                         "comedi_: submitting out-urb[%d]\n", i);
871                 /* in case of a resubmission after an unlink... */
872                 usbduxsub->urbOut[i]->context = usbduxsub->comedidev;
873                 usbduxsub->urbOut[i]->dev = usbduxsub->usbdev;
874                 usbduxsub->urbOut[i]->status = 0;
875                 usbduxsub->urbOut[i]->transfer_flags = URB_ISO_ASAP;
876                 errFlag = usb_submit_urb(usbduxsub->urbOut[i], GFP_ATOMIC);
877                 if (errFlag) {
878                         dev_err(&usbduxsub->interface->dev,
879                                 "comedi_: ao: usb_submit_urb(%d) error %d\n",
880                                 i, errFlag);
881                         return errFlag;
882                 }
883         }
884         return 0;
885 }
886
887 static int chanToInterval(int nChannels)
888 {
889         if (nChannels <= 2)
890                 /* 4kHz */
891                 return 2;
892         if (nChannels <= 8)
893                 /* 2kHz */
894                 return 4;
895         /* 1kHz */
896         return 8;
897 }
898
899 static int usbdux_ai_cmdtest(struct comedi_device *dev,
900                              struct comedi_subdevice *s,
901                              struct comedi_cmd *cmd)
902 {
903         int err = 0, tmp, i;
904         unsigned int tmpTimer;
905         struct usbduxsub *this_usbduxsub = dev->private;
906
907         if (!(this_usbduxsub->probed))
908                 return -ENODEV;
909
910         dev_dbg(&this_usbduxsub->interface->dev,
911                 "comedi%d: usbdux_ai_cmdtest\n", dev->minor);
912
913         /* make sure triggers are valid */
914         /* Only immediate triggers are allowed */
915         tmp = cmd->start_src;
916         cmd->start_src &= TRIG_NOW | TRIG_INT;
917         if (!cmd->start_src || tmp != cmd->start_src)
918                 err++;
919
920         /* trigger should happen timed */
921         tmp = cmd->scan_begin_src;
922         /* start a new _scan_ with a timer */
923         cmd->scan_begin_src &= TRIG_TIMER;
924         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
925                 err++;
926
927         /* scanning is continous */
928         tmp = cmd->convert_src;
929         cmd->convert_src &= TRIG_NOW;
930         if (!cmd->convert_src || tmp != cmd->convert_src)
931                 err++;
932
933         /* issue a trigger when scan is finished and start a new scan */
934         tmp = cmd->scan_end_src;
935         cmd->scan_end_src &= TRIG_COUNT;
936         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
937                 err++;
938
939         /* trigger at the end of count events or not, stop condition or not */
940         tmp = cmd->stop_src;
941         cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
942         if (!cmd->stop_src || tmp != cmd->stop_src)
943                 err++;
944
945         if (err)
946                 return 1;
947
948         /*
949          * step 2: make sure trigger sources are unique and mutually compatible
950          * note that mutual compatibility is not an issue here
951          */
952         if (cmd->scan_begin_src != TRIG_FOLLOW &&
953             cmd->scan_begin_src != TRIG_EXT &&
954             cmd->scan_begin_src != TRIG_TIMER)
955                 err++;
956         if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
957                 err++;
958
959         if (err)
960                 return 2;
961
962         /* step 3: make sure arguments are trivially compatible */
963         if (cmd->start_arg != 0) {
964                 cmd->start_arg = 0;
965                 err++;
966         }
967
968         if (cmd->scan_begin_src == TRIG_FOLLOW) {
969                 /* internal trigger */
970                 if (cmd->scan_begin_arg != 0) {
971                         cmd->scan_begin_arg = 0;
972                         err++;
973                 }
974         }
975
976         if (cmd->scan_begin_src == TRIG_TIMER) {
977                 if (this_usbduxsub->high_speed) {
978                         /*
979                          * In high speed mode microframes are possible.
980                          * However, during one microframe we can roughly
981                          * sample two channels. Thus, the more channels
982                          * are in the channel list the more time we need.
983                          */
984                         i = chanToInterval(cmd->chanlist_len);
985                         if (cmd->scan_begin_arg < (1000000 / 8 * i)) {
986                                 cmd->scan_begin_arg = 1000000 / 8 * i;
987                                 err++;
988                         }
989                         /* now calc the real sampling rate with all the
990                          * rounding errors */
991                         tmpTimer =
992                             ((unsigned int)(cmd->scan_begin_arg / 125000)) *
993                             125000;
994                         if (cmd->scan_begin_arg != tmpTimer) {
995                                 cmd->scan_begin_arg = tmpTimer;
996                                 err++;
997                         }
998                 } else {
999                         /* full speed */
1000                         /* 1kHz scans every USB frame */
1001                         if (cmd->scan_begin_arg < 1000000) {
1002                                 cmd->scan_begin_arg = 1000000;
1003                                 err++;
1004                         }
1005                         /*
1006                          * calc the real sampling rate with the rounding errors
1007                          */
1008                         tmpTimer = ((unsigned int)(cmd->scan_begin_arg /
1009                                                    1000000)) * 1000000;
1010                         if (cmd->scan_begin_arg != tmpTimer) {
1011                                 cmd->scan_begin_arg = tmpTimer;
1012                                 err++;
1013                         }
1014                 }
1015         }
1016         /* the same argument */
1017         if (cmd->scan_end_arg != cmd->chanlist_len) {
1018                 cmd->scan_end_arg = cmd->chanlist_len;
1019                 err++;
1020         }
1021
1022         if (cmd->stop_src == TRIG_COUNT) {
1023                 /* any count is allowed */
1024         } else {
1025                 /* TRIG_NONE */
1026                 if (cmd->stop_arg != 0) {
1027                         cmd->stop_arg = 0;
1028                         err++;
1029                 }
1030         }
1031
1032         if (err)
1033                 return 3;
1034
1035         return 0;
1036 }
1037
1038 /*
1039  * creates the ADC command for the MAX1271
1040  * range is the range value from comedi
1041  */
1042 static void create_adc_command(unsigned int chan,
1043                                uint8_t *muxsg0,
1044                                uint8_t *muxsg1)
1045 {
1046         if (chan < 8)
1047                 (*muxsg0) = (*muxsg0) | (1 << chan);
1048         else if (chan < 16)
1049                 (*muxsg1) = (*muxsg1) | (1 << (chan-8));
1050 }
1051
1052
1053 /* bulk transfers to usbdux */
1054
1055 #define SENDADCOMMANDS            0
1056 #define SENDDACOMMANDS            1
1057 #define SENDDIOCONFIGCOMMAND      2
1058 #define SENDDIOBITSCOMMAND        3
1059 #define SENDSINGLEAD              4
1060 #define SENDPWMON                 7
1061 #define SENDPWMOFF                8
1062
1063 static int send_dux_commands(struct usbduxsub *this_usbduxsub, int cmd_type)
1064 {
1065         int result, nsent;
1066
1067         this_usbduxsub->dux_commands[0] = cmd_type;
1068 #ifdef NOISY_DUX_DEBUGBUG
1069         printk(KERN_DEBUG "comedi%d: usbdux: dux_commands: ",
1070                this_usbduxsub->comedidev->minor);
1071         for (result = 0; result < SIZEOFDUXBUFFER; result++)
1072                 printk(" %02x", this_usbduxsub->dux_commands[result]);
1073         printk("\n");
1074 #endif
1075         result = usb_bulk_msg(this_usbduxsub->usbdev,
1076                               usb_sndbulkpipe(this_usbduxsub->usbdev,
1077                                               COMMAND_OUT_EP),
1078                               this_usbduxsub->dux_commands, SIZEOFDUXBUFFER,
1079                               &nsent, BULK_TIMEOUT);
1080         if (result < 0)
1081                 dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
1082                         "could not transmit dux_command to the usb-device, "
1083                         "err=%d\n", this_usbduxsub->comedidev->minor, result);
1084
1085         return result;
1086 }
1087
1088 static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command)
1089 {
1090         int result = (-EFAULT);
1091         int nrec;
1092         int i;
1093
1094         for (i = 0; i < RETRIES; i++) {
1095                 result = usb_bulk_msg(this_usbduxsub->usbdev,
1096                                       usb_rcvbulkpipe(this_usbduxsub->usbdev,
1097                                                       COMMAND_IN_EP),
1098                                       this_usbduxsub->insnBuffer, SIZEINSNBUF,
1099                                       &nrec, BULK_TIMEOUT);
1100                 if (result < 0) {
1101                         dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
1102                                 "insn: USB error %d "
1103                                 "while receiving DUX command"
1104                                 "\n", this_usbduxsub->comedidev->minor,
1105                                 result);
1106                         return result;
1107                 }
1108                 if (this_usbduxsub->insnBuffer[0] == command)
1109                         return result;
1110         }
1111         /* this is only reached if the data has been requested a couple of
1112          * times */
1113         dev_err(&this_usbduxsub->interface->dev, "comedi%d: insn: "
1114                 "wrong data returned from firmware: want %d, got %d.\n",
1115                 this_usbduxsub->comedidev->minor, command,
1116                 this_usbduxsub->insnBuffer[0]);
1117         return -EFAULT;
1118 }
1119
1120 static int usbdux_ai_inttrig(struct comedi_device *dev,
1121                              struct comedi_subdevice *s, unsigned int trignum)
1122 {
1123         int ret;
1124         struct usbduxsub *this_usbduxsub = dev->private;
1125         if (!this_usbduxsub)
1126                 return -EFAULT;
1127
1128         down(&this_usbduxsub->sem);
1129         if (!(this_usbduxsub->probed)) {
1130                 up(&this_usbduxsub->sem);
1131                 return -ENODEV;
1132         }
1133         dev_dbg(&this_usbduxsub->interface->dev,
1134                 "comedi%d: usbdux_ai_inttrig\n", dev->minor);
1135
1136         if (trignum != 0) {
1137                 dev_err(&this_usbduxsub->interface->dev,
1138                         "comedi%d: usbdux_ai_inttrig: invalid trignum\n",
1139                         dev->minor);
1140                 up(&this_usbduxsub->sem);
1141                 return -EINVAL;
1142         }
1143         if (!(this_usbduxsub->ai_cmd_running)) {
1144                 this_usbduxsub->ai_cmd_running = 1;
1145                 ret = usbduxsub_submit_InURBs(this_usbduxsub);
1146                 if (ret < 0) {
1147                         dev_err(&this_usbduxsub->interface->dev,
1148                                 "comedi%d: usbdux_ai_inttrig: "
1149                                 "urbSubmit: err=%d\n", dev->minor, ret);
1150                         this_usbduxsub->ai_cmd_running = 0;
1151                         up(&this_usbduxsub->sem);
1152                         return ret;
1153                 }
1154                 s->async->inttrig = NULL;
1155         } else {
1156                 dev_err(&this_usbduxsub->interface->dev,
1157                         "comedi%d: ai_inttrig but acqu is already running\n",
1158                         dev->minor);
1159         }
1160         up(&this_usbduxsub->sem);
1161         return 1;
1162 }
1163
1164 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1165 {
1166         struct comedi_cmd *cmd = &s->async->cmd;
1167         unsigned int chan;
1168         int i, ret;
1169         struct usbduxsub *this_usbduxsub = dev->private;
1170         int result;
1171         uint8_t muxsg0 = 0;
1172         uint8_t muxsg1 = 0;
1173         uint8_t sysred = 0;
1174
1175         if (!this_usbduxsub)
1176                 return -EFAULT;
1177
1178         dev_dbg(&this_usbduxsub->interface->dev,
1179                 "comedi%d: usbdux_ai_cmd\n", dev->minor);
1180
1181         /* block other CPUs from starting an ai_cmd */
1182         down(&this_usbduxsub->sem);
1183
1184         if (!(this_usbduxsub->probed)) {
1185                 up(&this_usbduxsub->sem);
1186                 return -ENODEV;
1187         }
1188         if (this_usbduxsub->ai_cmd_running) {
1189                 dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
1190                         "ai_cmd not possible. Another ai_cmd is running.\n",
1191                         dev->minor);
1192                 up(&this_usbduxsub->sem);
1193                 return -EBUSY;
1194         }
1195         /* set current channel of the running aquisition to zero */
1196         s->async->cur_chan = 0;
1197
1198         /* first the number of channels per time step */
1199         this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
1200
1201         /* CONFIG0 */
1202         this_usbduxsub->dux_commands[2] = 0x12;
1203
1204         /* CONFIG1: 23kHz sampling rate, delay = 0us,  */
1205         this_usbduxsub->dux_commands[3] = 0x03;
1206
1207         /* CONFIG3: differential channels off */
1208         this_usbduxsub->dux_commands[4] = 0x00;
1209
1210         for (i = 0; i < cmd->chanlist_len; i++) {
1211                 chan = CR_CHAN(cmd->chanlist[i]);
1212                 create_adc_command(chan, &muxsg0, &muxsg1);
1213                 if (i >= NUMCHANNELS) {
1214                         dev_err(&this_usbduxsub->interface->dev,
1215                                 "comedi%d: channel list too long\n",
1216                                 dev->minor);
1217                         break;
1218                 }
1219         }
1220         this_usbduxsub->dux_commands[5] = muxsg0;
1221         this_usbduxsub->dux_commands[6] = muxsg1;
1222         this_usbduxsub->dux_commands[7] = sysred;
1223
1224         dev_dbg(&this_usbduxsub->interface->dev,
1225                 "comedi %d: sending commands to the usb device: size=%u\n",
1226                 dev->minor, NUMCHANNELS);
1227
1228         result = send_dux_commands(this_usbduxsub, SENDADCOMMANDS);
1229         if (result < 0) {
1230                 up(&this_usbduxsub->sem);
1231                 return result;
1232         }
1233
1234         if (this_usbduxsub->high_speed) {
1235                 /*
1236                  * every 2 channels get a time window of 125us. Thus, if we
1237                  * sample all 16 channels we need 1ms. If we sample only one
1238                  * channel we need only 125us
1239                  */
1240                 this_usbduxsub->ai_interval =
1241                         chanToInterval(cmd->chanlist_len);
1242                 this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
1243                                                           (this_usbduxsub->
1244                                                            ai_interval));
1245         } else {
1246                 /* interval always 1ms */
1247                 this_usbduxsub->ai_interval = 1;
1248                 this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000;
1249         }
1250         if (this_usbduxsub->ai_timer < 1) {
1251                 dev_err(&this_usbduxsub->interface->dev, "comedi%d: ai_cmd: "
1252                         "timer=%d, scan_begin_arg=%d. "
1253                         "Not properly tested by cmdtest?\n", dev->minor,
1254                         this_usbduxsub->ai_timer, cmd->scan_begin_arg);
1255                 up(&this_usbduxsub->sem);
1256                 return -EINVAL;
1257         }
1258         this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
1259
1260         if (cmd->stop_src == TRIG_COUNT) {
1261                 /* data arrives as one packet */
1262                 this_usbduxsub->ai_sample_count = cmd->stop_arg;
1263                 this_usbduxsub->ai_continous = 0;
1264         } else {
1265                 /* continous aquisition */
1266                 this_usbduxsub->ai_continous = 1;
1267                 this_usbduxsub->ai_sample_count = 0;
1268         }
1269
1270         if (cmd->start_src == TRIG_NOW) {
1271                 /* enable this acquisition operation */
1272                 this_usbduxsub->ai_cmd_running = 1;
1273                 ret = usbduxsub_submit_InURBs(this_usbduxsub);
1274                 if (ret < 0) {
1275                         this_usbduxsub->ai_cmd_running = 0;
1276                         /* fixme: unlink here?? */
1277                         up(&this_usbduxsub->sem);
1278                         return ret;
1279                 }
1280                 s->async->inttrig = NULL;
1281         } else {
1282                 /* TRIG_INT */
1283                 /* don't enable the acquision operation */
1284                 /* wait for an internal signal */
1285                 s->async->inttrig = usbdux_ai_inttrig;
1286         }
1287         up(&this_usbduxsub->sem);
1288         return 0;
1289 }
1290
1291 /* Mode 0 is used to get a single conversion on demand */
1292 static int usbdux_ai_insn_read(struct comedi_device *dev,
1293                                struct comedi_subdevice *s,
1294                                struct comedi_insn *insn, unsigned int *data)
1295 {
1296         int i;
1297         int32_t one = 0;
1298         int chan;
1299         int err;
1300         struct usbduxsub *this_usbduxsub = dev->private;
1301         uint8_t muxsg0 = 0;
1302         uint8_t muxsg1 = 0;
1303         uint8_t sysred = 0;
1304
1305         if (!this_usbduxsub)
1306                 return 0;
1307
1308         dev_dbg(&this_usbduxsub->interface->dev,
1309                 "comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n",
1310                 dev->minor, insn->n, insn->subdev);
1311
1312         down(&this_usbduxsub->sem);
1313         if (!(this_usbduxsub->probed)) {
1314                 up(&this_usbduxsub->sem);
1315                 return -ENODEV;
1316         }
1317         if (this_usbduxsub->ai_cmd_running) {
1318                 dev_err(&this_usbduxsub->interface->dev,
1319                         "comedi%d: ai_insn_read not possible. "
1320                         "Async Command is running.\n", dev->minor);
1321                 up(&this_usbduxsub->sem);
1322                 return 0;
1323         }
1324
1325         /* sample one channel */
1326         /* CONFIG0: chopper on */
1327         this_usbduxsub->dux_commands[1] = 0x16;
1328
1329         /* CONFIG1: 2kHz sampling rate */
1330         this_usbduxsub->dux_commands[2] = 0x80;
1331
1332         /* CONFIG3: differential channels off */
1333         this_usbduxsub->dux_commands[3] = 0x00;
1334
1335         chan = CR_CHAN(insn->chanspec);
1336         create_adc_command(chan, &muxsg0, &muxsg1);
1337
1338         this_usbduxsub->dux_commands[4] = muxsg0;
1339         this_usbduxsub->dux_commands[5] = muxsg1;
1340         this_usbduxsub->dux_commands[6] = sysred;
1341
1342         /* adc commands */
1343         err = send_dux_commands(this_usbduxsub, SENDSINGLEAD);
1344         if (err < 0) {
1345                 up(&this_usbduxsub->sem);
1346                 return err;
1347         }
1348
1349         for (i = 0; i < insn->n; i++) {
1350                 err = receive_dux_commands(this_usbduxsub, SENDSINGLEAD);
1351                 if (err < 0) {
1352                         up(&this_usbduxsub->sem);
1353                         return 0;
1354                 }
1355                 /* 32 bits big endian from the A/D converter */
1356                 one = be32_to_cpu(*((int32_t *)
1357                                     ((this_usbduxsub->insnBuffer)+1)));
1358                 /* mask out the staus byte */
1359                 one = one & 0x00ffffff;
1360                 /* turn it into an unsigned integer */
1361                 one = one ^ 0x00800000;
1362                 data[i] = one;
1363         }
1364         up(&this_usbduxsub->sem);
1365         return i;
1366 }
1367
1368
1369
1370
1371 static int usbdux_getstatusinfo(struct comedi_device *dev, int chan)
1372 {
1373         struct usbduxsub *this_usbduxsub = dev->private;
1374         uint8_t sysred = 0;
1375         uint32_t one;
1376         int err;
1377
1378         if (!this_usbduxsub)
1379                 return 0;
1380
1381         if (this_usbduxsub->ai_cmd_running) {
1382                 dev_err(&this_usbduxsub->interface->dev,
1383                         "comedi%d: status read not possible. "
1384                         "Async Command is running.\n", dev->minor);
1385                 return 0;
1386         }
1387
1388         /* CONFIG0 */
1389         this_usbduxsub->dux_commands[1] = 0x12;
1390
1391         /* CONFIG1: 2kHz sampling rate */
1392         this_usbduxsub->dux_commands[2] = 0x80;
1393
1394         /* CONFIG3: differential channels off */
1395         this_usbduxsub->dux_commands[3] = 0x00;
1396
1397         if (chan == 1) {
1398                 /* ADC offset */
1399                 sysred = sysred | 1;
1400         } else if (chan == 2) {
1401                 /* VCC */
1402                 sysred = sysred | 4;
1403         } else if (chan == 3) {
1404                 /* temperature */
1405                 sysred = sysred | 8;
1406         } else if (chan == 4) {
1407                 /* gain */
1408                 sysred = sysred | 16;
1409         } else if (chan == 5) {
1410                 /* ref */
1411                 sysred = sysred | 32;
1412         }
1413
1414         this_usbduxsub->dux_commands[4] = 0;
1415         this_usbduxsub->dux_commands[5] = 0;
1416         this_usbduxsub->dux_commands[6] = sysred;
1417
1418         /* adc commands */
1419         err = send_dux_commands(this_usbduxsub, SENDSINGLEAD);
1420         if (err < 0)
1421                 return err;
1422
1423         err = receive_dux_commands(this_usbduxsub, SENDSINGLEAD);
1424         if (err < 0)
1425                 return err;
1426
1427         /* 32 bits big endian from the A/D converter */
1428         one = be32_to_cpu(*((int32_t *)((this_usbduxsub->insnBuffer)+1)));
1429         /* mask out the staus byte */
1430         one = one & 0x00ffffff;
1431         one = one ^ 0x00800000;
1432
1433         return (int)one;
1434 }
1435
1436
1437
1438
1439
1440
1441 /************************************/
1442 /* analog out */
1443
1444 static int usbdux_ao_insn_read(struct comedi_device *dev,
1445                                struct comedi_subdevice *s,
1446                                struct comedi_insn *insn, unsigned int *data)
1447 {
1448         int i;
1449         int chan = CR_CHAN(insn->chanspec);
1450         struct usbduxsub *this_usbduxsub = dev->private;
1451
1452         if (!this_usbduxsub)
1453                 return -EFAULT;
1454
1455         down(&this_usbduxsub->sem);
1456         if (!(this_usbduxsub->probed)) {
1457                 up(&this_usbduxsub->sem);
1458                 return -ENODEV;
1459         }
1460         for (i = 0; i < insn->n; i++)
1461                 data[i] = this_usbduxsub->outBuffer[chan];
1462
1463         up(&this_usbduxsub->sem);
1464         return i;
1465 }
1466
1467 static int usbdux_ao_insn_write(struct comedi_device *dev,
1468                                 struct comedi_subdevice *s,
1469                                 struct comedi_insn *insn, unsigned int *data)
1470 {
1471         int i, err;
1472         int chan = CR_CHAN(insn->chanspec);
1473         struct usbduxsub *this_usbduxsub = dev->private;
1474
1475         if (!this_usbduxsub)
1476                 return -EFAULT;
1477
1478         dev_dbg(&this_usbduxsub->interface->dev,
1479                 "comedi%d: ao_insn_write\n", dev->minor);
1480
1481         down(&this_usbduxsub->sem);
1482         if (!(this_usbduxsub->probed)) {
1483                 up(&this_usbduxsub->sem);
1484                 return -ENODEV;
1485         }
1486         if (this_usbduxsub->ao_cmd_running) {
1487                 dev_err(&this_usbduxsub->interface->dev,
1488                         "comedi%d: ao_insn_write: "
1489                         "ERROR: asynchronous ao_cmd is running\n", dev->minor);
1490                 up(&this_usbduxsub->sem);
1491                 return 0;
1492         }
1493
1494         for (i = 0; i < insn->n; i++) {
1495                 dev_dbg(&this_usbduxsub->interface->dev,
1496                         "comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n",
1497                         dev->minor, chan, i, data[i]);
1498
1499                 /* number of channels: 1 */
1500                 this_usbduxsub->dux_commands[1] = 1;
1501                 /* channel number */
1502                 this_usbduxsub->dux_commands[2] = data[i];
1503                 this_usbduxsub->outBuffer[chan] = data[i];
1504                 this_usbduxsub->dux_commands[3] = chan;
1505                 err = send_dux_commands(this_usbduxsub, SENDDACOMMANDS);
1506                 if (err < 0) {
1507                         up(&this_usbduxsub->sem);
1508                         return err;
1509                 }
1510         }
1511         up(&this_usbduxsub->sem);
1512
1513         return i;
1514 }
1515
1516 static int usbdux_ao_inttrig(struct comedi_device *dev,
1517                              struct comedi_subdevice *s, unsigned int trignum)
1518 {
1519         int ret;
1520         struct usbduxsub *this_usbduxsub = dev->private;
1521
1522         if (!this_usbduxsub)
1523                 return -EFAULT;
1524
1525         down(&this_usbduxsub->sem);
1526         if (!(this_usbduxsub->probed)) {
1527                 up(&this_usbduxsub->sem);
1528                 return -ENODEV;
1529         }
1530         if (trignum != 0) {
1531                 dev_err(&this_usbduxsub->interface->dev,
1532                         "comedi%d: usbdux_ao_inttrig: invalid trignum\n",
1533                         dev->minor);
1534                 return -EINVAL;
1535         }
1536         if (!(this_usbduxsub->ao_cmd_running)) {
1537                 this_usbduxsub->ao_cmd_running = 1;
1538                 ret = usbduxsub_submit_OutURBs(this_usbduxsub);
1539                 if (ret < 0) {
1540                         dev_err(&this_usbduxsub->interface->dev,
1541                                 "comedi%d: usbdux_ao_inttrig: submitURB: "
1542                                 "err=%d\n", dev->minor, ret);
1543                         this_usbduxsub->ao_cmd_running = 0;
1544                         up(&this_usbduxsub->sem);
1545                         return ret;
1546                 }
1547                 s->async->inttrig = NULL;
1548         } else {
1549                 dev_err(&this_usbduxsub->interface->dev,
1550                         "comedi%d: ao_inttrig but acqu is already running.\n",
1551                         dev->minor);
1552         }
1553         up(&this_usbduxsub->sem);
1554         return 1;
1555 }
1556
1557 static int usbdux_ao_cmdtest(struct comedi_device *dev,
1558                              struct comedi_subdevice *s,
1559                              struct comedi_cmd *cmd)
1560 {
1561         int err = 0, tmp;
1562         struct usbduxsub *this_usbduxsub = dev->private;
1563
1564         if (!this_usbduxsub)
1565                 return -EFAULT;
1566
1567         if (!(this_usbduxsub->probed))
1568                 return -ENODEV;
1569
1570         dev_dbg(&this_usbduxsub->interface->dev,
1571                 "comedi%d: usbdux_ao_cmdtest\n", dev->minor);
1572
1573         /* make sure triggers are valid */
1574         /* Only immediate triggers are allowed */
1575         tmp = cmd->start_src;
1576         cmd->start_src &= TRIG_NOW | TRIG_INT;
1577         if (!cmd->start_src || tmp != cmd->start_src)
1578                 err++;
1579
1580         /* trigger should happen timed */
1581         tmp = cmd->scan_begin_src;
1582         /* just now we scan also in the high speed mode every frame */
1583         /* this is due to ehci driver limitations */
1584         if (0) {                /* (this_usbduxsub->high_speed) */
1585                 /* start immidiately a new scan */
1586                 /* the sampling rate is set by the coversion rate */
1587                 cmd->scan_begin_src &= TRIG_FOLLOW;
1588         } else {
1589                 /* start a new scan (output at once) with a timer */
1590                 cmd->scan_begin_src &= TRIG_TIMER;
1591         }
1592         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1593                 err++;
1594
1595         /* scanning is continous */
1596         tmp = cmd->convert_src;
1597
1598         /* all conversion events happen simultaneously */
1599         cmd->convert_src &= TRIG_NOW;
1600
1601         if (!cmd->convert_src || tmp != cmd->convert_src)
1602                 err++;
1603
1604         /* issue a trigger when scan is finished and start a new scan */
1605         tmp = cmd->scan_end_src;
1606         cmd->scan_end_src &= TRIG_COUNT;
1607         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1608                 err++;
1609
1610         /* trigger at the end of count events or not, stop condition or not */
1611         tmp = cmd->stop_src;
1612         cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1613         if (!cmd->stop_src || tmp != cmd->stop_src)
1614                 err++;
1615
1616         if (err)
1617                 return 1;
1618
1619         /*
1620          * step 2: make sure trigger sources
1621          * are unique and mutually compatible
1622          * note that mutual compatibility is not an issue here
1623          */
1624         if (cmd->scan_begin_src != TRIG_FOLLOW &&
1625             cmd->scan_begin_src != TRIG_EXT &&
1626             cmd->scan_begin_src != TRIG_TIMER)
1627                 err++;
1628         if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1629                 err++;
1630
1631         if (err)
1632                 return 2;
1633
1634         /* step 3: make sure arguments are trivially compatible */
1635
1636         if (cmd->start_arg != 0) {
1637                 cmd->start_arg = 0;
1638                 err++;
1639         }
1640
1641         if (cmd->scan_begin_src == TRIG_FOLLOW) {
1642                 /* internal trigger */
1643                 if (cmd->scan_begin_arg != 0) {
1644                         cmd->scan_begin_arg = 0;
1645                         err++;
1646                 }
1647         }
1648
1649         if (cmd->scan_begin_src == TRIG_TIMER) {
1650                 /* timer */
1651                 if (cmd->scan_begin_arg < 1000000) {
1652                         cmd->scan_begin_arg = 1000000;
1653                         err++;
1654                 }
1655         }
1656         /* not used now, is for later use */
1657         if (cmd->convert_src == TRIG_TIMER) {
1658                 if (cmd->convert_arg < 125000) {
1659                         cmd->convert_arg = 125000;
1660                         err++;
1661                 }
1662         }
1663
1664         /* the same argument */
1665         if (cmd->scan_end_arg != cmd->chanlist_len) {
1666                 cmd->scan_end_arg = cmd->chanlist_len;
1667                 err++;
1668         }
1669
1670         if (cmd->stop_src == TRIG_COUNT) {
1671                 /* any count is allowed */
1672         } else {
1673                 /* TRIG_NONE */
1674                 if (cmd->stop_arg != 0) {
1675                         cmd->stop_arg = 0;
1676                         err++;
1677                 }
1678         }
1679
1680         dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: err=%d, "
1681                 "scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, "
1682                 "convert_arg=%d\n", dev->minor, err, cmd->scan_begin_src,
1683                 cmd->scan_begin_arg, cmd->convert_src, cmd->convert_arg);
1684
1685         if (err)
1686                 return 3;
1687
1688         return 0;
1689 }
1690
1691 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1692 {
1693         struct comedi_cmd *cmd = &s->async->cmd;
1694         unsigned int chan, gain;
1695         int i, ret;
1696         struct usbduxsub *this_usbduxsub = dev->private;
1697
1698         if (!this_usbduxsub)
1699                 return -EFAULT;
1700
1701         down(&this_usbduxsub->sem);
1702         if (!(this_usbduxsub->probed)) {
1703                 up(&this_usbduxsub->sem);
1704                 return -ENODEV;
1705         }
1706         dev_dbg(&this_usbduxsub->interface->dev,
1707                 "comedi%d: %s\n", dev->minor, __func__);
1708
1709         /* set current channel of the running aquisition to zero */
1710         s->async->cur_chan = 0;
1711         for (i = 0; i < cmd->chanlist_len; ++i) {
1712                 chan = CR_CHAN(cmd->chanlist[i]);
1713                 gain = CR_RANGE(cmd->chanlist[i]);
1714                 if (i >= NUMOUTCHANNELS) {
1715                         dev_err(&this_usbduxsub->interface->dev,
1716                                 "comedi%d: %s: channel list too long\n",
1717                                 dev->minor, __func__);
1718                         break;
1719                 }
1720                 this_usbduxsub->dac_commands[i] = chan;
1721                 dev_dbg(&this_usbduxsub->interface->dev,
1722                         "comedi%d: dac command for ch %d is %x\n",
1723                         dev->minor, i, this_usbduxsub->dac_commands[i]);
1724         }
1725
1726         /* we count in steps of 1ms (125us) */
1727         /* 125us mode not used yet */
1728         if (0) {                /* (this_usbduxsub->high_speed) */
1729                 /* 125us */
1730                 /* timing of the conversion itself: every 125 us */
1731                 this_usbduxsub->ao_timer = cmd->convert_arg / 125000;
1732         } else {
1733                 /* 1ms */
1734                 /* timing of the scan: we get all channels at once */
1735                 this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000;
1736                 dev_dbg(&this_usbduxsub->interface->dev,
1737                         "comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
1738                         "convert_src=%d, convert_arg=%d\n", dev->minor,
1739                         cmd->scan_begin_src, cmd->scan_begin_arg,
1740                         cmd->convert_src, cmd->convert_arg);
1741                 dev_dbg(&this_usbduxsub->interface->dev,
1742                         "comedi%d: ao_timer=%d (ms)\n",
1743                         dev->minor, this_usbduxsub->ao_timer);
1744                 if (this_usbduxsub->ao_timer < 1) {
1745                         dev_err(&this_usbduxsub->interface->dev,
1746                                 "comedi%d: usbdux: ao_timer=%d, "
1747                                 "scan_begin_arg=%d. "
1748                                 "Not properly tested by cmdtest?\n",
1749                                 dev->minor, this_usbduxsub->ao_timer,
1750                                 cmd->scan_begin_arg);
1751                         up(&this_usbduxsub->sem);
1752                         return -EINVAL;
1753                 }
1754         }
1755         this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
1756
1757         if (cmd->stop_src == TRIG_COUNT) {
1758                 /* not continous */
1759                 /* counter */
1760                 /* high speed also scans everything at once */
1761                 if (0) {        /* (this_usbduxsub->high_speed) */
1762                         this_usbduxsub->ao_sample_count =
1763                             (cmd->stop_arg) * (cmd->scan_end_arg);
1764                 } else {
1765                         /* there's no scan as the scan has been */
1766                         /* perf inside the FX2 */
1767                         /* data arrives as one packet */
1768                         this_usbduxsub->ao_sample_count = cmd->stop_arg;
1769                 }
1770                 this_usbduxsub->ao_continous = 0;
1771         } else {
1772                 /* continous aquisition */
1773                 this_usbduxsub->ao_continous = 1;
1774                 this_usbduxsub->ao_sample_count = 0;
1775         }
1776
1777         if (cmd->start_src == TRIG_NOW) {
1778                 /* enable this acquisition operation */
1779                 this_usbduxsub->ao_cmd_running = 1;
1780                 ret = usbduxsub_submit_OutURBs(this_usbduxsub);
1781                 if (ret < 0) {
1782                         this_usbduxsub->ao_cmd_running = 0;
1783                         /* fixme: unlink here?? */
1784                         up(&this_usbduxsub->sem);
1785                         return ret;
1786                 }
1787                 s->async->inttrig = NULL;
1788         } else {
1789                 /* TRIG_INT */
1790                 /* submit the urbs later */
1791                 /* wait for an internal signal */
1792                 s->async->inttrig = usbdux_ao_inttrig;
1793         }
1794
1795         up(&this_usbduxsub->sem);
1796         return 0;
1797 }
1798
1799 static int usbdux_dio_insn_config(struct comedi_device *dev,
1800                                   struct comedi_subdevice *s,
1801                                   struct comedi_insn *insn, unsigned int *data)
1802 {
1803         int chan = CR_CHAN(insn->chanspec);
1804
1805         /* The input or output configuration of each digital line is
1806          * configured by a special insn_config instruction.  chanspec
1807          * contains the channel to be changed, and data[0] contains the
1808          * value COMEDI_INPUT or COMEDI_OUTPUT. */
1809
1810         switch (data[0]) {
1811         case INSN_CONFIG_DIO_OUTPUT:
1812                 s->io_bits |= 1 << chan;        /* 1 means Out */
1813                 break;
1814         case INSN_CONFIG_DIO_INPUT:
1815                 s->io_bits &= ~(1 << chan);
1816                 break;
1817         case INSN_CONFIG_DIO_QUERY:
1818                 data[1] =
1819                     (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1820                 break;
1821         default:
1822                 return -EINVAL;
1823                 break;
1824         }
1825         /* we don't tell the firmware here as it would take 8 frames */
1826         /* to submit the information. We do it in the insn_bits. */
1827         return insn->n;
1828 }
1829
1830 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1831                                 struct comedi_subdevice *s,
1832                                 struct comedi_insn *insn,
1833                                 unsigned int *data)
1834 {
1835
1836         struct usbduxsub *this_usbduxsub = dev->private;
1837         int err;
1838
1839         if (!this_usbduxsub)
1840                 return -EFAULT;
1841
1842         if (insn->n != 2)
1843                 return -EINVAL;
1844
1845         down(&this_usbduxsub->sem);
1846
1847         if (!(this_usbduxsub->probed)) {
1848                 up(&this_usbduxsub->sem);
1849                 return -ENODEV;
1850         }
1851
1852         /* The insn data is a mask in data[0] and the new data
1853          * in data[1], each channel cooresponding to a bit. */
1854         s->state &= ~data[0];
1855         s->state |= data[0] & data[1];
1856         /* The commands are 8 bits wide */
1857         this_usbduxsub->dux_commands[1] = (s->io_bits) & 0x000000FF;
1858         this_usbduxsub->dux_commands[4] = (s->state) & 0x000000FF;
1859         this_usbduxsub->dux_commands[2] = ((s->io_bits) & 0x0000FF00) >> 8;
1860         this_usbduxsub->dux_commands[5] = ((s->state) & 0x0000FF00) >> 8;
1861         this_usbduxsub->dux_commands[3] = ((s->io_bits) & 0x00FF0000) >> 16;
1862         this_usbduxsub->dux_commands[6] = ((s->state) & 0x00FF0000) >> 16;
1863
1864         /* This command also tells the firmware to return */
1865         /* the digital input lines */
1866         err = send_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1867         if (err < 0) {
1868                 up(&this_usbduxsub->sem);
1869                 return err;
1870         }
1871         err = receive_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1872         if (err < 0) {
1873                 up(&this_usbduxsub->sem);
1874                 return err;
1875         }
1876
1877         data[1] = (((unsigned int)(this_usbduxsub->insnBuffer[1]))&0xff) |
1878                 ((((unsigned int)(this_usbduxsub->insnBuffer[2]))&0xff) << 8) |
1879                 ((((unsigned int)(this_usbduxsub->insnBuffer[3]))&0xff) << 16);
1880
1881         s->state = data[1];
1882
1883         up(&this_usbduxsub->sem);
1884         return 2;
1885 }
1886
1887 /***********************************/
1888 /* PWM */
1889
1890 static int usbduxsub_unlink_PwmURBs(struct usbduxsub *usbduxsub_tmp)
1891 {
1892         int err = 0;
1893
1894         if (usbduxsub_tmp && usbduxsub_tmp->urbPwm) {
1895                 if (usbduxsub_tmp->urbPwm)
1896                         usb_kill_urb(usbduxsub_tmp->urbPwm);
1897                 dev_dbg(&usbduxsub_tmp->interface->dev,
1898                         "comedi: unlinked PwmURB: res=%d\n", err);
1899         }
1900         return err;
1901 }
1902
1903 /* This cancels a running acquisition operation
1904  * in any context.
1905  */
1906 static int usbdux_pwm_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
1907 {
1908         int ret = 0;
1909
1910         if (!this_usbduxsub)
1911                 return -EFAULT;
1912
1913         dev_dbg(&this_usbduxsub->interface->dev, "comedi: %s\n", __func__);
1914         if (do_unlink)
1915                 ret = usbduxsub_unlink_PwmURBs(this_usbduxsub);
1916
1917         this_usbduxsub->pwm_cmd_running = 0;
1918
1919         return ret;
1920 }
1921
1922 /* force unlink - is called by comedi */
1923 static int usbdux_pwm_cancel(struct comedi_device *dev,
1924                              struct comedi_subdevice *s)
1925 {
1926         struct usbduxsub *this_usbduxsub = dev->private;
1927         int res = 0;
1928
1929         /* unlink only if it is really running */
1930         res = usbdux_pwm_stop(this_usbduxsub, this_usbduxsub->pwm_cmd_running);
1931
1932         dev_dbg(&this_usbduxsub->interface->dev,
1933                 "comedi %d: sending pwm off command to the usb device.\n",
1934                 dev->minor);
1935         res = send_dux_commands(this_usbduxsub, SENDPWMOFF);
1936         if (res < 0)
1937                 return res;
1938
1939         return res;
1940 }
1941
1942 static void usbduxsub_pwm_irq(struct urb *urb)
1943 {
1944         int ret;
1945         struct usbduxsub *this_usbduxsub;
1946         struct comedi_device *this_comedidev;
1947         struct comedi_subdevice *s;
1948
1949         /* printk(KERN_DEBUG "PWM: IRQ\n"); */
1950
1951         /* the context variable points to the subdevice */
1952         this_comedidev = urb->context;
1953         /* the private structure of the subdevice is struct usbduxsub */
1954         this_usbduxsub = this_comedidev->private;
1955
1956         s = this_comedidev->subdevices + SUBDEV_DA;
1957
1958         switch (urb->status) {
1959         case 0:
1960                 /* success */
1961                 break;
1962
1963         case -ECONNRESET:
1964         case -ENOENT:
1965         case -ESHUTDOWN:
1966         case -ECONNABORTED:
1967                 /*
1968                  * after an unlink command, unplug, ... etc
1969                  * no unlink needed here. Already shutting down.
1970                  */
1971                 if (this_usbduxsub->pwm_cmd_running)
1972                         usbdux_pwm_stop(this_usbduxsub, 0);
1973
1974                 return;
1975
1976         default:
1977                 /* a real error */
1978                 if (this_usbduxsub->pwm_cmd_running) {
1979                         dev_err(&this_usbduxsub->interface->dev,
1980                                 "comedi_: Non-zero urb status received in "
1981                                 "pwm intr context: %d\n", urb->status);
1982                         usbdux_pwm_stop(this_usbduxsub, 0);
1983                 }
1984                 return;
1985         }
1986
1987         /* are we actually running? */
1988         if (!(this_usbduxsub->pwm_cmd_running))
1989                 return;
1990
1991         urb->transfer_buffer_length = this_usbduxsub->sizePwmBuf;
1992         urb->dev = this_usbduxsub->usbdev;
1993         urb->status = 0;
1994         if (this_usbduxsub->pwm_cmd_running) {
1995                 ret = usb_submit_urb(urb, GFP_ATOMIC);
1996                 if (ret < 0) {
1997                         dev_err(&this_usbduxsub->interface->dev,
1998                                 "comedi_: pwm urb resubm failed in int-cont. "
1999                                 "ret=%d", ret);
2000                         if (ret == EL2NSYNC)
2001                                 dev_err(&this_usbduxsub->interface->dev,
2002                                         "buggy USB host controller or bug in "
2003                                         "IRQ handling!\n");
2004
2005                         /* don't do an unlink here */
2006                         usbdux_pwm_stop(this_usbduxsub, 0);
2007                 }
2008         }
2009 }
2010
2011 static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub)
2012 {
2013         int errFlag;
2014
2015         if (!usbduxsub)
2016                 return -EFAULT;
2017
2018         dev_dbg(&usbduxsub->interface->dev, "comedi_: submitting pwm-urb\n");
2019
2020         /* in case of a resubmission after an unlink... */
2021         usb_fill_bulk_urb(usbduxsub->urbPwm,
2022                           usbduxsub->usbdev,
2023                           usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP),
2024                           usbduxsub->urbPwm->transfer_buffer,
2025                           usbduxsub->sizePwmBuf, usbduxsub_pwm_irq,
2026                           usbduxsub->comedidev);
2027
2028         errFlag = usb_submit_urb(usbduxsub->urbPwm, GFP_ATOMIC);
2029         if (errFlag) {
2030                 dev_err(&usbduxsub->interface->dev,
2031                         "comedi_: usbduxsigma: pwm: usb_submit_urb error %d\n",
2032                         errFlag);
2033                 return errFlag;
2034         }
2035         return 0;
2036 }
2037
2038 static int usbdux_pwm_period(struct comedi_device *dev,
2039                              struct comedi_subdevice *s, unsigned int period)
2040 {
2041         struct usbduxsub *this_usbduxsub = dev->private;
2042         int fx2delay = 255;
2043
2044         if (period < MIN_PWM_PERIOD) {
2045                 dev_err(&this_usbduxsub->interface->dev,
2046                         "comedi%d: illegal period setting for pwm.\n",
2047                         dev->minor);
2048                 return -EAGAIN;
2049         } else {
2050                 fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
2051                 if (fx2delay > 255) {
2052                         dev_err(&this_usbduxsub->interface->dev,
2053                                 "comedi%d: period %d for pwm is too low.\n",
2054                                 dev->minor, period);
2055                         return -EAGAIN;
2056                 }
2057         }
2058         this_usbduxsub->pwmDelay = fx2delay;
2059         this_usbduxsub->pwmPeriod = period;
2060         dev_dbg(&this_usbduxsub->interface->dev, "%s: frequ=%d, period=%d\n",
2061                 __func__, period, fx2delay);
2062         return 0;
2063 }
2064
2065 /* is called from insn so there's no need to do all the sanity checks */
2066 static int usbdux_pwm_start(struct comedi_device *dev,
2067                             struct comedi_subdevice *s)
2068 {
2069         int ret, i;
2070         struct usbduxsub *this_usbduxsub = dev->private;
2071
2072         dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: %s\n",
2073                 dev->minor, __func__);
2074
2075         if (this_usbduxsub->pwm_cmd_running) {
2076                 /* already running */
2077                 return 0;
2078         }
2079
2080         this_usbduxsub->dux_commands[1] = ((uint8_t) this_usbduxsub->pwmDelay);
2081         ret = send_dux_commands(this_usbduxsub, SENDPWMON);
2082         if (ret < 0)
2083                 return ret;
2084
2085         /* initialise the buffer */
2086         for (i = 0; i < this_usbduxsub->sizePwmBuf; i++)
2087                 ((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0;
2088
2089         this_usbduxsub->pwm_cmd_running = 1;
2090         ret = usbduxsub_submit_PwmURBs(this_usbduxsub);
2091         if (ret < 0) {
2092                 this_usbduxsub->pwm_cmd_running = 0;
2093                 return ret;
2094         }
2095         return 0;
2096 }
2097
2098 /* generates the bit pattern for PWM with the optional sign bit */
2099 static int usbdux_pwm_pattern(struct comedi_device *dev,
2100                               struct comedi_subdevice *s, int channel,
2101                               unsigned int value, unsigned int sign)
2102 {
2103         struct usbduxsub *this_usbduxsub = dev->private;
2104         int i, szbuf;
2105         char *pBuf;
2106         char pwm_mask;
2107         char sgn_mask;
2108         char c;
2109
2110         if (!this_usbduxsub)
2111                 return -EFAULT;
2112
2113         /* this is the DIO bit which carries the PWM data */
2114         pwm_mask = (1 << channel);
2115         /* this is the DIO bit which carries the optional direction bit */
2116         sgn_mask = (16 << channel);
2117         /* this is the buffer which will be filled with the with bit */
2118         /* pattern for one period */
2119         szbuf = this_usbduxsub->sizePwmBuf;
2120         pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer);
2121         for (i = 0; i < szbuf; i++) {
2122                 c = *pBuf;
2123                 /* reset bits */
2124                 c = c & (~pwm_mask);
2125                 /* set the bit as long as the index is lower than the value */
2126                 if (i < value)
2127                         c = c | pwm_mask;
2128                 /* set the optional sign bit for a relay */
2129                 if (!sign) {
2130                         /* positive value */
2131                         c = c & (~sgn_mask);
2132                 } else {
2133                         /* negative value */
2134                         c = c | sgn_mask;
2135                 }
2136                 *(pBuf++) = c;
2137         }
2138         return 1;
2139 }
2140
2141 static int usbdux_pwm_write(struct comedi_device *dev,
2142                             struct comedi_subdevice *s,
2143                             struct comedi_insn *insn, unsigned int *data)
2144 {
2145         struct usbduxsub *this_usbduxsub = dev->private;
2146
2147         if (!this_usbduxsub)
2148                 return -EFAULT;
2149
2150         if ((insn->n) != 1) {
2151                 /*
2152                  * doesn't make sense to have more than one value here because
2153                  * it would just overwrite the PWM buffer a couple of times
2154                  */
2155                 return -EINVAL;
2156         }
2157
2158         /*
2159          * the sign is set via a special INSN only, this gives us 8 bits for
2160          * normal operation
2161          * relay sign 0 by default
2162          */
2163         return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
2164 }
2165
2166 static int usbdux_pwm_read(struct comedi_device *x1,
2167                            struct comedi_subdevice *x2, struct comedi_insn *x3,
2168                            unsigned int *x4)
2169 {
2170         /* not needed */
2171         return -EINVAL;
2172 };
2173
2174 /* switches on/off PWM */
2175 static int usbdux_pwm_config(struct comedi_device *dev,
2176                              struct comedi_subdevice *s,
2177                              struct comedi_insn *insn, unsigned int *data)
2178 {
2179         struct usbduxsub *this_usbduxsub = dev->private;
2180         switch (data[0]) {
2181         case INSN_CONFIG_ARM:
2182                 /* switch it on */
2183                 dev_dbg(&this_usbduxsub->interface->dev,
2184                         "comedi%d: %s: pwm on\n", dev->minor, __func__);
2185                 /*
2186                  * if not zero the PWM is limited to a certain time which is
2187                  * not supported here
2188                  */
2189                 if (data[1] != 0)
2190                         return -EINVAL;
2191                 return usbdux_pwm_start(dev, s);
2192         case INSN_CONFIG_DISARM:
2193                 dev_dbg(&this_usbduxsub->interface->dev,
2194                         "comedi%d: %s: pwm off\n", dev->minor, __func__);
2195                 return usbdux_pwm_cancel(dev, s);
2196         case INSN_CONFIG_GET_PWM_STATUS:
2197                 /*
2198                  * to check if the USB transmission has failed or in case PWM
2199                  * was limited to n cycles to check if it has terminated
2200                  */
2201                 data[1] = this_usbduxsub->pwm_cmd_running;
2202                 return 0;
2203         case INSN_CONFIG_PWM_SET_PERIOD:
2204                 dev_dbg(&this_usbduxsub->interface->dev,
2205                         "comedi%d: %s: setting period\n", dev->minor,
2206                         __func__);
2207                 return usbdux_pwm_period(dev, s, data[1]);
2208         case INSN_CONFIG_PWM_GET_PERIOD:
2209                 data[1] = this_usbduxsub->pwmPeriod;
2210                 return 0;
2211         case INSN_CONFIG_PWM_SET_H_BRIDGE:
2212                 /* value in the first byte and the sign in the second for a
2213                    relay */
2214                 return usbdux_pwm_pattern(dev, s,
2215                                           /* the channel number */
2216                                           CR_CHAN(insn->chanspec),
2217                                           /* actual PWM data */
2218                                           data[1],
2219                                           /* just a sign */
2220                                           (data[2] != 0));
2221         case INSN_CONFIG_PWM_GET_H_BRIDGE:
2222                 /* values are not kept in this driver, nothing to return */
2223                 return -EINVAL;
2224         }
2225         return -EINVAL;
2226 }
2227
2228 /* end of PWM */
2229 /*****************************************************************/
2230
2231 static void tidy_up(struct usbduxsub *usbduxsub_tmp)
2232 {
2233         int i;
2234
2235         if (!usbduxsub_tmp)
2236                 return;
2237         dev_dbg(&usbduxsub_tmp->interface->dev, "comedi_: tiding up\n");
2238
2239         /* shows the usb subsystem that the driver is down */
2240         if (usbduxsub_tmp->interface)
2241                 usb_set_intfdata(usbduxsub_tmp->interface, NULL);
2242
2243         usbduxsub_tmp->probed = 0;
2244
2245         if (usbduxsub_tmp->urbIn) {
2246                 if (usbduxsub_tmp->ai_cmd_running) {
2247                         usbduxsub_tmp->ai_cmd_running = 0;
2248                         usbduxsub_unlink_InURBs(usbduxsub_tmp);
2249                 }
2250                 for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
2251                         kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer);
2252                         usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL;
2253                         usb_kill_urb(usbduxsub_tmp->urbIn[i]);
2254                         usb_free_urb(usbduxsub_tmp->urbIn[i]);
2255                         usbduxsub_tmp->urbIn[i] = NULL;
2256                 }
2257                 kfree(usbduxsub_tmp->urbIn);
2258                 usbduxsub_tmp->urbIn = NULL;
2259         }
2260         if (usbduxsub_tmp->urbOut) {
2261                 if (usbduxsub_tmp->ao_cmd_running) {
2262                         usbduxsub_tmp->ao_cmd_running = 0;
2263                         usbduxsub_unlink_OutURBs(usbduxsub_tmp);
2264                 }
2265                 for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
2266                         if (usbduxsub_tmp->urbOut[i]->transfer_buffer) {
2267                                 kfree(usbduxsub_tmp->
2268                                       urbOut[i]->transfer_buffer);
2269                                 usbduxsub_tmp->urbOut[i]->transfer_buffer =
2270                                     NULL;
2271                         }
2272                         if (usbduxsub_tmp->urbOut[i]) {
2273                                 usb_kill_urb(usbduxsub_tmp->urbOut[i]);
2274                                 usb_free_urb(usbduxsub_tmp->urbOut[i]);
2275                                 usbduxsub_tmp->urbOut[i] = NULL;
2276                         }
2277                 }
2278                 kfree(usbduxsub_tmp->urbOut);
2279                 usbduxsub_tmp->urbOut = NULL;
2280         }
2281         if (usbduxsub_tmp->urbPwm) {
2282                 if (usbduxsub_tmp->pwm_cmd_running) {
2283                         usbduxsub_tmp->pwm_cmd_running = 0;
2284                         usbduxsub_unlink_PwmURBs(usbduxsub_tmp);
2285                 }
2286                 kfree(usbduxsub_tmp->urbPwm->transfer_buffer);
2287                 usbduxsub_tmp->urbPwm->transfer_buffer = NULL;
2288                 usb_kill_urb(usbduxsub_tmp->urbPwm);
2289                 usb_free_urb(usbduxsub_tmp->urbPwm);
2290                 usbduxsub_tmp->urbPwm = NULL;
2291         }
2292         kfree(usbduxsub_tmp->inBuffer);
2293         usbduxsub_tmp->inBuffer = NULL;
2294         kfree(usbduxsub_tmp->insnBuffer);
2295         usbduxsub_tmp->insnBuffer = NULL;
2296         kfree(usbduxsub_tmp->outBuffer);
2297         usbduxsub_tmp->outBuffer = NULL;
2298         kfree(usbduxsub_tmp->dac_commands);
2299         usbduxsub_tmp->dac_commands = NULL;
2300         kfree(usbduxsub_tmp->dux_commands);
2301         usbduxsub_tmp->dux_commands = NULL;
2302         usbduxsub_tmp->ai_cmd_running = 0;
2303         usbduxsub_tmp->ao_cmd_running = 0;
2304         usbduxsub_tmp->pwm_cmd_running = 0;
2305 }
2306
2307 static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
2308                                                      void *context)
2309 {
2310         struct usbduxsub *usbduxsub_tmp = context;
2311         struct usb_device *usbdev = usbduxsub_tmp->usbdev;
2312         int ret;
2313
2314         if (fw == NULL) {
2315                 dev_err(&usbdev->dev,
2316                         "Firmware complete handler without firmware!\n");
2317                 return;
2318         }
2319
2320         /*
2321          * we need to upload the firmware here because fw will be
2322          * freed once we've left this function
2323          */
2324         ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size);
2325
2326         if (ret) {
2327                 dev_err(&usbdev->dev,
2328                         "Could not upload firmware (err=%d)\n", ret);
2329                 goto out;
2330         }
2331         comedi_usb_auto_config(usbdev, BOARDNAME);
2332 out:
2333         release_firmware(fw);
2334 }
2335
2336 /* allocate memory for the urbs and initialise them */
2337 static int usbduxsigma_probe(struct usb_interface *uinterf,
2338                            const struct usb_device_id *id)
2339 {
2340         struct usb_device *udev = interface_to_usbdev(uinterf);
2341         struct device *dev = &uinterf->dev;
2342         int i;
2343         int index;
2344         int ret;
2345
2346         dev_dbg(dev, "comedi_: usbdux_: "
2347                 "finding a free structure for the usb-device\n");
2348
2349         down(&start_stop_sem);
2350         /* look for a free place in the usbdux array */
2351         index = -1;
2352         for (i = 0; i < NUMUSBDUX; i++) {
2353                 if (!(usbduxsub[i].probed)) {
2354                         index = i;
2355                         break;
2356                 }
2357         }
2358
2359         /* no more space */
2360         if (index == -1) {
2361                 dev_err(dev, "Too many usbduxsigma-devices connected.\n");
2362                 up(&start_stop_sem);
2363                 return -EMFILE;
2364         }
2365         dev_dbg(dev, "comedi_: usbdux: "
2366                 "usbduxsub[%d] is ready to connect to comedi.\n", index);
2367
2368         sema_init(&(usbduxsub[index].sem), 1);
2369         /* save a pointer to the usb device */
2370         usbduxsub[index].usbdev = udev;
2371
2372         /* save the interface itself */
2373         usbduxsub[index].interface = uinterf;
2374         /* get the interface number from the interface */
2375         usbduxsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
2376         /* hand the private data over to the usb subsystem */
2377         /* will be needed for disconnect */
2378         usb_set_intfdata(uinterf, &(usbduxsub[index]));
2379
2380         dev_dbg(dev, "comedi_: usbdux: ifnum=%d\n", usbduxsub[index].ifnum);
2381
2382         /* test if it is high speed (USB 2.0) */
2383         usbduxsub[index].high_speed =
2384             (usbduxsub[index].usbdev->speed == USB_SPEED_HIGH);
2385
2386         /* create space for the commands of the DA converter */
2387         usbduxsub[index].dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
2388         if (!usbduxsub[index].dac_commands) {
2389                 dev_err(dev, "comedi_: usbduxsigma: "
2390                         "error alloc space for dac commands\n");
2391                 tidy_up(&(usbduxsub[index]));
2392                 up(&start_stop_sem);
2393                 return -ENOMEM;
2394         }
2395         /* create space for the commands going to the usb device */
2396         usbduxsub[index].dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
2397         if (!usbduxsub[index].dux_commands) {
2398                 dev_err(dev, "comedi_: usbduxsigma: "
2399                         "error alloc space for dux commands\n");
2400                 tidy_up(&(usbduxsub[index]));
2401                 up(&start_stop_sem);
2402                 return -ENOMEM;
2403         }
2404         /* create space for the in buffer and set it to zero */
2405         usbduxsub[index].inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
2406         if (!(usbduxsub[index].inBuffer)) {
2407                 dev_err(dev, "comedi_: usbduxsigma: "
2408                         "could not alloc space for inBuffer\n");
2409                 tidy_up(&(usbduxsub[index]));
2410                 up(&start_stop_sem);
2411                 return -ENOMEM;
2412         }
2413         /* create space of the instruction buffer */
2414         usbduxsub[index].insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
2415         if (!(usbduxsub[index].insnBuffer)) {
2416                 dev_err(dev, "comedi_: usbduxsigma: "
2417                         "could not alloc space for insnBuffer\n");
2418                 tidy_up(&(usbduxsub[index]));
2419                 up(&start_stop_sem);
2420                 return -ENOMEM;
2421         }
2422         /* create space for the outbuffer */
2423         usbduxsub[index].outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
2424         if (!(usbduxsub[index].outBuffer)) {
2425                 dev_err(dev, "comedi_: usbduxsigma: "
2426                         "could not alloc space for outBuffer\n");
2427                 tidy_up(&(usbduxsub[index]));
2428                 up(&start_stop_sem);
2429                 return -ENOMEM;
2430         }
2431         /* setting to alternate setting 3: enabling iso ep and bulk ep. */
2432         i = usb_set_interface(usbduxsub[index].usbdev,
2433                               usbduxsub[index].ifnum, 3);
2434         if (i < 0) {
2435                 dev_err(dev, "comedi_: usbduxsigma%d: "
2436                         "could not set alternate setting 3 in high speed.\n",
2437                         index);
2438                 tidy_up(&(usbduxsub[index]));
2439                 up(&start_stop_sem);
2440                 return -ENODEV;
2441         }
2442         if (usbduxsub[index].high_speed)
2443                 usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSHIGH;
2444         else
2445                 usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSFULL;
2446
2447         usbduxsub[index].urbIn =
2448             kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfInBuffers,
2449                     GFP_KERNEL);
2450         if (!(usbduxsub[index].urbIn)) {
2451                 dev_err(dev, "comedi_: usbduxsigma: "
2452                         "Could not alloc. urbIn array\n");
2453                 tidy_up(&(usbduxsub[index]));
2454                 up(&start_stop_sem);
2455                 return -ENOMEM;
2456         }
2457         for (i = 0; i < usbduxsub[index].numOfInBuffers; i++) {
2458                 /* one frame: 1ms */
2459                 usbduxsub[index].urbIn[i] = usb_alloc_urb(1, GFP_KERNEL);
2460                 if (usbduxsub[index].urbIn[i] == NULL) {
2461                         dev_err(dev, "comedi_: usbduxsigma%d: "
2462                                 "Could not alloc. urb(%d)\n", index, i);
2463                         tidy_up(&(usbduxsub[index]));
2464                         up(&start_stop_sem);
2465                         return -ENOMEM;
2466                 }
2467                 usbduxsub[index].urbIn[i]->dev = usbduxsub[index].usbdev;
2468                 /* will be filled later with a pointer to the comedi-device */
2469                 /* and ONLY then the urb should be submitted */
2470                 usbduxsub[index].urbIn[i]->context = NULL;
2471                 usbduxsub[index].urbIn[i]->pipe =
2472                     usb_rcvisocpipe(usbduxsub[index].usbdev, ISOINEP);
2473                 usbduxsub[index].urbIn[i]->transfer_flags = URB_ISO_ASAP;
2474                 usbduxsub[index].urbIn[i]->transfer_buffer =
2475                     kzalloc(SIZEINBUF, GFP_KERNEL);
2476                 if (!(usbduxsub[index].urbIn[i]->transfer_buffer)) {
2477                         dev_err(dev, "comedi_: usbduxsigma%d: "
2478                                 "could not alloc. transb.\n", index);
2479                         tidy_up(&(usbduxsub[index]));
2480                         up(&start_stop_sem);
2481                         return -ENOMEM;
2482                 }
2483                 usbduxsub[index].urbIn[i]->complete = usbduxsub_ai_IsocIrq;
2484                 usbduxsub[index].urbIn[i]->number_of_packets = 1;
2485                 usbduxsub[index].urbIn[i]->transfer_buffer_length = SIZEINBUF;
2486                 usbduxsub[index].urbIn[i]->iso_frame_desc[0].offset = 0;
2487                 usbduxsub[index].urbIn[i]->iso_frame_desc[0].length =
2488                         SIZEINBUF;
2489         }
2490
2491         /* out */
2492         if (usbduxsub[index].high_speed)
2493                 usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSHIGH;
2494         else
2495                 usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSFULL;
2496
2497         usbduxsub[index].urbOut =
2498             kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfOutBuffers,
2499                     GFP_KERNEL);
2500         if (!(usbduxsub[index].urbOut)) {
2501                 dev_err(dev, "comedi_: usbduxsigma: "
2502                         "Could not alloc. urbOut array\n");
2503                 tidy_up(&(usbduxsub[index]));
2504                 up(&start_stop_sem);
2505                 return -ENOMEM;
2506         }
2507         for (i = 0; i < usbduxsub[index].numOfOutBuffers; i++) {
2508                 /* one frame: 1ms */
2509                 usbduxsub[index].urbOut[i] = usb_alloc_urb(1, GFP_KERNEL);
2510                 if (usbduxsub[index].urbOut[i] == NULL) {
2511                         dev_err(dev, "comedi_: usbduxsigma%d: "
2512                                 "Could not alloc. urb(%d)\n", index, i);
2513                         tidy_up(&(usbduxsub[index]));
2514                         up(&start_stop_sem);
2515                         return -ENOMEM;
2516                 }
2517                 usbduxsub[index].urbOut[i]->dev = usbduxsub[index].usbdev;
2518                 /* will be filled later with a pointer to the comedi-device */
2519                 /* and ONLY then the urb should be submitted */
2520                 usbduxsub[index].urbOut[i]->context = NULL;
2521                 usbduxsub[index].urbOut[i]->pipe =
2522                     usb_sndisocpipe(usbduxsub[index].usbdev, ISOOUTEP);
2523                 usbduxsub[index].urbOut[i]->transfer_flags = URB_ISO_ASAP;
2524                 usbduxsub[index].urbOut[i]->transfer_buffer =
2525                     kzalloc(SIZEOUTBUF, GFP_KERNEL);
2526                 if (!(usbduxsub[index].urbOut[i]->transfer_buffer)) {
2527                         dev_err(dev, "comedi_: usbduxsigma%d: "
2528                                 "could not alloc. transb.\n", index);
2529                         tidy_up(&(usbduxsub[index]));
2530                         up(&start_stop_sem);
2531                         return -ENOMEM;
2532                 }
2533                 usbduxsub[index].urbOut[i]->complete = usbduxsub_ao_IsocIrq;
2534                 usbduxsub[index].urbOut[i]->number_of_packets = 1;
2535                 usbduxsub[index].urbOut[i]->transfer_buffer_length =
2536                         SIZEOUTBUF;
2537                 usbduxsub[index].urbOut[i]->iso_frame_desc[0].offset = 0;
2538                 usbduxsub[index].urbOut[i]->iso_frame_desc[0].length =
2539                     SIZEOUTBUF;
2540                 if (usbduxsub[index].high_speed) {
2541                         /* uframes */
2542                         usbduxsub[index].urbOut[i]->interval = 8;
2543                 } else {
2544                         /* frames */
2545                         usbduxsub[index].urbOut[i]->interval = 1;
2546                 }
2547         }
2548
2549         /* pwm */
2550         if (usbduxsub[index].high_speed) {
2551                 /* max bulk ep size in high speed */
2552                 usbduxsub[index].sizePwmBuf = 512;
2553                 usbduxsub[index].urbPwm = usb_alloc_urb(0, GFP_KERNEL);
2554                 if (usbduxsub[index].urbPwm == NULL) {
2555                         dev_err(dev, "comedi_: usbduxsigma%d: "
2556                                 "Could not alloc. pwm urb\n", index);
2557                         tidy_up(&(usbduxsub[index]));
2558                         up(&start_stop_sem);
2559                         return -ENOMEM;
2560                 }
2561                 usbduxsub[index].urbPwm->transfer_buffer =
2562                     kzalloc(usbduxsub[index].sizePwmBuf, GFP_KERNEL);
2563                 if (!(usbduxsub[index].urbPwm->transfer_buffer)) {
2564                         dev_err(dev, "comedi_: usbduxsigma%d: "
2565                                 "could not alloc. transb. for pwm\n", index);
2566                         tidy_up(&(usbduxsub[index]));
2567                         up(&start_stop_sem);
2568                         return -ENOMEM;
2569                 }
2570         } else {
2571                 usbduxsub[index].urbPwm = NULL;
2572                 usbduxsub[index].sizePwmBuf = 0;
2573         }
2574
2575         usbduxsub[index].ai_cmd_running = 0;
2576         usbduxsub[index].ao_cmd_running = 0;
2577         usbduxsub[index].pwm_cmd_running = 0;
2578
2579         /* we've reached the bottom of the function */
2580         usbduxsub[index].probed = 1;
2581         up(&start_stop_sem);
2582
2583         ret = request_firmware_nowait(THIS_MODULE,
2584                                       FW_ACTION_HOTPLUG,
2585                                       "usbduxsigma_firmware.bin",
2586                                       &udev->dev,
2587                                       GFP_KERNEL,
2588                                       usbduxsub + index,
2589                                       usbdux_firmware_request_complete_handler
2590                                       );
2591
2592         if (ret) {
2593                 dev_err(dev, "Could not load firmware (err=%d)\n", ret);
2594                 return ret;
2595         }
2596
2597         dev_info(dev, "comedi_: successfully initialised.\n");
2598         /* success */
2599         return 0;
2600 }
2601
2602 static void usbduxsigma_disconnect(struct usb_interface *intf)
2603 {
2604         struct usbduxsub *usbduxsub_tmp = usb_get_intfdata(intf);
2605         struct usb_device *udev = interface_to_usbdev(intf);
2606
2607         if (!usbduxsub_tmp) {
2608                 dev_err(&intf->dev,
2609                         "comedi_: disconnect called with null pointer.\n");
2610                 return;
2611         }
2612         if (usbduxsub_tmp->usbdev != udev) {
2613                 dev_err(&intf->dev, "comedi_: BUG! wrong ptr!\n");
2614                 return;
2615         }
2616         if (usbduxsub_tmp->ai_cmd_running)
2617                 /* we are still running a command */
2618                 usbdux_ai_stop(usbduxsub_tmp, 1);
2619         if (usbduxsub_tmp->ao_cmd_running)
2620                 /* we are still running a command */
2621                 usbdux_ao_stop(usbduxsub_tmp, 1);
2622         comedi_usb_auto_unconfig(udev);
2623         down(&start_stop_sem);
2624         down(&usbduxsub_tmp->sem);
2625         tidy_up(usbduxsub_tmp);
2626         up(&usbduxsub_tmp->sem);
2627         up(&start_stop_sem);
2628         dev_info(&intf->dev, "comedi_: disconnected from the usb\n");
2629 }
2630
2631 /* is called when comedi-config is called */
2632 static int usbduxsigma_attach(struct comedi_device *dev,
2633                               struct comedi_devconfig *it)
2634 {
2635         int ret;
2636         int index;
2637         int i;
2638         struct usbduxsub *udev;
2639
2640         int offset;
2641
2642         struct comedi_subdevice *s = NULL;
2643         dev->private = NULL;
2644
2645         down(&start_stop_sem);
2646         /* find a valid device which has been detected by the probe function of
2647          * the usb */
2648         index = -1;
2649         for (i = 0; i < NUMUSBDUX; i++) {
2650                 if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) {
2651                         index = i;
2652                         break;
2653                 }
2654         }
2655
2656         if (index < 0) {
2657                 printk(KERN_ERR "comedi%d: usbduxsigma: error: attach failed,"
2658                        "dev not connected to the usb bus.\n", dev->minor);
2659                 up(&start_stop_sem);
2660                 return -ENODEV;
2661         }
2662
2663         udev = &usbduxsub[index];
2664         down(&udev->sem);
2665         /* pointer back to the corresponding comedi device */
2666         udev->comedidev = dev;
2667
2668         /* trying to upload the firmware into the FX2 */
2669         if (comedi_aux_data(it->options, 0) &&
2670             it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
2671                 firmwareUpload(udev, comedi_aux_data(it->options, 0),
2672                                it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
2673         }
2674
2675         dev->board_name = BOARDNAME;
2676
2677         /* set number of subdevices */
2678         if (udev->high_speed) {
2679                 /* with pwm */
2680                 dev->n_subdevices = 4;
2681         } else {
2682                 /* without pwm */
2683                 dev->n_subdevices = 3;
2684         }
2685
2686         /* allocate space for the subdevices */
2687         ret = alloc_subdevices(dev, dev->n_subdevices);
2688         if (ret < 0) {
2689                 dev_err(&udev->interface->dev,
2690                         "comedi%d: no space for subdev\n", dev->minor);
2691                 up(&start_stop_sem);
2692                 return ret;
2693         }
2694
2695         /* private structure is also simply the usb-structure */
2696         dev->private = udev;
2697
2698         /* the first subdevice is the A/D converter */
2699         s = dev->subdevices + SUBDEV_AD;
2700         /* the URBs get the comedi subdevice */
2701         /* which is responsible for reading */
2702         /* this is the subdevice which reads data */
2703         dev->read_subdev = s;
2704         /* the subdevice receives as private structure the */
2705         /* usb-structure */
2706         s->private = NULL;
2707         /* analog input */
2708         s->type = COMEDI_SUBD_AI;
2709         /* readable and ref is to ground, 32 bit wide data! */
2710         s->subdev_flags = SDF_READABLE | SDF_GROUND |
2711                 SDF_CMD_READ | SDF_LSAMPL;
2712         /* 16 A/D channels */
2713         s->n_chan = NUMCHANNELS;
2714         /* length of the channellist */
2715         s->len_chanlist = NUMCHANNELS;
2716         /* callback functions */
2717         s->insn_read = usbdux_ai_insn_read;
2718         s->do_cmdtest = usbdux_ai_cmdtest;
2719         s->do_cmd = usbdux_ai_cmd;
2720         s->cancel = usbdux_ai_cancel;
2721         /* max value from the A/D converter (24bit) */
2722         s->maxdata = 0x00FFFFFF;
2723         /* range table to convert to physical units */
2724         s->range_table = (&range_usbdux_ai_range);
2725
2726         /* analog out */
2727         s = dev->subdevices + SUBDEV_DA;
2728         /* analog out */
2729         s->type = COMEDI_SUBD_AO;
2730         /* backward pointer */
2731         dev->write_subdev = s;
2732         /* the subdevice receives as private structure the */
2733         /* usb-structure */
2734         s->private = NULL;
2735         /* are writable */
2736         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
2737         /* 4 channels */
2738         s->n_chan = 4;
2739         /* length of the channellist */
2740         s->len_chanlist = 4;
2741         /* 8 bit resolution */
2742         s->maxdata = 0x00ff;
2743         /* unipolar range */
2744         s->range_table = (&range_usbdux_ao_range);
2745         /* callback */
2746         s->do_cmdtest = usbdux_ao_cmdtest;
2747         s->do_cmd = usbdux_ao_cmd;
2748         s->cancel = usbdux_ao_cancel;
2749         s->insn_read = usbdux_ao_insn_read;
2750         s->insn_write = usbdux_ao_insn_write;
2751
2752         /* digital I/O */
2753         s = dev->subdevices + SUBDEV_DIO;
2754         s->type = COMEDI_SUBD_DIO;
2755         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
2756         /* 8 external and 16 internal channels */
2757         s->n_chan = 24;
2758         s->maxdata = 1;
2759         s->range_table = (&range_digital);
2760         s->insn_bits = usbdux_dio_insn_bits;
2761         s->insn_config = usbdux_dio_insn_config;
2762         /* we don't use it */
2763         s->private = NULL;
2764
2765         if (udev->high_speed) {
2766                 /* timer / pwm */
2767                 s = dev->subdevices + SUBDEV_PWM;
2768                 s->type = COMEDI_SUBD_PWM;
2769                 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
2770                 s->n_chan = 8;
2771                 /* this defines the max duty cycle resolution */
2772                 s->maxdata = udev->sizePwmBuf;
2773                 s->insn_write = usbdux_pwm_write;
2774                 s->insn_read = usbdux_pwm_read;
2775                 s->insn_config = usbdux_pwm_config;
2776                 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
2777         }
2778         /* finally decide that it's attached */
2779         udev->attached = 1;
2780
2781         up(&udev->sem);
2782
2783         up(&start_stop_sem);
2784
2785         offset = usbdux_getstatusinfo(dev, 0);
2786         if (offset < 0)
2787                 dev_err(&udev->interface->dev,
2788                         "Communication to USBDUXSIGMA failed!"
2789                         "Check firmware and cabling.");
2790
2791         dev_info(&udev->interface->dev,
2792                  "comedi%d: attached, ADC_zero = %x", dev->minor, offset);
2793
2794         return 0;
2795 }
2796
2797 static int usbduxsigma_detach(struct comedi_device *dev)
2798 {
2799         struct usbduxsub *usbduxsub_tmp;
2800
2801         if (!dev) {
2802                 printk(KERN_ERR
2803                        "comedi? usbduxsigma detach: dev=NULL\n");
2804                 return -EFAULT;
2805         }
2806
2807         usbduxsub_tmp = dev->private;
2808         if (!usbduxsub_tmp) {
2809                 printk(KERN_ERR
2810                        "comedi?: usbduxsigma detach: private=NULL\n");
2811                 return -EFAULT;
2812         }
2813
2814         dev_dbg(&usbduxsub_tmp->interface->dev,
2815                 "comedi%d: detach usb device\n",
2816                 dev->minor);
2817
2818         down(&usbduxsub_tmp->sem);
2819         /* Don't allow detach to free the private structure */
2820         /* It's one entry of of usbduxsub[] */
2821         dev->private = NULL;
2822         usbduxsub_tmp->attached = 0;
2823         usbduxsub_tmp->comedidev = NULL;
2824         dev_info(&usbduxsub_tmp->interface->dev,
2825                 "comedi%d: successfully detached.\n", dev->minor);
2826         up(&usbduxsub_tmp->sem);
2827         return 0;
2828 }
2829
2830 /* main driver struct */
2831 static struct comedi_driver driver_usbduxsigma = {
2832         .driver_name = "usbduxsigma",
2833         .module = THIS_MODULE,
2834         .attach = usbduxsigma_attach,
2835         .detach = usbduxsigma_detach,
2836 };
2837
2838 /* Table with the USB-devices */
2839 static const struct usb_device_id usbduxsigma_table[] = {
2840         {USB_DEVICE(0x13d8, 0x0020)},
2841         {USB_DEVICE(0x13d8, 0x0021)},
2842         {USB_DEVICE(0x13d8, 0x0022)},
2843         {}                      /* Terminating entry */
2844 };
2845
2846 MODULE_DEVICE_TABLE(usb, usbduxsigma_table);
2847
2848 /* The usbduxsub-driver */
2849 static struct usb_driver usbduxsigma_driver = {
2850         .name = BOARDNAME,
2851         .probe = usbduxsigma_probe,
2852         .disconnect = usbduxsigma_disconnect,
2853         .id_table = usbduxsigma_table,
2854 };
2855
2856 /* Can't use the nice macro as I have also to initialise the USB */
2857 /* subsystem: */
2858 /* registering the usb-system _and_ the comedi-driver */
2859 static int __init init_usbduxsigma(void)
2860 {
2861         printk(KERN_INFO KBUILD_MODNAME ": "
2862                DRIVER_VERSION ":" DRIVER_DESC "\n");
2863         usb_register(&usbduxsigma_driver);
2864         comedi_driver_register(&driver_usbduxsigma);
2865         return 0;
2866 }
2867
2868 /* deregistering the comedi driver and the usb-subsystem */
2869 static void __exit exit_usbduxsigma(void)
2870 {
2871         comedi_driver_unregister(&driver_usbduxsigma);
2872         usb_deregister(&usbduxsigma_driver);
2873 }
2874
2875 module_init(init_usbduxsigma);
2876 module_exit(exit_usbduxsigma);
2877
2878 MODULE_AUTHOR(DRIVER_AUTHOR);
2879 MODULE_DESCRIPTION(DRIVER_DESC);
2880 MODULE_LICENSE("GPL");