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