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