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