staging: comedi: usbdux: tidy up the comedi_lrange tables
[linux-2.6-block.git] / drivers / staging / comedi / drivers / usbdux.c
1 /*
2    comedi/drivers/usbdux.c
3    Copyright (C) 2003-2007 Bernd Porr, Bernd.Porr@f2s.com
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14  */
15 /*
16 Driver: usbdux
17 Description: University of Stirling USB DAQ & INCITE Technology Limited
18 Devices: [ITL] USB-DUX (usbdux.o)
19 Author: Bernd Porr <BerndPorr@f2s.com>
20 Updated: 8 Dec 2008
21 Status: Stable
22 Configuration options:
23   You have to upload firmware with the -i option. The
24   firmware is usually installed under /usr/share/usb or
25   /usr/local/share/usb or /lib/firmware.
26
27 Connection scheme for the counter at the digital port:
28   0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1.
29   The sampling rate of the counter is approximately 500Hz.
30
31 Please note that under USB2.0 the length of the channel list determines
32 the max sampling rate. If you sample only one channel you get 8kHz
33 sampling rate. If you sample two channels you get 4kHz and so on.
34 */
35 /*
36  * I must give credit here to Chris Baugher who
37  * wrote the driver for AT-MIO-16d. I used some parts of this
38  * driver. I also must give credits to David Brownell
39  * who supported me with the USB development.
40  *
41  * Bernd Porr
42  *
43  *
44  * Revision history:
45  * 0.94: D/A output should work now with any channel list combinations
46  * 0.95: .owner commented out for kernel vers below 2.4.19
47  *       sanity checks in ai/ao_cmd
48  * 0.96: trying to get it working with 2.6, moved all memory alloc to comedi's
49  *       attach final USB IDs
50  *       moved memory allocation completely to the corresponding comedi
51  *       functions firmware upload is by fxload and no longer by comedi (due to
52  *       enumeration)
53  * 0.97: USB IDs received, adjusted table
54  * 0.98: SMP, locking, memory alloc: moved all usb memory alloc
55  *       to the usb subsystem and moved all comedi related memory
56  *       alloc to comedi.
57  *       | kernel | registration | usbdux-usb | usbdux-comedi | comedi |
58  * 0.99: USB 2.0: changed protocol to isochronous transfer
59  *                IRQ transfer is too buggy and too risky in 2.0
60  *                for the high speed ISO transfer is now a working version
61  *                available
62  * 0.99b: Increased the iso transfer buffer for high sp.to 10 buffers. Some VIA
63  *        chipsets miss out IRQs. Deeper buffering is needed.
64  * 1.00: full USB 2.0 support for the A/D converter. Now: max 8kHz sampling
65  *       rate.
66  *       Firmware vers 1.00 is needed for this.
67  *       Two 16 bit up/down/reset counter with a sampling rate of 1kHz
68  *       And loads of cleaning up, in particular streamlining the
69  *       bulk transfers.
70  * 1.1:  moved EP4 transfers to EP1 to make space for a PWM output on EP4
71  * 1.2:  added PWM support via EP4
72  * 2.0:  PWM seems to be stable and is not interfering with the other functions
73  * 2.1:  changed PWM API
74  * 2.2:  added firmware kernel request to fix an udev problem
75  * 2.3:  corrected a bug in bulk timeouts which were far too short
76  * 2.4:  fixed a bug which causes the driver to hang when it ran out of data.
77  *       Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it.
78  *
79  */
80
81 #include <linux/kernel.h>
82 #include <linux/module.h>
83 #include <linux/init.h>
84 #include <linux/slab.h>
85 #include <linux/input.h>
86 #include <linux/usb.h>
87 #include <linux/fcntl.h>
88 #include <linux/compiler.h>
89
90 #include "../comedidev.h"
91
92 #include "comedi_fc.h"
93
94 /* timeout for the USB-transfer in ms*/
95 #define BULK_TIMEOUT 1000
96
97 /* constants for "firmware" upload and download */
98 #define FIRMWARE "usbdux_firmware.bin"
99 #define USBDUXSUB_FIRMWARE 0xA0
100 #define VENDOR_DIR_IN  0xC0
101 #define VENDOR_DIR_OUT 0x40
102
103 /* internal addresses of the 8051 processor */
104 #define USBDUXSUB_CPUCS 0xE600
105
106 /*
107  * the minor device number, major is 180 only for debugging purposes and to
108  * upload special firmware (programming the eeprom etc) which is not compatible
109  * with the comedi framwork
110  */
111 #define USBDUXSUB_MINOR 32
112
113 /* max lenghth of the transfer-buffer for software upload */
114 #define TB_LEN 0x2000
115
116 /* Input endpoint number: ISO/IRQ */
117 #define ISOINEP           6
118
119 /* Output endpoint number: ISO/IRQ */
120 #define ISOOUTEP          2
121
122 /* This EP sends DUX commands to USBDUX */
123 #define COMMAND_OUT_EP     1
124
125 /* This EP receives the DUX commands from USBDUX */
126 #define COMMAND_IN_EP        8
127
128 /* Output endpoint for PWM */
129 #define PWM_EP         4
130
131 /* 300Hz max frequ under PWM */
132 #define MIN_PWM_PERIOD  ((long)(1E9/300))
133
134 /* Default PWM frequency */
135 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
136
137 /* Number of channels */
138 #define NUMCHANNELS       8
139
140 /* Size of one A/D value */
141 #define SIZEADIN          ((sizeof(int16_t)))
142
143 /*
144  * Size of the input-buffer IN BYTES
145  * Always multiple of 8 for 8 microframes which is needed in the highspeed mode
146  */
147 #define SIZEINBUF         ((8*SIZEADIN))
148
149 /* 16 bytes. */
150 #define SIZEINSNBUF       16
151
152 /* Number of DA channels */
153 #define NUMOUTCHANNELS    8
154
155 /* size of one value for the D/A converter: channel and value */
156 #define SIZEDAOUT          ((sizeof(int8_t)+sizeof(int16_t)))
157
158 /*
159  * Size of the output-buffer in bytes
160  * Actually only the first 4 triplets are used but for the
161  * high speed mode we need to pad it to 8 (microframes).
162  */
163 #define SIZEOUTBUF         ((8*SIZEDAOUT))
164
165 /*
166  * Size of the buffer for the dux commands: just now max size is determined
167  * by the analogue out + command byte + panic bytes...
168  */
169 #define SIZEOFDUXBUFFER    ((8*SIZEDAOUT+2))
170
171 /* Number of in-URBs which receive the data: min=2 */
172 #define NUMOFINBUFFERSFULL     5
173
174 /* Number of out-URBs which send the data: min=2 */
175 #define NUMOFOUTBUFFERSFULL    5
176
177 /* Number of in-URBs which receive the data: min=5 */
178 /* must have more buffers due to buggy USB ctr */
179 #define NUMOFINBUFFERSHIGH     10
180
181 /* Number of out-URBs which send the data: min=5 */
182 /* must have more buffers due to buggy USB ctr */
183 #define NUMOFOUTBUFFERSHIGH    10
184
185 /* number of retries to get the right dux command */
186 #define RETRIES 10
187
188 static const struct comedi_lrange range_usbdux_ai_range = {
189         4, {
190                 BIP_RANGE(4.096),
191                 BIP_RANGE(4.096 / 2),
192                 UNI_RANGE(4.096),
193                 UNI_RANGE(4.096 / 2)
194         }
195 };
196
197 static const struct comedi_lrange range_usbdux_ao_range = {
198         2, {
199                 BIP_RANGE(4.096),
200                 UNI_RANGE(4.096)
201         }
202 };
203
204 struct usbdux_private {
205         /* pointer to the usb-device */
206         struct usb_device *usbdev;
207         /* actual number of in-buffers */
208         int num_in_buffers;
209         /* actual number of out-buffers */
210         int num_out_buffers;
211         /* ISO-transfer handling: buffers */
212         struct urb **urb_in;
213         struct urb **urb_out;
214         /* pwm-transfer handling */
215         struct urb *urb_pwm;
216         /* PWM period */
217         unsigned int pwm_period;
218         /* PWM internal delay for the GPIF in the FX2 */
219         int8_t pwn_delay;
220         /* size of the PWM buffer which holds the bit pattern */
221         int size_pwm_buf;
222         /* input buffer for the ISO-transfer */
223         int16_t *in_buffer;
224         /* input buffer for single insn */
225         int16_t *insn_buffer;
226         /* output buffer for single DA outputs */
227         int16_t *out_buffer;
228         /* interface number */
229         int ifnum;
230         /* interface structure in 2.6 */
231         struct usb_interface *interface;
232         /* comedi device for the interrupt context */
233         struct comedi_device *comedidev;
234         /* is it USB_SPEED_HIGH or not? */
235         short int high_speed;
236         /* asynchronous command is running */
237         short int ai_cmd_running;
238         short int ao_cmd_running;
239         /* pwm is running */
240         short int pwm_cmd_running;
241         /* continous acquisition */
242         short int ai_continous;
243         short int ao_continous;
244         /* number of samples to acquire */
245         int ai_sample_count;
246         int ao_sample_count;
247         /* time between samples in units of the timer */
248         unsigned int ai_timer;
249         unsigned int ao_timer;
250         /* counter between aquisitions */
251         unsigned int ai_counter;
252         unsigned int ao_counter;
253         /* interval in frames/uframes */
254         unsigned int ai_interval;
255         /* D/A commands */
256         int8_t *dac_commands;
257         /* commands */
258         int8_t *dux_commands;
259         struct semaphore sem;
260 };
261
262 /*
263  * Stops the data acquision
264  * It should be safe to call this function from any context
265  */
266 static int usbduxsub_unlink_inurbs(struct usbdux_private *usbduxsub_tmp)
267 {
268         int i = 0;
269         int err = 0;
270
271         if (usbduxsub_tmp && usbduxsub_tmp->urb_in) {
272                 for (i = 0; i < usbduxsub_tmp->num_in_buffers; i++) {
273                         if (usbduxsub_tmp->urb_in[i]) {
274                                 /* We wait here until all transfers have been
275                                  * cancelled. */
276                                 usb_kill_urb(usbduxsub_tmp->urb_in[i]);
277                         }
278                         dev_dbg(&usbduxsub_tmp->interface->dev,
279                                 "comedi: usbdux: unlinked InURB %d, err=%d\n",
280                                 i, err);
281                 }
282         }
283         return err;
284 }
285
286 /*
287  * This will stop a running acquisition operation
288  * Is called from within this driver from both the
289  * interrupt context and from comedi
290  */
291 static int usbdux_ai_stop(struct usbdux_private *this_usbduxsub, int do_unlink)
292 {
293         int ret = 0;
294
295         if (!this_usbduxsub) {
296                 pr_err("comedi?: usbdux_ai_stop: this_usbduxsub=NULL!\n");
297                 return -EFAULT;
298         }
299         dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_stop\n");
300
301         if (do_unlink) {
302                 /* stop aquistion */
303                 ret = usbduxsub_unlink_inurbs(this_usbduxsub);
304         }
305
306         this_usbduxsub->ai_cmd_running = 0;
307
308         return ret;
309 }
310
311 /*
312  * This will cancel a running acquisition operation.
313  * This is called by comedi but never from inside the driver.
314  */
315 static int usbdux_ai_cancel(struct comedi_device *dev,
316                             struct comedi_subdevice *s)
317 {
318         struct usbdux_private *this_usbduxsub;
319         int res = 0;
320
321         /* force unlink of all urbs */
322         this_usbduxsub = dev->private;
323         if (!this_usbduxsub)
324                 return -EFAULT;
325
326         dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_cancel\n");
327
328         /* prevent other CPUs from submitting new commands just now */
329         down(&this_usbduxsub->sem);
330         /* unlink only if the urb really has been submitted */
331         res = usbdux_ai_stop(this_usbduxsub, this_usbduxsub->ai_cmd_running);
332         up(&this_usbduxsub->sem);
333         return res;
334 }
335
336 /* analogue IN - interrupt service routine */
337 static void usbduxsub_ai_isoc_irq(struct urb *urb)
338 {
339         struct comedi_device *dev = urb->context;
340         struct comedi_subdevice *s = dev->read_subdev;
341         struct usbdux_private *devpriv = dev->private;
342         int i, err, n;
343
344         /* first we test if something unusual has just happened */
345         switch (urb->status) {
346         case 0:
347                 /* copy the result in the transfer buffer */
348                 memcpy(devpriv->in_buffer, urb->transfer_buffer, SIZEINBUF);
349                 break;
350         case -EILSEQ:
351                 /* error in the ISOchronous data */
352                 /* we don't copy the data into the transfer buffer */
353                 /* and recycle the last data byte */
354                 dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
355                 break;
356
357         case -ECONNRESET:
358         case -ENOENT:
359         case -ESHUTDOWN:
360         case -ECONNABORTED:
361                 /* happens after an unlink command */
362                 if (devpriv->ai_cmd_running) {
363                         s->async->events |= COMEDI_CB_EOA;
364                         s->async->events |= COMEDI_CB_ERROR;
365                         comedi_event(dev, s);
366                         /* stop the transfer w/o unlink */
367                         usbdux_ai_stop(devpriv, 0);
368                 }
369                 return;
370
371         default:
372                 /* a real error on the bus */
373                 /* pass error to comedi if we are really running a command */
374                 if (devpriv->ai_cmd_running) {
375                         dev_err(dev->class_dev,
376                                 "Non-zero urb status received in ai intr context: %d\n",
377                                 urb->status);
378                         s->async->events |= COMEDI_CB_EOA;
379                         s->async->events |= COMEDI_CB_ERROR;
380                         comedi_event(dev, s);
381                         /* don't do an unlink here */
382                         usbdux_ai_stop(devpriv, 0);
383                 }
384                 return;
385         }
386
387         /*
388          * at this point we are reasonably sure that nothing dodgy has happened
389          * are we running a command?
390          */
391         if (unlikely(!devpriv->ai_cmd_running)) {
392                 /*
393                  * not running a command, do not continue execution if no
394                  * asynchronous command is running in particular not resubmit
395                  */
396                 return;
397         }
398
399         urb->dev = devpriv->usbdev;
400
401         /* resubmit the urb */
402         err = usb_submit_urb(urb, GFP_ATOMIC);
403         if (unlikely(err < 0)) {
404                 dev_err(dev->class_dev,
405                         "urb resubmit failed in int-context! err=%d\n", err);
406                 if (err == -EL2NSYNC)
407                         dev_err(dev->class_dev,
408                                 "buggy USB host controller or bug in IRQ handler!\n");
409                 s->async->events |= COMEDI_CB_EOA;
410                 s->async->events |= COMEDI_CB_ERROR;
411                 comedi_event(dev, s);
412                 /* don't do an unlink here */
413                 usbdux_ai_stop(devpriv, 0);
414                 return;
415         }
416
417         devpriv->ai_counter--;
418         if (likely(devpriv->ai_counter > 0))
419                 return;
420
421         /* timer zero, transfer measurements to comedi */
422         devpriv->ai_counter = devpriv->ai_timer;
423
424         /* test, if we transmit only a fixed number of samples */
425         if (!devpriv->ai_continous) {
426                 /* not continuous, fixed number of samples */
427                 devpriv->ai_sample_count--;
428                 /* all samples received? */
429                 if (devpriv->ai_sample_count < 0) {
430                         /* prevent a resubmit next time */
431                         usbdux_ai_stop(devpriv, 0);
432                         /* say comedi that the acquistion is over */
433                         s->async->events |= COMEDI_CB_EOA;
434                         comedi_event(dev, s);
435                         return;
436                 }
437         }
438         /* get the data from the USB bus and hand it over to comedi */
439         n = s->async->cmd.chanlist_len;
440         for (i = 0; i < n; i++) {
441                 /* transfer data */
442                 if (CR_RANGE(s->async->cmd.chanlist[i]) <= 1) {
443                         err = comedi_buf_put(s->async,
444                              le16_to_cpu(devpriv->in_buffer[i]) ^ 0x800);
445                 } else {
446                         err = comedi_buf_put(s->async,
447                              le16_to_cpu(devpriv->in_buffer[i]));
448                 }
449                 if (unlikely(err == 0)) {
450                         /* buffer overflow */
451                         usbdux_ai_stop(devpriv, 0);
452                         return;
453                 }
454         }
455         /* tell comedi that data is there */
456         s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
457         comedi_event(dev, s);
458 }
459
460 static int usbduxsub_unlink_outurbs(struct usbdux_private *usbduxsub_tmp)
461 {
462         int i = 0;
463         int err = 0;
464
465         if (usbduxsub_tmp && usbduxsub_tmp->urb_out) {
466                 for (i = 0; i < usbduxsub_tmp->num_out_buffers; i++) {
467                         if (usbduxsub_tmp->urb_out[i])
468                                 usb_kill_urb(usbduxsub_tmp->urb_out[i]);
469
470                         dev_dbg(&usbduxsub_tmp->interface->dev,
471                                 "comedi: usbdux: unlinked OutURB %d: res=%d\n",
472                                 i, err);
473                 }
474         }
475         return err;
476 }
477
478 /* This will cancel a running acquisition operation
479  * in any context.
480  */
481 static int usbdux_ao_stop(struct usbdux_private *this_usbduxsub, int do_unlink)
482 {
483         int ret = 0;
484
485         if (!this_usbduxsub)
486                 return -EFAULT;
487         dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ao_cancel\n");
488
489         if (do_unlink)
490                 ret = usbduxsub_unlink_outurbs(this_usbduxsub);
491
492         this_usbduxsub->ao_cmd_running = 0;
493
494         return ret;
495 }
496
497 /* force unlink, is called by comedi */
498 static int usbdux_ao_cancel(struct comedi_device *dev,
499                             struct comedi_subdevice *s)
500 {
501         struct usbdux_private *this_usbduxsub = dev->private;
502         int res = 0;
503
504         if (!this_usbduxsub)
505                 return -EFAULT;
506
507         /* prevent other CPUs from submitting a command just now */
508         down(&this_usbduxsub->sem);
509         /* unlink only if it is really running */
510         res = usbdux_ao_stop(this_usbduxsub, this_usbduxsub->ao_cmd_running);
511         up(&this_usbduxsub->sem);
512         return res;
513 }
514
515 static void usbduxsub_ao_isoc_irq(struct urb *urb)
516 {
517         struct comedi_device *dev = urb->context;
518         struct comedi_subdevice *s = dev->write_subdev;
519         struct usbdux_private *devpriv = dev->private;
520         int i, ret;
521         int8_t *datap;
522
523         switch (urb->status) {
524         case 0:
525                 /* success */
526                 break;
527
528         case -ECONNRESET:
529         case -ENOENT:
530         case -ESHUTDOWN:
531         case -ECONNABORTED:
532                 /* after an unlink command, unplug, ... etc */
533                 /* no unlink needed here. Already shutting down. */
534                 if (devpriv->ao_cmd_running) {
535                         s->async->events |= COMEDI_CB_EOA;
536                         comedi_event(dev, s);
537                         usbdux_ao_stop(devpriv, 0);
538                 }
539                 return;
540
541         default:
542                 /* a real error */
543                 if (devpriv->ao_cmd_running) {
544                         dev_err(dev->class_dev,
545                                 "Non-zero urb status received in ao intr context: %d\n",
546                                 urb->status);
547                         s->async->events |= COMEDI_CB_ERROR;
548                         s->async->events |= COMEDI_CB_EOA;
549                         comedi_event(dev, s);
550                         /* we do an unlink if we are in the high speed mode */
551                         usbdux_ao_stop(devpriv, 0);
552                 }
553                 return;
554         }
555
556         /* are we actually running? */
557         if (!devpriv->ao_cmd_running)
558                 return;
559
560         /* normal operation: executing a command in this subdevice */
561         devpriv->ao_counter--;
562         if ((int)devpriv->ao_counter <= 0) {
563                 /* timer zero */
564                 devpriv->ao_counter = devpriv->ao_timer;
565
566                 /* handle non continous acquisition */
567                 if (!devpriv->ao_continous) {
568                         /* fixed number of samples */
569                         devpriv->ao_sample_count--;
570                         if (devpriv->ao_sample_count < 0) {
571                                 /* all samples transmitted */
572                                 usbdux_ao_stop(devpriv, 0);
573                                 s->async->events |= COMEDI_CB_EOA;
574                                 comedi_event(dev, s);
575                                 /* no resubmit of the urb */
576                                 return;
577                         }
578                 }
579                 /* transmit data to the USB bus */
580                 ((uint8_t *) (urb->transfer_buffer))[0] =
581                     s->async->cmd.chanlist_len;
582                 for (i = 0; i < s->async->cmd.chanlist_len; i++) {
583                         short temp;
584                         if (i >= NUMOUTCHANNELS)
585                                 break;
586
587                         /* pointer to the DA */
588                         datap =
589                             (&(((int8_t *) urb->transfer_buffer)[i * 3 + 1]));
590                         /* get the data from comedi */
591                         ret = comedi_buf_get(s->async, &temp);
592                         datap[0] = temp;
593                         datap[1] = temp >> 8;
594                         datap[2] = devpriv->dac_commands[i];
595                         if (ret < 0) {
596                                 dev_err(&urb->dev->dev,
597                                         "comedi: buffer underflow\n");
598                                 s->async->events |= COMEDI_CB_EOA;
599                                 s->async->events |= COMEDI_CB_OVERFLOW;
600                         }
601                         /* transmit data to comedi */
602                         s->async->events |= COMEDI_CB_BLOCK;
603                         comedi_event(dev, s);
604                 }
605         }
606         urb->transfer_buffer_length = SIZEOUTBUF;
607         urb->dev = devpriv->usbdev;
608         urb->status = 0;
609         if (devpriv->ao_cmd_running) {
610                 if (devpriv->high_speed)
611                         urb->interval = 8;      /* uframes */
612                 else
613                         urb->interval = 1;      /* frames */
614                 urb->number_of_packets = 1;
615                 urb->iso_frame_desc[0].offset = 0;
616                 urb->iso_frame_desc[0].length = SIZEOUTBUF;
617                 urb->iso_frame_desc[0].status = 0;
618                 ret = usb_submit_urb(urb, GFP_ATOMIC);
619                 if (ret < 0) {
620                         dev_err(dev->class_dev,
621                                 "ao urb resubm failed in int-cont. ret=%d",
622                                 ret);
623                         if (ret == EL2NSYNC)
624                                 dev_err(dev->class_dev,
625                                         "buggy USB host controller or bug in IRQ handling!\n");
626
627                         s->async->events |= COMEDI_CB_EOA;
628                         s->async->events |= COMEDI_CB_ERROR;
629                         comedi_event(dev, s);
630                         /* don't do an unlink here */
631                         usbdux_ao_stop(devpriv, 0);
632                 }
633         }
634 }
635
636 #define FIRMWARE_MAX_LEN 0x2000
637
638 static int usbdux_firmware_upload(struct comedi_device *dev,
639                                   const u8 *data, size_t size,
640                                   unsigned long context)
641 {
642         struct usbdux_private *usbduxsub = dev->private;
643         struct usb_device *usb = usbduxsub->usbdev;
644         uint8_t *buf;
645         uint8_t *tmp;
646         int ret;
647
648         if (!data)
649                 return 0;
650
651         if (size > FIRMWARE_MAX_LEN) {
652                 dev_err(&usbduxsub->interface->dev,
653                         "usbdux firmware binary it too large for FX2.\n");
654                 return -ENOMEM;
655         }
656
657         /* we generate a local buffer for the firmware */
658         buf = kmemdup(data, size, GFP_KERNEL);
659         if (!buf)
660                 return -ENOMEM;
661
662         /* we need a malloc'ed buffer for usb_control_msg() */
663         tmp = kmalloc(1, GFP_KERNEL);
664         if (!tmp) {
665                 kfree(buf);
666                 return -ENOMEM;
667         }
668
669         /* stop the current firmware on the device */
670         *tmp = 1;       /* 7f92 to one */
671         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
672                               USBDUXSUB_FIRMWARE,
673                               VENDOR_DIR_OUT,
674                               USBDUXSUB_CPUCS, 0x0000,
675                               tmp, 1,
676                               BULK_TIMEOUT);
677         if (ret < 0) {
678                 dev_err(&usbduxsub->interface->dev,
679                         "comedi_: can not stop firmware\n");
680                 goto done;
681         }
682
683         /* upload the new firmware to the device */
684         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
685                               USBDUXSUB_FIRMWARE,
686                               VENDOR_DIR_OUT,
687                               0, 0x0000,
688                               buf, size,
689                               BULK_TIMEOUT);
690         if (ret < 0) {
691                 dev_err(&usbduxsub->interface->dev,
692                         "comedi_: firmware upload failed\n");
693                 goto done;
694         }
695
696         /* start the new firmware on the device */
697         *tmp = 0;       /* 7f92 to zero */
698         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
699                               USBDUXSUB_FIRMWARE,
700                               VENDOR_DIR_OUT,
701                               USBDUXSUB_CPUCS, 0x0000,
702                               tmp, 1,
703                               BULK_TIMEOUT);
704         if (ret < 0)
705                 dev_err(&usbduxsub->interface->dev,
706                         "comedi_: can not start firmware\n");
707
708 done:
709         kfree(tmp);
710         kfree(buf);
711         return ret;
712 }
713
714 static int usbduxsub_submit_inurbs(struct usbdux_private *usbduxsub)
715 {
716         int i, err_flag;
717
718         if (!usbduxsub)
719                 return -EFAULT;
720
721         /* Submit all URBs and start the transfer on the bus */
722         for (i = 0; i < usbduxsub->num_in_buffers; i++) {
723                 /* in case of a resubmission after an unlink... */
724                 usbduxsub->urb_in[i]->interval = usbduxsub->ai_interval;
725                 usbduxsub->urb_in[i]->context = usbduxsub->comedidev;
726                 usbduxsub->urb_in[i]->dev = usbduxsub->usbdev;
727                 usbduxsub->urb_in[i]->status = 0;
728                 usbduxsub->urb_in[i]->transfer_flags = URB_ISO_ASAP;
729                 dev_dbg(&usbduxsub->interface->dev,
730                         "comedi%d: submitting in-urb[%d]: %p,%p intv=%d\n",
731                         usbduxsub->comedidev->minor, i,
732                         (usbduxsub->urb_in[i]->context),
733                         (usbduxsub->urb_in[i]->dev),
734                         (usbduxsub->urb_in[i]->interval));
735                 err_flag = usb_submit_urb(usbduxsub->urb_in[i], GFP_ATOMIC);
736                 if (err_flag) {
737                         dev_err(&usbduxsub->interface->dev,
738                                 "comedi_: ai: usb_submit_urb(%d) error %d\n",
739                                 i, err_flag);
740                         return err_flag;
741                 }
742         }
743         return 0;
744 }
745
746 static int usbduxsub_submit_outurbs(struct usbdux_private *usbduxsub)
747 {
748         int i, err_flag;
749
750         if (!usbduxsub)
751                 return -EFAULT;
752
753         for (i = 0; i < usbduxsub->num_out_buffers; i++) {
754                 dev_dbg(&usbduxsub->interface->dev,
755                         "comedi_: submitting out-urb[%d]\n", i);
756                 /* in case of a resubmission after an unlink... */
757                 usbduxsub->urb_out[i]->context = usbduxsub->comedidev;
758                 usbduxsub->urb_out[i]->dev = usbduxsub->usbdev;
759                 usbduxsub->urb_out[i]->status = 0;
760                 usbduxsub->urb_out[i]->transfer_flags = URB_ISO_ASAP;
761                 err_flag = usb_submit_urb(usbduxsub->urb_out[i], GFP_ATOMIC);
762                 if (err_flag) {
763                         dev_err(&usbduxsub->interface->dev,
764                                 "comedi_: ao: usb_submit_urb(%d) error %d\n",
765                                 i, err_flag);
766                         return err_flag;
767                 }
768         }
769         return 0;
770 }
771
772 static int usbdux_ai_cmdtest(struct comedi_device *dev,
773                              struct comedi_subdevice *s, struct comedi_cmd *cmd)
774 {
775         struct usbdux_private *this_usbduxsub = dev->private;
776         int err = 0, i;
777         unsigned int tmp_timer;
778
779         /* Step 1 : check if triggers are trivially valid */
780
781         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
782         err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
783         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
784         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
785         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
786
787         if (err)
788                 return 1;
789
790         /* Step 2a : make sure trigger sources are unique */
791
792         err |= cfc_check_trigger_is_unique(cmd->start_src);
793         err |= cfc_check_trigger_is_unique(cmd->stop_src);
794
795         /* Step 2b : and mutually compatible */
796
797         if (err)
798                 return 2;
799
800         /* Step 3: check if arguments are trivially valid */
801
802         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
803
804         if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
805                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
806
807         if (cmd->scan_begin_src == TRIG_TIMER) {
808                 if (this_usbduxsub->high_speed) {
809                         /*
810                          * In high speed mode microframes are possible.
811                          * However, during one microframe we can roughly
812                          * sample one channel. Thus, the more channels
813                          * are in the channel list the more time we need.
814                          */
815                         i = 1;
816                         /* find a power of 2 for the number of channels */
817                         while (i < (cmd->chanlist_len))
818                                 i = i * 2;
819
820                         err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
821                                                          1000000 / 8 * i);
822                         /* now calc the real sampling rate with all the
823                          * rounding errors */
824                         tmp_timer =
825                             ((unsigned int)(cmd->scan_begin_arg / 125000)) *
826                             125000;
827                 } else {
828                         /* full speed */
829                         /* 1kHz scans every USB frame */
830                         err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
831                                                          1000000);
832                         /*
833                          * calc the real sampling rate with the rounding errors
834                          */
835                         tmp_timer = ((unsigned int)(cmd->scan_begin_arg /
836                                                    1000000)) * 1000000;
837                 }
838                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
839                                                 tmp_timer);
840         }
841
842         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
843
844         if (cmd->stop_src == TRIG_COUNT) {
845                 /* any count is allowed */
846         } else {
847                 /* TRIG_NONE */
848                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
849         }
850
851         if (err)
852                 return 3;
853
854         return 0;
855 }
856
857 /*
858  * creates the ADC command for the MAX1271
859  * range is the range value from comedi
860  */
861 static int8_t create_adc_command(unsigned int chan, int range)
862 {
863         int8_t p = (range <= 1);
864         int8_t r = ((range % 2) == 0);
865         return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
866 }
867
868 /* bulk transfers to usbdux */
869
870 #define SENDADCOMMANDS            0
871 #define SENDDACOMMANDS            1
872 #define SENDDIOCONFIGCOMMAND      2
873 #define SENDDIOBITSCOMMAND        3
874 #define SENDSINGLEAD              4
875 #define READCOUNTERCOMMAND        5
876 #define WRITECOUNTERCOMMAND       6
877 #define SENDPWMON                 7
878 #define SENDPWMOFF                8
879
880 static int send_dux_commands(struct usbdux_private *this_usbduxsub, int cmd_type)
881 {
882         int result, nsent;
883
884         this_usbduxsub->dux_commands[0] = cmd_type;
885         result = usb_bulk_msg(this_usbduxsub->usbdev,
886                               usb_sndbulkpipe(this_usbduxsub->usbdev,
887                                               COMMAND_OUT_EP),
888                               this_usbduxsub->dux_commands, SIZEOFDUXBUFFER,
889                               &nsent, BULK_TIMEOUT);
890         if (result < 0)
891                 dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
892                         "could not transmit dux_command to the usb-device, "
893                         "err=%d\n", this_usbduxsub->comedidev->minor, result);
894
895         return result;
896 }
897
898 static int receive_dux_commands(struct usbdux_private *this_usbduxsub, int command)
899 {
900         int result = (-EFAULT);
901         int nrec;
902         int i;
903
904         for (i = 0; i < RETRIES; i++) {
905                 result = usb_bulk_msg(this_usbduxsub->usbdev,
906                                       usb_rcvbulkpipe(this_usbduxsub->usbdev,
907                                                       COMMAND_IN_EP),
908                                       this_usbduxsub->insn_buffer, SIZEINSNBUF,
909                                       &nrec, BULK_TIMEOUT);
910                 if (result < 0) {
911                         dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
912                                 "insn: USB error %d while receiving DUX command"
913                                 "\n", this_usbduxsub->comedidev->minor, result);
914                         return result;
915                 }
916                 if (le16_to_cpu(this_usbduxsub->insn_buffer[0]) == command)
917                         return result;
918         }
919         /* this is only reached if the data has been requested a couple of
920          * times */
921         dev_err(&this_usbduxsub->interface->dev, "comedi%d: insn: "
922                 "wrong data returned from firmware: want cmd %d, got cmd %d.\n",
923                 this_usbduxsub->comedidev->minor, command,
924                 le16_to_cpu(this_usbduxsub->insn_buffer[0]));
925         return -EFAULT;
926 }
927
928 static int usbdux_ai_inttrig(struct comedi_device *dev,
929                              struct comedi_subdevice *s, unsigned int trignum)
930 {
931         int ret;
932         struct usbdux_private *this_usbduxsub = dev->private;
933         if (!this_usbduxsub)
934                 return -EFAULT;
935
936         down(&this_usbduxsub->sem);
937         dev_dbg(&this_usbduxsub->interface->dev,
938                 "comedi%d: usbdux_ai_inttrig\n", dev->minor);
939
940         if (trignum != 0) {
941                 dev_err(&this_usbduxsub->interface->dev,
942                         "comedi%d: usbdux_ai_inttrig: invalid trignum\n",
943                         dev->minor);
944                 up(&this_usbduxsub->sem);
945                 return -EINVAL;
946         }
947         if (!(this_usbduxsub->ai_cmd_running)) {
948                 this_usbduxsub->ai_cmd_running = 1;
949                 ret = usbduxsub_submit_inurbs(this_usbduxsub);
950                 if (ret < 0) {
951                         dev_err(&this_usbduxsub->interface->dev,
952                                 "comedi%d: usbdux_ai_inttrig: "
953                                 "urbSubmit: err=%d\n", dev->minor, ret);
954                         this_usbduxsub->ai_cmd_running = 0;
955                         up(&this_usbduxsub->sem);
956                         return ret;
957                 }
958                 s->async->inttrig = NULL;
959         } else {
960                 dev_err(&this_usbduxsub->interface->dev,
961                         "comedi%d: ai_inttrig but acqu is already running\n",
962                         dev->minor);
963         }
964         up(&this_usbduxsub->sem);
965         return 1;
966 }
967
968 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
969 {
970         struct comedi_cmd *cmd = &s->async->cmd;
971         unsigned int chan, range;
972         int i, ret;
973         struct usbdux_private *this_usbduxsub = dev->private;
974         int result;
975
976         if (!this_usbduxsub)
977                 return -EFAULT;
978
979         dev_dbg(&this_usbduxsub->interface->dev,
980                 "comedi%d: usbdux_ai_cmd\n", dev->minor);
981
982         /* block other CPUs from starting an ai_cmd */
983         down(&this_usbduxsub->sem);
984         if (this_usbduxsub->ai_cmd_running) {
985                 dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
986                         "ai_cmd not possible. Another ai_cmd is running.\n",
987                         dev->minor);
988                 up(&this_usbduxsub->sem);
989                 return -EBUSY;
990         }
991         /* set current channel of the running acquisition to zero */
992         s->async->cur_chan = 0;
993
994         this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
995         for (i = 0; i < cmd->chanlist_len; ++i) {
996                 chan = CR_CHAN(cmd->chanlist[i]);
997                 range = CR_RANGE(cmd->chanlist[i]);
998                 if (i >= NUMCHANNELS) {
999                         dev_err(&this_usbduxsub->interface->dev,
1000                                 "comedi%d: channel list too long\n",
1001                                 dev->minor);
1002                         break;
1003                 }
1004                 this_usbduxsub->dux_commands[i + 2] =
1005                     create_adc_command(chan, range);
1006         }
1007
1008         dev_dbg(&this_usbduxsub->interface->dev,
1009                 "comedi %d: sending commands to the usb device: size=%u\n",
1010                 dev->minor, NUMCHANNELS);
1011
1012         result = send_dux_commands(this_usbduxsub, SENDADCOMMANDS);
1013         if (result < 0) {
1014                 up(&this_usbduxsub->sem);
1015                 return result;
1016         }
1017
1018         if (this_usbduxsub->high_speed) {
1019                 /*
1020                  * every channel gets a time window of 125us. Thus, if we
1021                  * sample all 8 channels we need 1ms. If we sample only one
1022                  * channel we need only 125us
1023                  */
1024                 this_usbduxsub->ai_interval = 1;
1025                 /* find a power of 2 for the interval */
1026                 while ((this_usbduxsub->ai_interval) < (cmd->chanlist_len)) {
1027                         this_usbduxsub->ai_interval =
1028                             (this_usbduxsub->ai_interval) * 2;
1029                 }
1030                 this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
1031                                                           (this_usbduxsub->
1032                                                            ai_interval));
1033         } else {
1034                 /* interval always 1ms */
1035                 this_usbduxsub->ai_interval = 1;
1036                 this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000;
1037         }
1038         if (this_usbduxsub->ai_timer < 1) {
1039                 dev_err(&this_usbduxsub->interface->dev, "comedi%d: ai_cmd: "
1040                         "timer=%d, scan_begin_arg=%d. "
1041                         "Not properly tested by cmdtest?\n", dev->minor,
1042                         this_usbduxsub->ai_timer, cmd->scan_begin_arg);
1043                 up(&this_usbduxsub->sem);
1044                 return -EINVAL;
1045         }
1046         this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
1047
1048         if (cmd->stop_src == TRIG_COUNT) {
1049                 /* data arrives as one packet */
1050                 this_usbduxsub->ai_sample_count = cmd->stop_arg;
1051                 this_usbduxsub->ai_continous = 0;
1052         } else {
1053                 /* continous acquisition */
1054                 this_usbduxsub->ai_continous = 1;
1055                 this_usbduxsub->ai_sample_count = 0;
1056         }
1057
1058         if (cmd->start_src == TRIG_NOW) {
1059                 /* enable this acquisition operation */
1060                 this_usbduxsub->ai_cmd_running = 1;
1061                 ret = usbduxsub_submit_inurbs(this_usbduxsub);
1062                 if (ret < 0) {
1063                         this_usbduxsub->ai_cmd_running = 0;
1064                         /* fixme: unlink here?? */
1065                         up(&this_usbduxsub->sem);
1066                         return ret;
1067                 }
1068                 s->async->inttrig = NULL;
1069         } else {
1070                 /* TRIG_INT */
1071                 /* don't enable the acquision operation */
1072                 /* wait for an internal signal */
1073                 s->async->inttrig = usbdux_ai_inttrig;
1074         }
1075         up(&this_usbduxsub->sem);
1076         return 0;
1077 }
1078
1079 /* Mode 0 is used to get a single conversion on demand */
1080 static int usbdux_ai_insn_read(struct comedi_device *dev,
1081                                struct comedi_subdevice *s,
1082                                struct comedi_insn *insn, unsigned int *data)
1083 {
1084         int i;
1085         unsigned int one = 0;
1086         int chan, range;
1087         int err;
1088         struct usbdux_private *this_usbduxsub = dev->private;
1089
1090         if (!this_usbduxsub)
1091                 return 0;
1092
1093         dev_dbg(&this_usbduxsub->interface->dev,
1094                 "comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n",
1095                 dev->minor, insn->n, insn->subdev);
1096
1097         down(&this_usbduxsub->sem);
1098         if (this_usbduxsub->ai_cmd_running) {
1099                 dev_err(&this_usbduxsub->interface->dev,
1100                         "comedi%d: ai_insn_read not possible. "
1101                         "Async Command is running.\n", dev->minor);
1102                 up(&this_usbduxsub->sem);
1103                 return 0;
1104         }
1105
1106         /* sample one channel */
1107         chan = CR_CHAN(insn->chanspec);
1108         range = CR_RANGE(insn->chanspec);
1109         /* set command for the first channel */
1110         this_usbduxsub->dux_commands[1] = create_adc_command(chan, range);
1111
1112         /* adc commands */
1113         err = send_dux_commands(this_usbduxsub, SENDSINGLEAD);
1114         if (err < 0) {
1115                 up(&this_usbduxsub->sem);
1116                 return err;
1117         }
1118
1119         for (i = 0; i < insn->n; i++) {
1120                 err = receive_dux_commands(this_usbduxsub, SENDSINGLEAD);
1121                 if (err < 0) {
1122                         up(&this_usbduxsub->sem);
1123                         return 0;
1124                 }
1125                 one = le16_to_cpu(this_usbduxsub->insn_buffer[1]);
1126                 if (CR_RANGE(insn->chanspec) <= 1)
1127                         one = one ^ 0x800;
1128
1129                 data[i] = one;
1130         }
1131         up(&this_usbduxsub->sem);
1132         return i;
1133 }
1134
1135 /************************************/
1136 /* analog out */
1137
1138 static int usbdux_ao_insn_read(struct comedi_device *dev,
1139                                struct comedi_subdevice *s,
1140                                struct comedi_insn *insn, unsigned int *data)
1141 {
1142         int i;
1143         int chan = CR_CHAN(insn->chanspec);
1144         struct usbdux_private *this_usbduxsub = dev->private;
1145
1146         if (!this_usbduxsub)
1147                 return -EFAULT;
1148
1149         down(&this_usbduxsub->sem);
1150         for (i = 0; i < insn->n; i++)
1151                 data[i] = this_usbduxsub->out_buffer[chan];
1152
1153         up(&this_usbduxsub->sem);
1154         return i;
1155 }
1156
1157 static int usbdux_ao_insn_write(struct comedi_device *dev,
1158                                 struct comedi_subdevice *s,
1159                                 struct comedi_insn *insn, unsigned int *data)
1160 {
1161         int i, err;
1162         int chan = CR_CHAN(insn->chanspec);
1163         struct usbdux_private *this_usbduxsub = dev->private;
1164
1165         if (!this_usbduxsub)
1166                 return -EFAULT;
1167
1168         dev_dbg(&this_usbduxsub->interface->dev,
1169                 "comedi%d: ao_insn_write\n", dev->minor);
1170
1171         down(&this_usbduxsub->sem);
1172         if (this_usbduxsub->ao_cmd_running) {
1173                 dev_err(&this_usbduxsub->interface->dev,
1174                         "comedi%d: ao_insn_write: "
1175                         "ERROR: asynchronous ao_cmd is running\n", dev->minor);
1176                 up(&this_usbduxsub->sem);
1177                 return 0;
1178         }
1179
1180         for (i = 0; i < insn->n; i++) {
1181                 dev_dbg(&this_usbduxsub->interface->dev,
1182                         "comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n",
1183                         dev->minor, chan, i, data[i]);
1184
1185                 /* number of channels: 1 */
1186                 this_usbduxsub->dux_commands[1] = 1;
1187                 /* one 16 bit value */
1188                 *((int16_t *) (this_usbduxsub->dux_commands + 2)) =
1189                     cpu_to_le16(data[i]);
1190                 this_usbduxsub->out_buffer[chan] = data[i];
1191                 /* channel number */
1192                 this_usbduxsub->dux_commands[4] = (chan << 6);
1193                 err = send_dux_commands(this_usbduxsub, SENDDACOMMANDS);
1194                 if (err < 0) {
1195                         up(&this_usbduxsub->sem);
1196                         return err;
1197                 }
1198         }
1199         up(&this_usbduxsub->sem);
1200
1201         return i;
1202 }
1203
1204 static int usbdux_ao_inttrig(struct comedi_device *dev,
1205                              struct comedi_subdevice *s, unsigned int trignum)
1206 {
1207         int ret;
1208         struct usbdux_private *this_usbduxsub = dev->private;
1209
1210         if (!this_usbduxsub)
1211                 return -EFAULT;
1212
1213         down(&this_usbduxsub->sem);
1214         if (trignum != 0) {
1215                 dev_err(&this_usbduxsub->interface->dev,
1216                         "comedi%d: usbdux_ao_inttrig: invalid trignum\n",
1217                         dev->minor);
1218                 up(&this_usbduxsub->sem);
1219                 return -EINVAL;
1220         }
1221         if (!(this_usbduxsub->ao_cmd_running)) {
1222                 this_usbduxsub->ao_cmd_running = 1;
1223                 ret = usbduxsub_submit_outurbs(this_usbduxsub);
1224                 if (ret < 0) {
1225                         dev_err(&this_usbduxsub->interface->dev,
1226                                 "comedi%d: usbdux_ao_inttrig: submitURB: "
1227                                 "err=%d\n", dev->minor, ret);
1228                         this_usbduxsub->ao_cmd_running = 0;
1229                         up(&this_usbduxsub->sem);
1230                         return ret;
1231                 }
1232                 s->async->inttrig = NULL;
1233         } else {
1234                 dev_err(&this_usbduxsub->interface->dev,
1235                         "comedi%d: ao_inttrig but acqu is already running.\n",
1236                         dev->minor);
1237         }
1238         up(&this_usbduxsub->sem);
1239         return 1;
1240 }
1241
1242 static int usbdux_ao_cmdtest(struct comedi_device *dev,
1243                              struct comedi_subdevice *s, struct comedi_cmd *cmd)
1244 {
1245         struct usbdux_private *this_usbduxsub = dev->private;
1246         int err = 0;
1247         unsigned int flags;
1248
1249         if (!this_usbduxsub)
1250                 return -EFAULT;
1251
1252         /* Step 1 : check if triggers are trivially valid */
1253
1254         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
1255
1256         if (0) {                /* (this_usbduxsub->high_speed) */
1257                 /* the sampling rate is set by the coversion rate */
1258                 flags = TRIG_FOLLOW;
1259         } else {
1260                 /* start a new scan (output at once) with a timer */
1261                 flags = TRIG_TIMER;
1262         }
1263         err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
1264
1265         if (0) {                /* (this_usbduxsub->high_speed) */
1266                 /*
1267                  * in usb-2.0 only one conversion it transmitted
1268                  * but with 8kHz/n
1269                  */
1270                 flags = TRIG_TIMER;
1271         } else {
1272                 /*
1273                  * all conversion events happen simultaneously with
1274                  * a rate of 1kHz/n
1275                  */
1276                 flags = TRIG_NOW;
1277         }
1278         err |= cfc_check_trigger_src(&cmd->convert_src, flags);
1279
1280         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1281         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1282
1283         if (err)
1284                 return 1;
1285
1286         /* Step 2a : make sure trigger sources are unique */
1287
1288         err |= cfc_check_trigger_is_unique(cmd->start_src);
1289         err |= cfc_check_trigger_is_unique(cmd->stop_src);
1290
1291         /* Step 2b : and mutually compatible */
1292
1293         if (err)
1294                 return 2;
1295
1296         /* Step 3: check if arguments are trivially valid */
1297
1298         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1299
1300         if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
1301                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1302
1303         if (cmd->scan_begin_src == TRIG_TIMER)
1304                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1305                                                  1000000);
1306
1307         /* not used now, is for later use */
1308         if (cmd->convert_src == TRIG_TIMER)
1309                 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
1310
1311         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1312
1313         if (cmd->stop_src == TRIG_COUNT) {
1314                 /* any count is allowed */
1315         } else {
1316                 /* TRIG_NONE */
1317                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1318         }
1319
1320         if (err)
1321                 return 3;
1322
1323         return 0;
1324 }
1325
1326 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1327 {
1328         struct comedi_cmd *cmd = &s->async->cmd;
1329         unsigned int chan, gain;
1330         int i, ret;
1331         struct usbdux_private *this_usbduxsub = dev->private;
1332
1333         if (!this_usbduxsub)
1334                 return -EFAULT;
1335
1336         down(&this_usbduxsub->sem);
1337         dev_dbg(&this_usbduxsub->interface->dev,
1338                 "comedi%d: %s\n", dev->minor, __func__);
1339
1340         /* set current channel of the running acquisition to zero */
1341         s->async->cur_chan = 0;
1342         for (i = 0; i < cmd->chanlist_len; ++i) {
1343                 chan = CR_CHAN(cmd->chanlist[i]);
1344                 gain = CR_RANGE(cmd->chanlist[i]);
1345                 if (i >= NUMOUTCHANNELS) {
1346                         dev_err(&this_usbduxsub->interface->dev,
1347                                 "comedi%d: %s: channel list too long\n",
1348                                 dev->minor, __func__);
1349                         break;
1350                 }
1351                 this_usbduxsub->dac_commands[i] = (chan << 6);
1352                 dev_dbg(&this_usbduxsub->interface->dev,
1353                         "comedi%d: dac command for ch %d is %x\n",
1354                         dev->minor, i, this_usbduxsub->dac_commands[i]);
1355         }
1356
1357         /* we count in steps of 1ms (125us) */
1358         /* 125us mode not used yet */
1359         if (0) {                /* (this_usbduxsub->high_speed) */
1360                 /* 125us */
1361                 /* timing of the conversion itself: every 125 us */
1362                 this_usbduxsub->ao_timer = cmd->convert_arg / 125000;
1363         } else {
1364                 /* 1ms */
1365                 /* timing of the scan: we get all channels at once */
1366                 this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000;
1367                 dev_dbg(&this_usbduxsub->interface->dev,
1368                         "comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
1369                         "convert_src=%d, convert_arg=%d\n", dev->minor,
1370                         cmd->scan_begin_src, cmd->scan_begin_arg,
1371                         cmd->convert_src, cmd->convert_arg);
1372                 dev_dbg(&this_usbduxsub->interface->dev,
1373                         "comedi%d: ao_timer=%d (ms)\n",
1374                         dev->minor, this_usbduxsub->ao_timer);
1375                 if (this_usbduxsub->ao_timer < 1) {
1376                         dev_err(&this_usbduxsub->interface->dev,
1377                                 "comedi%d: usbdux: ao_timer=%d, "
1378                                 "scan_begin_arg=%d. "
1379                                 "Not properly tested by cmdtest?\n",
1380                                 dev->minor, this_usbduxsub->ao_timer,
1381                                 cmd->scan_begin_arg);
1382                         up(&this_usbduxsub->sem);
1383                         return -EINVAL;
1384                 }
1385         }
1386         this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
1387
1388         if (cmd->stop_src == TRIG_COUNT) {
1389                 /* not continuous */
1390                 /* counter */
1391                 /* high speed also scans everything at once */
1392                 if (0) {        /* (this_usbduxsub->high_speed) */
1393                         this_usbduxsub->ao_sample_count =
1394                             (cmd->stop_arg) * (cmd->scan_end_arg);
1395                 } else {
1396                         /* there's no scan as the scan has been */
1397                         /* perf inside the FX2 */
1398                         /* data arrives as one packet */
1399                         this_usbduxsub->ao_sample_count = cmd->stop_arg;
1400                 }
1401                 this_usbduxsub->ao_continous = 0;
1402         } else {
1403                 /* continous acquisition */
1404                 this_usbduxsub->ao_continous = 1;
1405                 this_usbduxsub->ao_sample_count = 0;
1406         }
1407
1408         if (cmd->start_src == TRIG_NOW) {
1409                 /* enable this acquisition operation */
1410                 this_usbduxsub->ao_cmd_running = 1;
1411                 ret = usbduxsub_submit_outurbs(this_usbduxsub);
1412                 if (ret < 0) {
1413                         this_usbduxsub->ao_cmd_running = 0;
1414                         /* fixme: unlink here?? */
1415                         up(&this_usbduxsub->sem);
1416                         return ret;
1417                 }
1418                 s->async->inttrig = NULL;
1419         } else {
1420                 /* TRIG_INT */
1421                 /* submit the urbs later */
1422                 /* wait for an internal signal */
1423                 s->async->inttrig = usbdux_ao_inttrig;
1424         }
1425
1426         up(&this_usbduxsub->sem);
1427         return 0;
1428 }
1429
1430 static int usbdux_dio_insn_config(struct comedi_device *dev,
1431                                   struct comedi_subdevice *s,
1432                                   struct comedi_insn *insn, unsigned int *data)
1433 {
1434         int chan = CR_CHAN(insn->chanspec);
1435
1436         /* The input or output configuration of each digital line is
1437          * configured by a special insn_config instruction.  chanspec
1438          * contains the channel to be changed, and data[0] contains the
1439          * value COMEDI_INPUT or COMEDI_OUTPUT. */
1440
1441         switch (data[0]) {
1442         case INSN_CONFIG_DIO_OUTPUT:
1443                 s->io_bits |= 1 << chan;        /* 1 means Out */
1444                 break;
1445         case INSN_CONFIG_DIO_INPUT:
1446                 s->io_bits &= ~(1 << chan);
1447                 break;
1448         case INSN_CONFIG_DIO_QUERY:
1449                 data[1] =
1450                     (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1451                 break;
1452         default:
1453                 return -EINVAL;
1454                 break;
1455         }
1456         /* we don't tell the firmware here as it would take 8 frames */
1457         /* to submit the information. We do it in the insn_bits. */
1458         return insn->n;
1459 }
1460
1461 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1462                                 struct comedi_subdevice *s,
1463                                 struct comedi_insn *insn, unsigned int *data)
1464 {
1465
1466         struct usbdux_private *this_usbduxsub = dev->private;
1467         int err;
1468
1469         if (!this_usbduxsub)
1470                 return -EFAULT;
1471
1472         down(&this_usbduxsub->sem);
1473
1474         /* The insn data is a mask in data[0] and the new data
1475          * in data[1], each channel cooresponding to a bit. */
1476         s->state &= ~data[0];
1477         s->state |= data[0] & data[1];
1478         this_usbduxsub->dux_commands[1] = s->io_bits;
1479         this_usbduxsub->dux_commands[2] = s->state;
1480
1481         /* This command also tells the firmware to return */
1482         /* the digital input lines */
1483         err = send_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1484         if (err < 0) {
1485                 up(&this_usbduxsub->sem);
1486                 return err;
1487         }
1488         err = receive_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1489         if (err < 0) {
1490                 up(&this_usbduxsub->sem);
1491                 return err;
1492         }
1493
1494         data[1] = le16_to_cpu(this_usbduxsub->insn_buffer[1]);
1495         up(&this_usbduxsub->sem);
1496         return insn->n;
1497 }
1498
1499 /* reads the 4 counters, only two are used just now */
1500 static int usbdux_counter_read(struct comedi_device *dev,
1501                                struct comedi_subdevice *s,
1502                                struct comedi_insn *insn, unsigned int *data)
1503 {
1504         struct usbdux_private *this_usbduxsub = dev->private;
1505         int chan = insn->chanspec;
1506         int err;
1507
1508         if (!this_usbduxsub)
1509                 return -EFAULT;
1510
1511         down(&this_usbduxsub->sem);
1512         err = send_dux_commands(this_usbduxsub, READCOUNTERCOMMAND);
1513         if (err < 0) {
1514                 up(&this_usbduxsub->sem);
1515                 return err;
1516         }
1517
1518         err = receive_dux_commands(this_usbduxsub, READCOUNTERCOMMAND);
1519         if (err < 0) {
1520                 up(&this_usbduxsub->sem);
1521                 return err;
1522         }
1523
1524         data[0] = le16_to_cpu(this_usbduxsub->insn_buffer[chan + 1]);
1525         up(&this_usbduxsub->sem);
1526         return 1;
1527 }
1528
1529 static int usbdux_counter_write(struct comedi_device *dev,
1530                                 struct comedi_subdevice *s,
1531                                 struct comedi_insn *insn, unsigned int *data)
1532 {
1533         struct usbdux_private *this_usbduxsub = dev->private;
1534         int err;
1535
1536         if (!this_usbduxsub)
1537                 return -EFAULT;
1538
1539         down(&this_usbduxsub->sem);
1540         this_usbduxsub->dux_commands[1] = insn->chanspec;
1541         *((int16_t *) (this_usbduxsub->dux_commands + 2)) = cpu_to_le16(*data);
1542
1543         err = send_dux_commands(this_usbduxsub, WRITECOUNTERCOMMAND);
1544         if (err < 0) {
1545                 up(&this_usbduxsub->sem);
1546                 return err;
1547         }
1548
1549         up(&this_usbduxsub->sem);
1550
1551         return 1;
1552 }
1553
1554 static int usbdux_counter_config(struct comedi_device *dev,
1555                                  struct comedi_subdevice *s,
1556                                  struct comedi_insn *insn, unsigned int *data)
1557 {
1558         /* nothing to do so far */
1559         return 2;
1560 }
1561
1562 /***********************************/
1563 /* PWM */
1564
1565 static int usbduxsub_unlink_pwm_urbs(struct usbdux_private *usbduxsub_tmp)
1566 {
1567         int err = 0;
1568
1569         if (usbduxsub_tmp && usbduxsub_tmp->urb_pwm) {
1570                 if (usbduxsub_tmp->urb_pwm)
1571                         usb_kill_urb(usbduxsub_tmp->urb_pwm);
1572                 dev_dbg(&usbduxsub_tmp->interface->dev,
1573                         "comedi: unlinked PwmURB: res=%d\n", err);
1574         }
1575         return err;
1576 }
1577
1578 /* This cancels a running acquisition operation
1579  * in any context.
1580  */
1581 static int usbdux_pwm_stop(struct usbdux_private *this_usbduxsub, int do_unlink)
1582 {
1583         int ret = 0;
1584
1585         if (!this_usbduxsub)
1586                 return -EFAULT;
1587
1588         dev_dbg(&this_usbduxsub->interface->dev, "comedi: %s\n", __func__);
1589         if (do_unlink)
1590                 ret = usbduxsub_unlink_pwm_urbs(this_usbduxsub);
1591
1592         this_usbduxsub->pwm_cmd_running = 0;
1593
1594         return ret;
1595 }
1596
1597 /* force unlink - is called by comedi */
1598 static int usbdux_pwm_cancel(struct comedi_device *dev,
1599                              struct comedi_subdevice *s)
1600 {
1601         struct usbdux_private *this_usbduxsub = dev->private;
1602         int res = 0;
1603
1604         /* unlink only if it is really running */
1605         res = usbdux_pwm_stop(this_usbduxsub, this_usbduxsub->pwm_cmd_running);
1606
1607         dev_dbg(&this_usbduxsub->interface->dev,
1608                 "comedi %d: sending pwm off command to the usb device.\n",
1609                 dev->minor);
1610
1611         return send_dux_commands(this_usbduxsub, SENDPWMOFF);
1612 }
1613
1614 static void usbduxsub_pwm_irq(struct urb *urb)
1615 {
1616         struct comedi_device *dev = urb->context;
1617         struct usbdux_private *devpriv = dev->private;
1618         int ret;
1619
1620         switch (urb->status) {
1621         case 0:
1622                 /* success */
1623                 break;
1624
1625         case -ECONNRESET:
1626         case -ENOENT:
1627         case -ESHUTDOWN:
1628         case -ECONNABORTED:
1629                 /*
1630                  * after an unlink command, unplug, ... etc
1631                  * no unlink needed here. Already shutting down.
1632                  */
1633                 if (devpriv->pwm_cmd_running)
1634                         usbdux_pwm_stop(devpriv, 0);
1635
1636                 return;
1637
1638         default:
1639                 /* a real error */
1640                 if (devpriv->pwm_cmd_running) {
1641                         dev_err(dev->class_dev,
1642                                 "Non-zero urb status received in pwm intr context: %d\n",
1643                                 urb->status);
1644                         usbdux_pwm_stop(devpriv, 0);
1645                 }
1646                 return;
1647         }
1648
1649         /* are we actually running? */
1650         if (!devpriv->pwm_cmd_running)
1651                 return;
1652
1653         urb->transfer_buffer_length = devpriv->size_pwm_buf;
1654         urb->dev = devpriv->usbdev;
1655         urb->status = 0;
1656         if (devpriv->pwm_cmd_running) {
1657                 ret = usb_submit_urb(urb, GFP_ATOMIC);
1658                 if (ret < 0) {
1659                         dev_err(dev->class_dev,
1660                                 "pwm urb resubm failed in int-cont. ret=%d",
1661                                 ret);
1662                         if (ret == EL2NSYNC)
1663                                 dev_err(dev->class_dev,
1664                                         "buggy USB host controller or bug in IRQ handling!\n");
1665
1666                         /* don't do an unlink here */
1667                         usbdux_pwm_stop(devpriv, 0);
1668                 }
1669         }
1670 }
1671
1672 static int usbduxsub_submit_pwm_urbs(struct usbdux_private *usbduxsub)
1673 {
1674         int err_flag;
1675
1676         if (!usbduxsub)
1677                 return -EFAULT;
1678
1679         dev_dbg(&usbduxsub->interface->dev, "comedi_: submitting pwm-urb\n");
1680
1681         /* in case of a resubmission after an unlink... */
1682         usb_fill_bulk_urb(usbduxsub->urb_pwm,
1683                           usbduxsub->usbdev,
1684                           usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP),
1685                           usbduxsub->urb_pwm->transfer_buffer,
1686                           usbduxsub->size_pwm_buf, usbduxsub_pwm_irq,
1687                           usbduxsub->comedidev);
1688
1689         err_flag = usb_submit_urb(usbduxsub->urb_pwm, GFP_ATOMIC);
1690         if (err_flag) {
1691                 dev_err(&usbduxsub->interface->dev,
1692                         "comedi_: usbdux: pwm: usb_submit_urb error %d\n",
1693                         err_flag);
1694                 return err_flag;
1695         }
1696         return 0;
1697 }
1698
1699 static int usbdux_pwm_period(struct comedi_device *dev,
1700                              struct comedi_subdevice *s, unsigned int period)
1701 {
1702         struct usbdux_private *this_usbduxsub = dev->private;
1703         int fx2delay = 255;
1704
1705         if (period < MIN_PWM_PERIOD) {
1706                 dev_err(&this_usbduxsub->interface->dev,
1707                         "comedi%d: illegal period setting for pwm.\n",
1708                         dev->minor);
1709                 return -EAGAIN;
1710         } else {
1711                 fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
1712                 if (fx2delay > 255) {
1713                         dev_err(&this_usbduxsub->interface->dev,
1714                                 "comedi%d: period %d for pwm is too low.\n",
1715                                 dev->minor, period);
1716                         return -EAGAIN;
1717                 }
1718         }
1719         this_usbduxsub->pwn_delay = fx2delay;
1720         this_usbduxsub->pwm_period = period;
1721         dev_dbg(&this_usbduxsub->interface->dev, "%s: frequ=%d, period=%d\n",
1722                 __func__, period, fx2delay);
1723         return 0;
1724 }
1725
1726 /* is called from insn so there's no need to do all the sanity checks */
1727 static int usbdux_pwm_start(struct comedi_device *dev,
1728                             struct comedi_subdevice *s)
1729 {
1730         int ret, i;
1731         struct usbdux_private *this_usbduxsub = dev->private;
1732
1733         dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: %s\n",
1734                 dev->minor, __func__);
1735
1736         if (this_usbduxsub->pwm_cmd_running) {
1737                 /* already running */
1738                 return 0;
1739         }
1740
1741         this_usbduxsub->dux_commands[1] = ((int8_t) this_usbduxsub->pwn_delay);
1742         ret = send_dux_commands(this_usbduxsub, SENDPWMON);
1743         if (ret < 0)
1744                 return ret;
1745
1746         /* initialise the buffer */
1747         for (i = 0; i < this_usbduxsub->size_pwm_buf; i++)
1748                 ((char *)(this_usbduxsub->urb_pwm->transfer_buffer))[i] = 0;
1749
1750         this_usbduxsub->pwm_cmd_running = 1;
1751         ret = usbduxsub_submit_pwm_urbs(this_usbduxsub);
1752         if (ret < 0) {
1753                 this_usbduxsub->pwm_cmd_running = 0;
1754                 return ret;
1755         }
1756         return 0;
1757 }
1758
1759 /* generates the bit pattern for PWM with the optional sign bit */
1760 static int usbdux_pwm_pattern(struct comedi_device *dev,
1761                               struct comedi_subdevice *s, int channel,
1762                               unsigned int value, unsigned int sign)
1763 {
1764         struct usbdux_private *this_usbduxsub = dev->private;
1765         int i, szbuf;
1766         char *p_buf;
1767         char pwm_mask;
1768         char sgn_mask;
1769         char c;
1770
1771         if (!this_usbduxsub)
1772                 return -EFAULT;
1773
1774         /* this is the DIO bit which carries the PWM data */
1775         pwm_mask = (1 << channel);
1776         /* this is the DIO bit which carries the optional direction bit */
1777         sgn_mask = (16 << channel);
1778         /* this is the buffer which will be filled with the with bit */
1779         /* pattern for one period */
1780         szbuf = this_usbduxsub->size_pwm_buf;
1781         p_buf = (char *)(this_usbduxsub->urb_pwm->transfer_buffer);
1782         for (i = 0; i < szbuf; i++) {
1783                 c = *p_buf;
1784                 /* reset bits */
1785                 c = c & (~pwm_mask);
1786                 /* set the bit as long as the index is lower than the value */
1787                 if (i < value)
1788                         c = c | pwm_mask;
1789                 /* set the optional sign bit for a relay */
1790                 if (!sign) {
1791                         /* positive value */
1792                         c = c & (~sgn_mask);
1793                 } else {
1794                         /* negative value */
1795                         c = c | sgn_mask;
1796                 }
1797                 *(p_buf++) = c;
1798         }
1799         return 1;
1800 }
1801
1802 static int usbdux_pwm_write(struct comedi_device *dev,
1803                             struct comedi_subdevice *s,
1804                             struct comedi_insn *insn, unsigned int *data)
1805 {
1806         struct usbdux_private *this_usbduxsub = dev->private;
1807
1808         if (!this_usbduxsub)
1809                 return -EFAULT;
1810
1811         if ((insn->n) != 1) {
1812                 /*
1813                  * doesn't make sense to have more than one value here because
1814                  * it would just overwrite the PWM buffer a couple of times
1815                  */
1816                 return -EINVAL;
1817         }
1818
1819         /*
1820          * the sign is set via a special INSN only, this gives us 8 bits for
1821          * normal operation
1822          * relay sign 0 by default
1823          */
1824         return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
1825 }
1826
1827 static int usbdux_pwm_read(struct comedi_device *x1,
1828                            struct comedi_subdevice *x2, struct comedi_insn *x3,
1829                            unsigned int *x4)
1830 {
1831         /* not needed */
1832         return -EINVAL;
1833 };
1834
1835 /* switches on/off PWM */
1836 static int usbdux_pwm_config(struct comedi_device *dev,
1837                              struct comedi_subdevice *s,
1838                              struct comedi_insn *insn, unsigned int *data)
1839 {
1840         struct usbdux_private *this_usbduxsub = dev->private;
1841         switch (data[0]) {
1842         case INSN_CONFIG_ARM:
1843                 /* switch it on */
1844                 dev_dbg(&this_usbduxsub->interface->dev,
1845                         "comedi%d: %s: pwm on\n", dev->minor, __func__);
1846                 /*
1847                  * if not zero the PWM is limited to a certain time which is
1848                  * not supported here
1849                  */
1850                 if (data[1] != 0)
1851                         return -EINVAL;
1852                 return usbdux_pwm_start(dev, s);
1853         case INSN_CONFIG_DISARM:
1854                 dev_dbg(&this_usbduxsub->interface->dev,
1855                         "comedi%d: %s: pwm off\n", dev->minor, __func__);
1856                 return usbdux_pwm_cancel(dev, s);
1857         case INSN_CONFIG_GET_PWM_STATUS:
1858                 /*
1859                  * to check if the USB transmission has failed or in case PWM
1860                  * was limited to n cycles to check if it has terminated
1861                  */
1862                 data[1] = this_usbduxsub->pwm_cmd_running;
1863                 return 0;
1864         case INSN_CONFIG_PWM_SET_PERIOD:
1865                 dev_dbg(&this_usbduxsub->interface->dev,
1866                         "comedi%d: %s: setting period\n", dev->minor, __func__);
1867                 return usbdux_pwm_period(dev, s, data[1]);
1868         case INSN_CONFIG_PWM_GET_PERIOD:
1869                 data[1] = this_usbduxsub->pwm_period;
1870                 return 0;
1871         case INSN_CONFIG_PWM_SET_H_BRIDGE:
1872                 /* value in the first byte and the sign in the second for a
1873                    relay */
1874                 return usbdux_pwm_pattern(dev, s,
1875                                           /* the channel number */
1876                                           CR_CHAN(insn->chanspec),
1877                                           /* actual PWM data */
1878                                           data[1],
1879                                           /* just a sign */
1880                                           (data[2] != 0));
1881         case INSN_CONFIG_PWM_GET_H_BRIDGE:
1882                 /* values are not kept in this driver, nothing to return here */
1883                 return -EINVAL;
1884         }
1885         return -EINVAL;
1886 }
1887
1888 /* end of PWM */
1889 /*****************************************************************/
1890
1891 static int usbdux_alloc_usb_buffers(struct usbdux_private *devpriv)
1892 {
1893         struct urb *urb;
1894         int i;
1895
1896         /* create space for the commands of the DA converter */
1897         devpriv->dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
1898         if (!devpriv->dac_commands)
1899                 return -ENOMEM;
1900
1901         /* create space for the commands going to the usb device */
1902         devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1903         if (!devpriv->dux_commands)
1904                 return -ENOMEM;
1905
1906         /* create space for the in buffer and set it to zero */
1907         devpriv->in_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1908         if (!devpriv->in_buffer)
1909                 return -ENOMEM;
1910
1911         /* create space of the instruction buffer */
1912         devpriv->insn_buffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1913         if (!devpriv->insn_buffer)
1914                 return -ENOMEM;
1915
1916         /* create space for the outbuffer */
1917         devpriv->out_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1918         if (!devpriv->out_buffer)
1919                 return -ENOMEM;
1920
1921         /* in urbs */
1922         devpriv->urb_in = kcalloc(devpriv->num_in_buffers, sizeof(*urb),
1923                                   GFP_KERNEL);
1924         if (!devpriv->urb_in)
1925                 return -ENOMEM;
1926
1927         for (i = 0; i < devpriv->num_in_buffers; i++) {
1928                 /* one frame: 1ms */
1929                 urb = usb_alloc_urb(1, GFP_KERNEL);
1930                 if (!urb)
1931                         return -ENOMEM;
1932                 devpriv->urb_in[i] = urb;
1933
1934                 urb->dev = devpriv->usbdev;
1935                 /* will be filled later with a pointer to the comedi-device */
1936                 /* and ONLY then the urb should be submitted */
1937                 urb->context = NULL;
1938                 urb->pipe = usb_rcvisocpipe(devpriv->usbdev, ISOINEP);
1939                 urb->transfer_flags = URB_ISO_ASAP;
1940                 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1941                 if (!urb->transfer_buffer)
1942                         return -ENOMEM;
1943
1944                 urb->complete = usbduxsub_ai_isoc_irq;
1945                 urb->number_of_packets = 1;
1946                 urb->transfer_buffer_length = SIZEINBUF;
1947                 urb->iso_frame_desc[0].offset = 0;
1948                 urb->iso_frame_desc[0].length = SIZEINBUF;
1949         }
1950
1951         /* out urbs */
1952         devpriv->urb_out = kcalloc(devpriv->num_out_buffers, sizeof(*urb),
1953                                    GFP_KERNEL);
1954         if (!devpriv->urb_out)
1955                 return -ENOMEM;
1956
1957         for (i = 0; i < devpriv->num_out_buffers; i++) {
1958                 /* one frame: 1ms */
1959                 urb = usb_alloc_urb(1, GFP_KERNEL);
1960                 if (!urb)
1961                         return -ENOMEM;
1962                 devpriv->urb_out[i] = urb;
1963
1964                 urb->dev = devpriv->usbdev;
1965                 /* will be filled later with a pointer to the comedi-device */
1966                 /* and ONLY then the urb should be submitted */
1967                 urb->context = NULL;
1968                 urb->pipe = usb_sndisocpipe(devpriv->usbdev, ISOOUTEP);
1969                 urb->transfer_flags = URB_ISO_ASAP;
1970                 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1971                 if (!urb->transfer_buffer)
1972                         return -ENOMEM;
1973
1974                 urb->complete = usbduxsub_ao_isoc_irq;
1975                 urb->number_of_packets = 1;
1976                 urb->transfer_buffer_length = SIZEOUTBUF;
1977                 urb->iso_frame_desc[0].offset = 0;
1978                 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1979                 if (devpriv->high_speed)
1980                         urb->interval = 8;      /* uframes */
1981                 else
1982                         urb->interval = 1;      /* frames */
1983         }
1984
1985         /* pwm */
1986         if (devpriv->size_pwm_buf) {
1987                 urb = usb_alloc_urb(0, GFP_KERNEL);
1988                 if (!urb)
1989                         return -ENOMEM;
1990                 devpriv->urb_pwm = urb;
1991
1992                 /* max bulk ep size in high speed */
1993                 urb->transfer_buffer = kzalloc(devpriv->size_pwm_buf,
1994                                                GFP_KERNEL);
1995                 if (!urb->transfer_buffer)
1996                         return -ENOMEM;
1997         }
1998
1999         return 0;
2000 }
2001
2002 static void usbdux_free_usb_buffers(struct usbdux_private *devpriv)
2003 {
2004         struct urb *urb;
2005         int i;
2006
2007         urb = devpriv->urb_pwm;
2008         if (urb) {
2009                 kfree(urb->transfer_buffer);
2010                 usb_kill_urb(urb);
2011                 usb_free_urb(urb);
2012         }
2013         if (devpriv->urb_out) {
2014                 for (i = 0; i < devpriv->num_out_buffers; i++) {
2015                         urb = devpriv->urb_out[i];
2016                         if (urb) {
2017                                 kfree(urb->transfer_buffer);
2018                                 usb_kill_urb(urb);
2019                                 usb_free_urb(urb);
2020                         }
2021                 }
2022                 kfree(devpriv->urb_out);
2023         }
2024         if (devpriv->urb_in) {
2025                 for (i = 0; i < devpriv->num_in_buffers; i++) {
2026                         urb = devpriv->urb_in[i];
2027                         if (urb) {
2028                                 kfree(urb->transfer_buffer);
2029                                 usb_kill_urb(urb);
2030                                 usb_free_urb(urb);
2031                         }
2032                 }
2033                 kfree(devpriv->urb_in);
2034         }
2035         kfree(devpriv->out_buffer);
2036         kfree(devpriv->insn_buffer);
2037         kfree(devpriv->in_buffer);
2038         kfree(devpriv->dux_commands);
2039         kfree(devpriv->dac_commands);
2040 }
2041
2042 static int usbdux_auto_attach(struct comedi_device *dev,
2043                               unsigned long context_unused)
2044 {
2045         struct usb_interface *intf = comedi_to_usb_interface(dev);
2046         struct usb_device *usb = comedi_to_usb_dev(dev);
2047         struct usbdux_private *devpriv;
2048         struct comedi_subdevice *s;
2049         int ret;
2050
2051         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
2052         if (!devpriv)
2053                 return -ENOMEM;
2054
2055         sema_init(&devpriv->sem, 1);
2056
2057         devpriv->comedidev = dev;
2058         devpriv->usbdev = usb;
2059         devpriv->interface = intf;
2060         devpriv->ifnum = intf->altsetting->desc.bInterfaceNumber;
2061         usb_set_intfdata(intf, devpriv);
2062
2063         devpriv->high_speed = (devpriv->usbdev->speed == USB_SPEED_HIGH);
2064         if (devpriv->high_speed) {
2065                 devpriv->num_in_buffers = NUMOFINBUFFERSHIGH;
2066                 devpriv->num_out_buffers = NUMOFOUTBUFFERSHIGH;
2067                 devpriv->size_pwm_buf = 512;
2068         } else {
2069                 devpriv->num_in_buffers = NUMOFINBUFFERSFULL;
2070                 devpriv->num_out_buffers = NUMOFOUTBUFFERSFULL;
2071         }
2072
2073         ret = usbdux_alloc_usb_buffers(devpriv);
2074         if (ret)
2075                 return ret;
2076
2077         /* setting to alternate setting 3: enabling iso ep and bulk ep. */
2078         ret = usb_set_interface(devpriv->usbdev, devpriv->ifnum, 3);
2079         if (ret < 0) {
2080                 dev_err(dev->class_dev,
2081                         "could not set alternate setting 3 in high speed\n");
2082                 return ret;
2083         }
2084
2085         ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
2086                                    usbdux_firmware_upload, 0);
2087         if (ret < 0)
2088                 return ret;
2089
2090         ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 5 : 4);
2091         if (ret)
2092                 return ret;
2093
2094         /* Analog Input subdevice */
2095         s = &dev->subdevices[0];
2096         dev->read_subdev = s;
2097         s->type         = COMEDI_SUBD_AI;
2098         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
2099         s->n_chan       = 8;
2100         s->maxdata      = 0x0fff;
2101         s->len_chanlist = 8;
2102         s->range_table  = &range_usbdux_ai_range;
2103         s->insn_read    = usbdux_ai_insn_read;
2104         s->do_cmdtest   = usbdux_ai_cmdtest;
2105         s->do_cmd       = usbdux_ai_cmd;
2106         s->cancel       = usbdux_ai_cancel;
2107
2108         /* Analog Output subdevice */
2109         s = &dev->subdevices[1];
2110         dev->write_subdev = s;
2111         s->type         = COMEDI_SUBD_AO;
2112         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
2113         s->n_chan       = 4;
2114         s->maxdata      = 0x0fff;
2115         s->len_chanlist = 4;
2116         s->range_table  = &range_usbdux_ao_range;
2117         s->do_cmdtest   = usbdux_ao_cmdtest;
2118         s->do_cmd       = usbdux_ao_cmd;
2119         s->cancel       = usbdux_ao_cancel;
2120         s->insn_read    = usbdux_ao_insn_read;
2121         s->insn_write   = usbdux_ao_insn_write;
2122
2123         /* Digital I/O subdevice */
2124         s = &dev->subdevices[2];
2125         s->type         = COMEDI_SUBD_DIO;
2126         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
2127         s->n_chan       = 8;
2128         s->maxdata      = 1;
2129         s->range_table  = &range_digital;
2130         s->insn_bits    = usbdux_dio_insn_bits;
2131         s->insn_config  = usbdux_dio_insn_config;
2132
2133         /* Counter subdevice */
2134         s = &dev->subdevices[3];
2135         s->type         = COMEDI_SUBD_COUNTER;
2136         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
2137         s->n_chan       = 4;
2138         s->maxdata      = 0xffff;
2139         s->insn_read    = usbdux_counter_read;
2140         s->insn_write   = usbdux_counter_write;
2141         s->insn_config  = usbdux_counter_config;
2142
2143         if (devpriv->high_speed) {
2144                 /* PWM subdevice */
2145                 s = &dev->subdevices[4];
2146                 s->type         = COMEDI_SUBD_PWM;
2147                 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
2148                 s->n_chan       = 8;
2149                 s->maxdata      = devpriv->size_pwm_buf;
2150                 s->insn_write   = usbdux_pwm_write;
2151                 s->insn_read    = usbdux_pwm_read;
2152                 s->insn_config  = usbdux_pwm_config;
2153
2154                 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
2155         }
2156
2157         return 0;
2158 }
2159
2160 static void usbdux_detach(struct comedi_device *dev)
2161 {
2162         struct usbdux_private *devpriv = dev->private;
2163
2164         if (devpriv) {
2165                 down(&devpriv->sem);
2166
2167                 usb_set_intfdata(devpriv->interface, NULL);
2168
2169                 if (devpriv->pwm_cmd_running)
2170                         usbduxsub_unlink_pwm_urbs(devpriv);
2171                 if (devpriv->ao_cmd_running)
2172                         usbduxsub_unlink_outurbs(devpriv);
2173                 if (devpriv->ai_cmd_running)
2174                         usbduxsub_unlink_inurbs(devpriv);
2175
2176                 usbdux_free_usb_buffers(devpriv);
2177
2178                 devpriv->comedidev = NULL;
2179
2180                 up(&devpriv->sem);
2181         }
2182 }
2183
2184 static struct comedi_driver usbdux_driver = {
2185         .driver_name    = "usbdux",
2186         .module         = THIS_MODULE,
2187         .auto_attach    = usbdux_auto_attach,
2188         .detach         = usbdux_detach,
2189 };
2190
2191 static int usbdux_usb_probe(struct usb_interface *intf,
2192                             const struct usb_device_id *id)
2193 {
2194         return comedi_usb_auto_config(intf, &usbdux_driver, 0);
2195 }
2196
2197 static const struct usb_device_id usbdux_usb_table[] = {
2198         { USB_DEVICE(0x13d8, 0x0001) },
2199         { USB_DEVICE(0x13d8, 0x0002) },
2200         { }
2201 };
2202 MODULE_DEVICE_TABLE(usb, usbdux_usb_table);
2203
2204 static struct usb_driver usbdux_usb_driver = {
2205         .name           = "usbdux",
2206         .probe          = usbdux_usb_probe,
2207         .disconnect     = comedi_usb_auto_unconfig,
2208         .id_table       = usbdux_usb_table,
2209 };
2210 module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver);
2211
2212 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
2213 MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com");
2214 MODULE_LICENSE("GPL");
2215 MODULE_FIRMWARE(FIRMWARE);