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