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