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