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