sunrpc: Include missing smp_lock.h
[linux-2.6-block.git] / drivers / staging / comedi / drivers / usbduxfast.c
1 /*
2  *  Copyright (C) 2004 Bernd Porr, Bernd.Porr@f2s.com
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 /*
20  * I must give credit here to Chris Baugher who
21  * wrote the driver for AT-MIO-16d. I used some parts of this
22  * driver. I also must give credits to David Brownell
23  * who supported me with the USB development.
24  *
25  * Bernd Porr
26  *
27  *
28  * Revision history:
29  * 0.9: Dropping the first data packet which seems to be from the last transfer.
30  *      Buffer overflows in the FX2 are handed over to comedi.
31  * 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
32  *       Added insn command basically for testing. Sample rate is
33  *       1MHz/16ch=62.5kHz
34  * 0.99: Ian Abbott pointed out a bug which has been corrected. Thanks!
35  * 0.99a: added external trigger.
36  * 1.00: added firmware kernel request to the driver which fixed
37  *       udev coldplug problem
38  */
39
40 #include <linux/kernel.h>
41 #include <linux/firmware.h>
42 #include <linux/module.h>
43 #include <linux/init.h>
44 #include <linux/slab.h>
45 #include <linux/input.h>
46 #include <linux/usb.h>
47 #include <linux/fcntl.h>
48 #include <linux/compiler.h>
49 #include "comedi_fc.h"
50 #include "../comedidev.h"
51
52 #define DRIVER_VERSION "v1.0"
53 #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
54 #define DRIVER_DESC "USB-DUXfast, BerndPorr@f2s.com"
55 #define BOARDNAME "usbduxfast"
56
57 /*
58  * timeout for the USB-transfer
59  */
60 #define EZTIMEOUT       30
61
62 /*
63  * constants for "firmware" upload and download
64  */
65 #define USBDUXFASTSUB_FIRMWARE  0xA0
66 #define VENDOR_DIR_IN           0xC0
67 #define VENDOR_DIR_OUT          0x40
68
69 /*
70  * internal adresses of the 8051 processor
71  */
72 #define USBDUXFASTSUB_CPUCS     0xE600
73
74 /*
75  * max lenghth of the transfer-buffer for software upload
76  */
77 #define TB_LEN  0x2000
78
79 /*
80  * input endpoint number
81  */
82 #define BULKINEP        6
83
84 /*
85  * endpoint for the A/D channellist: bulk OUT
86  */
87 #define CHANNELLISTEP   4
88
89 /*
90  * number of channels
91  */
92 #define NUMCHANNELS     32
93
94 /*
95  * size of the waveform descriptor
96  */
97 #define WAVESIZE        0x20
98
99 /*
100  * size of one A/D value
101  */
102 #define SIZEADIN        (sizeof(int16_t))
103
104 /*
105  * size of the input-buffer IN BYTES
106  */
107 #define SIZEINBUF       512
108
109 /*
110  * 16 bytes
111  */
112 #define SIZEINSNBUF     512
113
114 /*
115  * size of the buffer for the dux commands in bytes
116  */
117 #define SIZEOFDUXBUFFER 256
118
119 /*
120  * number of in-URBs which receive the data: min=5
121  */
122 #define NUMOFINBUFFERSHIGH      10
123
124 /*
125  * total number of usbduxfast devices
126  */
127 #define NUMUSBDUXFAST   16
128
129 /*
130  * number of subdevices
131  */
132 #define N_SUBDEVICES    1
133
134 /*
135  * analogue in subdevice
136  */
137 #define SUBDEV_AD       0
138
139 /*
140  * min delay steps for more than one channel
141  * basically when the mux gives up ;-)
142  *
143  * steps at 30MHz in the FX2
144  */
145 #define MIN_SAMPLING_PERIOD     9
146
147 /*
148  * max number of 1/30MHz delay steps
149  */
150 #define MAX_SAMPLING_PERIOD     500
151
152 /*
153  * number of received packets to ignore before we start handing data
154  * over to comedi, it's quad buffering and we have to ignore 4 packets
155  */
156 #define PACKETS_TO_IGNORE       4
157
158 /*
159  * comedi constants
160  */
161 static const struct comedi_lrange range_usbduxfast_ai_range = {
162         2, {BIP_RANGE(0.75), BIP_RANGE(0.5)}
163 };
164
165 /*
166  * private structure of one subdevice
167  *
168  * this is the structure which holds all the data of this driver
169  * one sub device just now: A/D
170  */
171 struct usbduxfastsub_s {
172         int attached;           /* is attached? */
173         int probed;             /* is it associated with a subdevice? */
174         struct usb_device *usbdev;      /* pointer to the usb-device */
175         struct urb *urbIn;      /* BULK-transfer handling: urb */
176         int8_t *transfer_buffer;
177         int16_t *insnBuffer;    /* input buffer for single insn */
178         int ifnum;              /* interface number */
179         struct usb_interface *interface;        /* interface structure */
180         struct comedi_device *comedidev;        /* comedi device for the interrupt
181                                                    context */
182         short int ai_cmd_running;       /* asynchronous command is running */
183         short int ai_continous; /* continous aquisition */
184         long int ai_sample_count;       /* number of samples to acquire */
185         uint8_t *dux_commands;  /* commands */
186         int ignore;             /* counter which ignores the first
187                                    buffers */
188         struct semaphore sem;
189 };
190
191 /*
192  * The pointer to the private usb-data of the driver
193  * is also the private data for the comedi-device.
194  * This has to be global as the usb subsystem needs
195  * global variables. The other reason is that this
196  * structure must be there _before_ any comedi
197  * command is issued. The usb subsystem must be
198  * initialised before comedi can access it.
199  */
200 static struct usbduxfastsub_s usbduxfastsub[NUMUSBDUXFAST];
201
202 static DECLARE_MUTEX(start_stop_sem);
203
204 /*
205  * bulk transfers to usbduxfast
206  */
207 #define SENDADCOMMANDS            0
208 #define SENDINITEP6               1
209
210 static int send_dux_commands(struct usbduxfastsub_s *udfs, int cmd_type)
211 {
212         int tmp, nsent;
213
214         udfs->dux_commands[0] = cmd_type;
215
216 #ifdef CONFIG_COMEDI_DEBUG
217         printk(KERN_DEBUG "comedi%d: usbduxfast: dux_commands: ",
218                udfs->comedidev->minor);
219         for (tmp = 0; tmp < SIZEOFDUXBUFFER; tmp++)
220                 printk(" %02x", udfs->dux_commands[tmp]);
221         printk("\n");
222 #endif
223
224         tmp = usb_bulk_msg(udfs->usbdev,
225                            usb_sndbulkpipe(udfs->usbdev, CHANNELLISTEP),
226                            udfs->dux_commands, SIZEOFDUXBUFFER, &nsent, 10000);
227         if (tmp < 0)
228                 printk(KERN_ERR "comedi%d: could not transmit dux_commands to"
229                        "the usb-device, err=%d\n", udfs->comedidev->minor, tmp);
230         return tmp;
231 }
232
233 /*
234  * Stops the data acquision.
235  * It should be safe to call this function from any context.
236  */
237 static int usbduxfastsub_unlink_InURBs(struct usbduxfastsub_s *udfs)
238 {
239         int j = 0;
240         int err = 0;
241
242         if (udfs && udfs->urbIn) {
243                 udfs->ai_cmd_running = 0;
244                 /* waits until a running transfer is over */
245                 usb_kill_urb(udfs->urbIn);
246                 j = 0;
247         }
248 #ifdef CONFIG_COMEDI_DEBUG
249         printk(KERN_DEBUG "comedi: usbduxfast: unlinked InURB: res=%d\n", j);
250 #endif
251         return err;
252 }
253
254 /*
255  * This will stop a running acquisition operation.
256  * Is called from within this driver from both the
257  * interrupt context and from comedi.
258  */
259 static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs, int do_unlink)
260 {
261         int ret = 0;
262
263         if (!udfs) {
264                 printk(KERN_ERR "comedi?: usbduxfast_ai_stop: udfs=NULL!\n");
265                 return -EFAULT;
266         }
267 #ifdef CONFIG_COMEDI_DEBUG
268         printk(KERN_DEBUG "comedi: usbduxfast_ai_stop\n");
269 #endif
270
271         udfs->ai_cmd_running = 0;
272
273         if (do_unlink)
274                 ret = usbduxfastsub_unlink_InURBs(udfs);        /* stop aquistion */
275
276         return ret;
277 }
278
279 /*
280  * This will cancel a running acquisition operation.
281  * This is called by comedi but never from inside the driver.
282  */
283 static int usbduxfast_ai_cancel(struct comedi_device *dev,
284                                 struct comedi_subdevice *s)
285 {
286         struct usbduxfastsub_s *udfs;
287         int ret;
288
289         /* force unlink of all urbs */
290 #ifdef CONFIG_COMEDI_DEBUG
291         printk(KERN_DEBUG "comedi: usbduxfast_ai_cancel\n");
292 #endif
293         udfs = dev->private;
294         if (!udfs) {
295                 printk(KERN_ERR "comedi: usbduxfast_ai_cancel: udfs=NULL\n");
296                 return -EFAULT;
297         }
298         down(&udfs->sem);
299         if (!udfs->probed) {
300                 up(&udfs->sem);
301                 return -ENODEV;
302         }
303         /* unlink */
304         ret = usbduxfast_ai_stop(udfs, 1);
305         up(&udfs->sem);
306
307         return ret;
308 }
309
310 /*
311  * analogue IN
312  * interrupt service routine
313  */
314 static void usbduxfastsub_ai_Irq(struct urb *urb)
315 {
316         int n, err;
317         struct usbduxfastsub_s *udfs;
318         struct comedi_device *this_comedidev;
319         struct comedi_subdevice *s;
320         uint16_t *p;
321
322         /* sanity checks - is the urb there? */
323         if (!urb) {
324                 printk(KERN_ERR "comedi_: usbduxfast_: ao int-handler called "
325                        "with urb=NULL!\n");
326                 return;
327         }
328         /* the context variable points to the subdevice */
329         this_comedidev = urb->context;
330         if (!this_comedidev) {
331                 printk(KERN_ERR "comedi_: usbduxfast_: urb context is a NULL "
332                        "pointer!\n");
333                 return;
334         }
335         /* the private structure of the subdevice is usbduxfastsub_s */
336         udfs = this_comedidev->private;
337         if (!udfs) {
338                 printk(KERN_ERR "comedi_: usbduxfast_: private of comedi "
339                        "subdev is a NULL pointer!\n");
340                 return;
341         }
342         /* are we running a command? */
343         if (unlikely(!udfs->ai_cmd_running)) {
344                 /*
345                  * not running a command
346                  * do not continue execution if no asynchronous command
347                  * is running in particular not resubmit
348                  */
349                 return;
350         }
351
352         if (unlikely(!udfs->attached)) {
353                 /* no comedi device there */
354                 return;
355         }
356         /* subdevice which is the AD converter */
357         s = this_comedidev->subdevices + SUBDEV_AD;
358
359         /* first we test if something unusual has just happened */
360         switch (urb->status) {
361         case 0:
362                 break;
363
364                 /*
365                  * happens after an unlink command or when the device
366                  * is plugged out
367                  */
368         case -ECONNRESET:
369         case -ENOENT:
370         case -ESHUTDOWN:
371         case -ECONNABORTED:
372                 /* tell this comedi */
373                 s->async->events |= COMEDI_CB_EOA;
374                 s->async->events |= COMEDI_CB_ERROR;
375                 comedi_event(udfs->comedidev, s);
376                 /* stop the transfer w/o unlink */
377                 usbduxfast_ai_stop(udfs, 0);
378                 return;
379
380         default:
381                 printk("comedi%d: usbduxfast: non-zero urb status received in "
382                        "ai intr context: %d\n",
383                        udfs->comedidev->minor, urb->status);
384                 s->async->events |= COMEDI_CB_EOA;
385                 s->async->events |= COMEDI_CB_ERROR;
386                 comedi_event(udfs->comedidev, s);
387                 usbduxfast_ai_stop(udfs, 0);
388                 return;
389         }
390
391         p = urb->transfer_buffer;
392         if (!udfs->ignore) {
393                 if (!udfs->ai_continous) {
394                         /* not continous, fixed number of samples */
395                         n = urb->actual_length / sizeof(uint16_t);
396                         if (unlikely(udfs->ai_sample_count < n)) {
397                                 /*
398                                  * we have send only a fraction of the bytes
399                                  * received
400                                  */
401                                 cfc_write_array_to_buffer(s,
402                                                           urb->transfer_buffer,
403                                                           udfs->ai_sample_count
404                                                           * sizeof(uint16_t));
405                                 usbduxfast_ai_stop(udfs, 0);
406                                 /* tell comedi that the acquistion is over */
407                                 s->async->events |= COMEDI_CB_EOA;
408                                 comedi_event(udfs->comedidev, s);
409                                 return;
410                         }
411                         udfs->ai_sample_count -= n;
412                 }
413                 /* write the full buffer to comedi */
414                 err = cfc_write_array_to_buffer(s, urb->transfer_buffer,
415                                                 urb->actual_length);
416                 if (unlikely(err == 0)) {
417                         /* buffer overflow */
418                         usbduxfast_ai_stop(udfs, 0);
419                         return;
420                 }
421
422                 /* tell comedi that data is there */
423                 comedi_event(udfs->comedidev, s);
424
425         } else {
426                 /* ignore this packet */
427                 udfs->ignore--;
428         }
429
430         /*
431          * command is still running
432          * resubmit urb for BULK transfer
433          */
434         urb->dev = udfs->usbdev;
435         urb->status = 0;
436         err = usb_submit_urb(urb, GFP_ATOMIC);
437         if (err < 0) {
438                 printk(KERN_ERR "comedi%d: usbduxfast: urb resubm failed: %d",
439                        udfs->comedidev->minor, err);
440                 s->async->events |= COMEDI_CB_EOA;
441                 s->async->events |= COMEDI_CB_ERROR;
442                 comedi_event(udfs->comedidev, s);
443                 usbduxfast_ai_stop(udfs, 0);
444         }
445 }
446
447 static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
448 {
449         int ret;
450         unsigned char local_transfer_buffer[16];
451
452         /* 7f92 to zero */
453         local_transfer_buffer[0] = 0;
454         ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE,   /* bRequest, "Firmware" */
455                               VENDOR_DIR_OUT,   /* bmRequestType */
456                               USBDUXFASTSUB_CPUCS,      /* Value */
457                               0x0000,   /* Index */
458                               local_transfer_buffer,    /* address of the transfer buffer */
459                               1,        /* Length */
460                               EZTIMEOUT);       /* Timeout */
461         if (ret < 0) {
462                 printk("comedi_: usbduxfast_: control msg failed (start)\n");
463                 return ret;
464         }
465
466         return 0;
467 }
468
469 static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
470 {
471         int ret;
472         unsigned char local_transfer_buffer[16];
473
474         /* 7f92 to one */
475         local_transfer_buffer[0] = 1;
476         ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE,   /* bRequest, "Firmware" */
477                               VENDOR_DIR_OUT,   /* bmRequestType */
478                               USBDUXFASTSUB_CPUCS,      /* Value */
479                               0x0000,   /* Index */
480                               local_transfer_buffer, 1, /* Length */
481                               EZTIMEOUT);       /* Timeout */
482         if (ret < 0) {
483                 printk(KERN_ERR "comedi_: usbduxfast: control msg failed "
484                        "(stop)\n");
485                 return ret;
486         }
487
488         return 0;
489 }
490
491 static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs,
492                                 unsigned char *local_transfer_buffer,
493                                 unsigned int startAddr, unsigned int len)
494 {
495         int ret;
496
497 #ifdef CONFIG_COMEDI_DEBUG
498         printk(KERN_DEBUG "comedi: usbduxfast: uploading %d bytes", len);
499         printk(KERN_DEBUG " to addr %d, first byte=%d.\n",
500                startAddr, local_transfer_buffer[0]);
501 #endif
502         ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE,   /* brequest, firmware */
503                               VENDOR_DIR_OUT,   /* bmRequestType */
504                               startAddr,        /* value */
505                               0x0000,   /* index */
506                               local_transfer_buffer,    /* our local safe buffer */
507                               len,      /* length */
508                               EZTIMEOUT);       /* timeout */
509
510 #ifdef CONFIG_COMEDI_DEBUG
511         printk(KERN_DEBUG "comedi_: usbduxfast: result=%d\n", ret);
512 #endif
513
514         if (ret < 0) {
515                 printk(KERN_ERR "comedi_: usbduxfast: uppload failed\n");
516                 return ret;
517         }
518
519         return 0;
520 }
521
522 int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs)
523 {
524         int ret;
525
526         if (!udfs)
527                 return -EFAULT;
528
529         usb_fill_bulk_urb(udfs->urbIn, udfs->usbdev,
530                           usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
531                           udfs->transfer_buffer,
532                           SIZEINBUF, usbduxfastsub_ai_Irq, udfs->comedidev);
533
534 #ifdef CONFIG_COMEDI_DEBUG
535         printk(KERN_DEBUG "comedi%d: usbduxfast: submitting in-urb: "
536                "0x%p,0x%p\n", udfs->comedidev->minor, udfs->urbIn->context,
537                udfs->urbIn->dev);
538 #endif
539         ret = usb_submit_urb(udfs->urbIn, GFP_ATOMIC);
540         if (ret) {
541                 printk(KERN_ERR "comedi_: usbduxfast: ai: usb_submit_urb error"
542                        " %d\n", ret);
543                 return ret;
544         }
545         return 0;
546 }
547
548 static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
549                                  struct comedi_subdevice *s,
550                                  struct comedi_cmd *cmd)
551 {
552         int err = 0, stop_mask = 0;
553         long int steps, tmp;
554         int minSamplPer;
555         struct usbduxfastsub_s *udfs = dev->private;
556
557         if (!udfs->probed)
558                 return -ENODEV;
559
560 #ifdef CONFIG_COMEDI_DEBUG
561         printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmdtest\n", dev->minor);
562         printk(KERN_DEBUG "comedi%d: usbduxfast: convert_arg=%u "
563                "scan_begin_arg=%u\n",
564                dev->minor, cmd->convert_arg, cmd->scan_begin_arg);
565 #endif
566         /* step 1: make sure trigger sources are trivially valid */
567
568         tmp = cmd->start_src;
569         cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT;
570         if (!cmd->start_src || tmp != cmd->start_src)
571                 err++;
572
573         tmp = cmd->scan_begin_src;
574         cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT;
575         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
576                 err++;
577
578         tmp = cmd->convert_src;
579         cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
580         if (!cmd->convert_src || tmp != cmd->convert_src)
581                 err++;
582
583         tmp = cmd->scan_end_src;
584         cmd->scan_end_src &= TRIG_COUNT;
585         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
586                 err++;
587
588         tmp = cmd->stop_src;
589         stop_mask = TRIG_COUNT | TRIG_NONE;
590         cmd->stop_src &= stop_mask;
591         if (!cmd->stop_src || tmp != cmd->stop_src)
592                 err++;
593
594         if (err)
595                 return 1;
596
597         /*
598          * step 2: make sure trigger sources are unique and mutually compatible
599          */
600
601         if (cmd->start_src != TRIG_NOW &&
602             cmd->start_src != TRIG_EXT && cmd->start_src != TRIG_INT)
603                 err++;
604         if (cmd->scan_begin_src != TRIG_TIMER &&
605             cmd->scan_begin_src != TRIG_FOLLOW &&
606             cmd->scan_begin_src != TRIG_EXT)
607                 err++;
608         if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
609                 err++;
610         if (cmd->stop_src != TRIG_COUNT &&
611             cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE)
612                 err++;
613
614         /* can't have external stop and start triggers at once */
615         if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
616                 err++;
617
618         if (err)
619                 return 2;
620
621         /* step 3: make sure arguments are trivially compatible */
622
623         if (cmd->start_src == TRIG_NOW && cmd->start_arg != 0) {
624                 cmd->start_arg = 0;
625                 err++;
626         }
627
628         if (!cmd->chanlist_len)
629                 err++;
630
631         if (cmd->scan_end_arg != cmd->chanlist_len) {
632                 cmd->scan_end_arg = cmd->chanlist_len;
633                 err++;
634         }
635
636         if (cmd->chanlist_len == 1)
637                 minSamplPer = 1;
638         else
639                 minSamplPer = MIN_SAMPLING_PERIOD;
640
641         if (cmd->convert_src == TRIG_TIMER) {
642                 steps = cmd->convert_arg * 30;
643                 if (steps < (minSamplPer * 1000))
644                         steps = minSamplPer * 1000;
645
646                 if (steps > (MAX_SAMPLING_PERIOD * 1000))
647                         steps = MAX_SAMPLING_PERIOD * 1000;
648
649                 /* calc arg again */
650                 tmp = steps / 30;
651                 if (cmd->convert_arg != tmp) {
652                         cmd->convert_arg = tmp;
653                         err++;
654                 }
655         }
656
657         if (cmd->scan_begin_src == TRIG_TIMER)
658                 err++;
659
660         /* stop source */
661         switch (cmd->stop_src) {
662         case TRIG_COUNT:
663                 if (!cmd->stop_arg) {
664                         cmd->stop_arg = 1;
665                         err++;
666                 }
667                 break;
668         case TRIG_NONE:
669                 if (cmd->stop_arg != 0) {
670                         cmd->stop_arg = 0;
671                         err++;
672                 }
673                 break;
674                 /*
675                  * TRIG_EXT doesn't care since it doesn't trigger
676                  * off a numbered channel
677                  */
678         default:
679                 break;
680         }
681
682         if (err)
683                 return 3;
684
685         /* step 4: fix up any arguments */
686
687         return 0;
688
689 }
690
691 static int usbduxfast_ai_inttrig(struct comedi_device *dev,
692                                  struct comedi_subdevice *s,
693                                  unsigned int trignum)
694 {
695         int ret;
696         struct usbduxfastsub_s *udfs = dev->private;
697
698         if (!udfs)
699                 return -EFAULT;
700
701         down(&udfs->sem);
702         if (!udfs->probed) {
703                 up(&udfs->sem);
704                 return -ENODEV;
705         }
706 #ifdef CONFIG_COMEDI_DEBUG
707         printk(KERN_DEBUG "comedi%d: usbduxfast_ai_inttrig\n", dev->minor);
708 #endif
709
710         if (trignum != 0) {
711                 printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: invalid"
712                        " trignum\n", dev->minor);
713                 up(&udfs->sem);
714                 return -EINVAL;
715         }
716         if (!udfs->ai_cmd_running) {
717                 udfs->ai_cmd_running = 1;
718                 ret = usbduxfastsub_submit_InURBs(udfs);
719                 if (ret < 0) {
720                         printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: "
721                                "urbSubmit: err=%d\n", dev->minor, ret);
722                         udfs->ai_cmd_running = 0;
723                         up(&udfs->sem);
724                         return ret;
725                 }
726                 s->async->inttrig = NULL;
727         } else {
728                 printk(KERN_ERR "comedi%d: ai_inttrig but acqu is already"
729                        " running\n", dev->minor);
730         }
731         up(&udfs->sem);
732         return 1;
733 }
734
735 /*
736  * offsets for the GPIF bytes
737  * the first byte is the command byte
738  */
739 #define LENBASE (1+0x00)
740 #define OPBASE  (1+0x08)
741 #define OUTBASE (1+0x10)
742 #define LOGBASE (1+0x18)
743
744 static int usbduxfast_ai_cmd(struct comedi_device *dev,
745                              struct comedi_subdevice *s)
746 {
747         struct comedi_cmd *cmd = &s->async->cmd;
748         unsigned int chan, gain, rngmask = 0xff;
749         int i, j, ret;
750         struct usbduxfastsub_s *udfs;
751         int result;
752         long steps, steps_tmp;
753
754 #ifdef CONFIG_COMEDI_DEBUG
755         printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmd\n", dev->minor);
756 #endif
757         udfs = dev->private;
758         if (!udfs)
759                 return -EFAULT;
760
761         down(&udfs->sem);
762         if (!udfs->probed) {
763                 up(&udfs->sem);
764                 return -ENODEV;
765         }
766         if (udfs->ai_cmd_running) {
767                 printk(KERN_ERR "comedi%d: ai_cmd not possible. Another ai_cmd"
768                        " is running.\n", dev->minor);
769                 up(&udfs->sem);
770                 return -EBUSY;
771         }
772         /* set current channel of the running aquisition to zero */
773         s->async->cur_chan = 0;
774
775         /*
776          * ignore the first buffers from the device if there
777          * is an error condition
778          */
779         udfs->ignore = PACKETS_TO_IGNORE;
780
781         if (cmd->chanlist_len > 0) {
782                 gain = CR_RANGE(cmd->chanlist[0]);
783                 for (i = 0; i < cmd->chanlist_len; ++i) {
784                         chan = CR_CHAN(cmd->chanlist[i]);
785                         if (chan != i) {
786                                 printk(KERN_ERR "comedi%d: cmd is accepting "
787                                        "only consecutive channels.\n",
788                                        dev->minor);
789                                 up(&udfs->sem);
790                                 return -EINVAL;
791                         }
792                         if ((gain != CR_RANGE(cmd->chanlist[i]))
793                             && (cmd->chanlist_len > 3)) {
794                                 printk(KERN_ERR "comedi%d: the gain must be"
795                                        " the same for all channels.\n",
796                                        dev->minor);
797                                 up(&udfs->sem);
798                                 return -EINVAL;
799                         }
800                         if (i >= NUMCHANNELS) {
801                                 printk(KERN_ERR "comedi%d: channel list too"
802                                        " long\n", dev->minor);
803                                 break;
804                         }
805                 }
806         }
807         steps = 0;
808         if (cmd->scan_begin_src == TRIG_TIMER) {
809                 printk(KERN_ERR "comedi%d: usbduxfast: "
810                        "scan_begin_src==TRIG_TIMER not valid.\n", dev->minor);
811                 up(&udfs->sem);
812                 return -EINVAL;
813         }
814         if (cmd->convert_src == TRIG_TIMER)
815                 steps = (cmd->convert_arg * 30) / 1000;
816
817         if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
818                 printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: steps=%ld, "
819                        "scan_begin_arg=%d. Not properly tested by cmdtest?\n",
820                        dev->minor, steps, cmd->scan_begin_arg);
821                 up(&udfs->sem);
822                 return -EINVAL;
823         }
824         if (steps > MAX_SAMPLING_PERIOD) {
825                 printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: sampling rate "
826                        "too low.\n", dev->minor);
827                 up(&udfs->sem);
828                 return -EINVAL;
829         }
830         if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
831             && (cmd->chanlist_len != 16)) {
832                 printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: TRIG_EXT only"
833                        " with 1 or 16 channels possible.\n", dev->minor);
834                 up(&udfs->sem);
835                 return -EINVAL;
836         }
837 #ifdef CONFIG_COMEDI_DEBUG
838         printk(KERN_DEBUG "comedi%d: usbduxfast: steps=%ld, convert_arg=%u\n",
839                dev->minor, steps, cmd->convert_arg);
840 #endif
841
842         switch (cmd->chanlist_len) {
843         case 1:
844                 /*
845                  * one channel
846                  */
847
848                 if (CR_RANGE(cmd->chanlist[0]) > 0)
849                         rngmask = 0xff - 0x04;
850                 else
851                         rngmask = 0xff;
852
853                 /*
854                  * for external trigger: looping in this state until
855                  * the RDY0 pin becomes zero
856                  */
857
858                 /* we loop here until ready has been set */
859                 if (cmd->start_src == TRIG_EXT) {
860                         /* branch back to state 0 */
861                         udfs->dux_commands[LENBASE + 0] = 0x01;
862                         /* deceision state w/o data */
863                         udfs->dux_commands[OPBASE + 0] = 0x01;
864                         udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
865                         /* RDY0 = 0 */
866                         udfs->dux_commands[LOGBASE + 0] = 0x00;
867                 } else {        /* we just proceed to state 1 */
868                         udfs->dux_commands[LENBASE + 0] = 1;
869                         udfs->dux_commands[OPBASE + 0] = 0;
870                         udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
871                         udfs->dux_commands[LOGBASE + 0] = 0;
872                 }
873
874                 if (steps < MIN_SAMPLING_PERIOD) {
875                         /* for fast single channel aqu without mux */
876                         if (steps <= 1) {
877                                 /*
878                                  * we just stay here at state 1 and rexecute
879                                  * the same state this gives us 30MHz sampling
880                                  * rate
881                                  */
882
883                                 /* branch back to state 1 */
884                                 udfs->dux_commands[LENBASE + 1] = 0x89;
885                                 /* deceision state with data */
886                                 udfs->dux_commands[OPBASE + 1] = 0x03;
887                                 udfs->dux_commands[OUTBASE + 1] =
888                                     0xFF & rngmask;
889                                 /* doesn't matter */
890                                 udfs->dux_commands[LOGBASE + 1] = 0xFF;
891                         } else {
892                                 /*
893                                  * we loop through two states: data and delay
894                                  * max rate is 15MHz
895                                  */
896                                 udfs->dux_commands[LENBASE + 1] = steps - 1;
897                                 /* data */
898                                 udfs->dux_commands[OPBASE + 1] = 0x02;
899                                 udfs->dux_commands[OUTBASE + 1] =
900                                     0xFF & rngmask;
901                                 /* doesn't matter */
902                                 udfs->dux_commands[LOGBASE + 1] = 0;
903                                 /* branch back to state 1 */
904                                 udfs->dux_commands[LENBASE + 2] = 0x09;
905                                 /* deceision state w/o data */
906                                 udfs->dux_commands[OPBASE + 2] = 0x01;
907                                 udfs->dux_commands[OUTBASE + 2] =
908                                     0xFF & rngmask;
909                                 /* doesn't matter */
910                                 udfs->dux_commands[LOGBASE + 2] = 0xFF;
911                         }
912                 } else {
913                         /*
914                          * we loop through 3 states: 2x delay and 1x data
915                          * this gives a min sampling rate of 60kHz
916                          */
917
918                         /* we have 1 state with duration 1 */
919                         steps = steps - 1;
920
921                         /* do the first part of the delay */
922                         udfs->dux_commands[LENBASE + 1] = steps / 2;
923                         udfs->dux_commands[OPBASE + 1] = 0;
924                         udfs->dux_commands[OUTBASE + 1] = 0xFF & rngmask;
925                         udfs->dux_commands[LOGBASE + 1] = 0;
926
927                         /* and the second part */
928                         udfs->dux_commands[LENBASE + 2] = steps - steps / 2;
929                         udfs->dux_commands[OPBASE + 2] = 0;
930                         udfs->dux_commands[OUTBASE + 2] = 0xFF & rngmask;
931                         udfs->dux_commands[LOGBASE + 2] = 0;
932
933                         /* get the data and branch back */
934
935                         /* branch back to state 1 */
936                         udfs->dux_commands[LENBASE + 3] = 0x09;
937                         /* deceision state w data */
938                         udfs->dux_commands[OPBASE + 3] = 0x03;
939                         udfs->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
940                         /* doesn't matter */
941                         udfs->dux_commands[LOGBASE + 3] = 0xFF;
942                 }
943                 break;
944
945         case 2:
946                 /*
947                  * two channels
948                  * commit data to the FIFO
949                  */
950
951                 if (CR_RANGE(cmd->chanlist[0]) > 0)
952                         rngmask = 0xff - 0x04;
953                 else
954                         rngmask = 0xff;
955
956                 udfs->dux_commands[LENBASE + 0] = 1;
957                 /* data */
958                 udfs->dux_commands[OPBASE + 0] = 0x02;
959                 udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
960                 udfs->dux_commands[LOGBASE + 0] = 0;
961
962                 /* we have 1 state with duration 1: state 0 */
963                 steps_tmp = steps - 1;
964
965                 if (CR_RANGE(cmd->chanlist[1]) > 0)
966                         rngmask = 0xff - 0x04;
967                 else
968                         rngmask = 0xff;
969
970                 /* do the first part of the delay */
971                 udfs->dux_commands[LENBASE + 1] = steps_tmp / 2;
972                 udfs->dux_commands[OPBASE + 1] = 0;
973                 /* count */
974                 udfs->dux_commands[OUTBASE + 1] = 0xFE & rngmask;
975                 udfs->dux_commands[LOGBASE + 1] = 0;
976
977                 /* and the second part */
978                 udfs->dux_commands[LENBASE + 2] = steps_tmp - steps_tmp / 2;
979                 udfs->dux_commands[OPBASE + 2] = 0;
980                 udfs->dux_commands[OUTBASE + 2] = 0xFF & rngmask;
981                 udfs->dux_commands[LOGBASE + 2] = 0;
982
983                 udfs->dux_commands[LENBASE + 3] = 1;
984                 /* data */
985                 udfs->dux_commands[OPBASE + 3] = 0x02;
986                 udfs->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
987                 udfs->dux_commands[LOGBASE + 3] = 0;
988
989                 /*
990                  * we have 2 states with duration 1: step 6 and
991                  * the IDLE state
992                  */
993                 steps_tmp = steps - 2;
994
995                 if (CR_RANGE(cmd->chanlist[0]) > 0)
996                         rngmask = 0xff - 0x04;
997                 else
998                         rngmask = 0xff;
999
1000                 /* do the first part of the delay */
1001                 udfs->dux_commands[LENBASE + 4] = steps_tmp / 2;
1002                 udfs->dux_commands[OPBASE + 4] = 0;
1003                 /* reset */
1004                 udfs->dux_commands[OUTBASE + 4] = (0xFF - 0x02) & rngmask;
1005                 udfs->dux_commands[LOGBASE + 4] = 0;
1006
1007                 /* and the second part */
1008                 udfs->dux_commands[LENBASE + 5] = steps_tmp - steps_tmp / 2;
1009                 udfs->dux_commands[OPBASE + 5] = 0;
1010                 udfs->dux_commands[OUTBASE + 5] = 0xFF & rngmask;
1011                 udfs->dux_commands[LOGBASE + 5] = 0;
1012
1013                 udfs->dux_commands[LENBASE + 6] = 1;
1014                 udfs->dux_commands[OPBASE + 6] = 0;
1015                 udfs->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
1016                 udfs->dux_commands[LOGBASE + 6] = 0;
1017                 break;
1018
1019         case 3:
1020                 /*
1021                  * three channels
1022                  */
1023                 for (j = 0; j < 1; j++) {
1024                         if (CR_RANGE(cmd->chanlist[j]) > 0)
1025                                 rngmask = 0xff - 0x04;
1026                         else
1027                                 rngmask = 0xff;
1028                         /*
1029                          * commit data to the FIFO and do the first part
1030                          * of the delay
1031                          */
1032                         udfs->dux_commands[LENBASE + j * 2] = steps / 2;
1033                         /* data */
1034                         udfs->dux_commands[OPBASE + j * 2] = 0x02;
1035                         /* no change */
1036                         udfs->dux_commands[OUTBASE + j * 2] = 0xFF & rngmask;
1037                         udfs->dux_commands[LOGBASE + j * 2] = 0;
1038
1039                         if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
1040                                 rngmask = 0xff - 0x04;
1041                         else
1042                                 rngmask = 0xff;
1043
1044                         /* do the second part of the delay */
1045                         udfs->dux_commands[LENBASE + j * 2 + 1] =
1046                             steps - steps / 2;
1047                         /* no data */
1048                         udfs->dux_commands[OPBASE + j * 2 + 1] = 0;
1049                         /* count */
1050                         udfs->dux_commands[OUTBASE + j * 2 + 1] =
1051                             0xFE & rngmask;
1052                         udfs->dux_commands[LOGBASE + j * 2 + 1] = 0;
1053                 }
1054
1055                 /* 2 steps with duration 1: the idele step and step 6: */
1056                 steps_tmp = steps - 2;
1057
1058                 /* commit data to the FIFO and do the first part of the delay */
1059                 udfs->dux_commands[LENBASE + 4] = steps_tmp / 2;
1060                 /* data */
1061                 udfs->dux_commands[OPBASE + 4] = 0x02;
1062                 udfs->dux_commands[OUTBASE + 4] = 0xFF & rngmask;
1063                 udfs->dux_commands[LOGBASE + 4] = 0;
1064
1065                 if (CR_RANGE(cmd->chanlist[0]) > 0)
1066                         rngmask = 0xff - 0x04;
1067                 else
1068                         rngmask = 0xff;
1069
1070                 /* do the second part of the delay */
1071                 udfs->dux_commands[LENBASE + 5] = steps_tmp - steps_tmp / 2;
1072                 /* no data */
1073                 udfs->dux_commands[OPBASE + 5] = 0;
1074                 /* reset */
1075                 udfs->dux_commands[OUTBASE + 5] = (0xFF - 0x02) & rngmask;
1076                 udfs->dux_commands[LOGBASE + 5] = 0;
1077
1078                 udfs->dux_commands[LENBASE + 6] = 1;
1079                 udfs->dux_commands[OPBASE + 6] = 0;
1080                 udfs->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
1081                 udfs->dux_commands[LOGBASE + 6] = 0;
1082
1083         case 16:
1084                 if (CR_RANGE(cmd->chanlist[0]) > 0)
1085                         rngmask = 0xff - 0x04;
1086                 else
1087                         rngmask = 0xff;
1088
1089                 if (cmd->start_src == TRIG_EXT) {
1090                         /*
1091                          * we loop here until ready has been set
1092                          */
1093
1094                         /* branch back to state 0 */
1095                         udfs->dux_commands[LENBASE + 0] = 0x01;
1096                         /* deceision state w/o data */
1097                         udfs->dux_commands[OPBASE + 0] = 0x01;
1098                         /* reset */
1099                         udfs->dux_commands[OUTBASE + 0] =
1100                             (0xFF - 0x02) & rngmask;
1101                         /* RDY0 = 0 */
1102                         udfs->dux_commands[LOGBASE + 0] = 0x00;
1103                 } else {
1104                         /*
1105                          * we just proceed to state 1
1106                          */
1107
1108                         /* 30us reset pulse */
1109                         udfs->dux_commands[LENBASE + 0] = 255;
1110                         udfs->dux_commands[OPBASE + 0] = 0;
1111                         /* reset */
1112                         udfs->dux_commands[OUTBASE + 0] =
1113                             (0xFF - 0x02) & rngmask;
1114                         udfs->dux_commands[LOGBASE + 0] = 0;
1115                 }
1116
1117                 /* commit data to the FIFO */
1118                 udfs->dux_commands[LENBASE + 1] = 1;
1119                 /* data */
1120                 udfs->dux_commands[OPBASE + 1] = 0x02;
1121                 udfs->dux_commands[OUTBASE + 1] = 0xFF & rngmask;
1122                 udfs->dux_commands[LOGBASE + 1] = 0;
1123
1124                 /* we have 2 states with duration 1 */
1125                 steps = steps - 2;
1126
1127                 /* do the first part of the delay */
1128                 udfs->dux_commands[LENBASE + 2] = steps / 2;
1129                 udfs->dux_commands[OPBASE + 2] = 0;
1130                 udfs->dux_commands[OUTBASE + 2] = 0xFE & rngmask;
1131                 udfs->dux_commands[LOGBASE + 2] = 0;
1132
1133                 /* and the second part */
1134                 udfs->dux_commands[LENBASE + 3] = steps - steps / 2;
1135                 udfs->dux_commands[OPBASE + 3] = 0;
1136                 udfs->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
1137                 udfs->dux_commands[LOGBASE + 3] = 0;
1138
1139                 /* branch back to state 1 */
1140                 udfs->dux_commands[LENBASE + 4] = 0x09;
1141                 /* deceision state w/o data */
1142                 udfs->dux_commands[OPBASE + 4] = 0x01;
1143                 udfs->dux_commands[OUTBASE + 4] = 0xFF & rngmask;
1144                 /* doesn't matter */
1145                 udfs->dux_commands[LOGBASE + 4] = 0xFF;
1146
1147                 break;
1148
1149         default:
1150                 printk(KERN_ERR "comedi %d: unsupported combination of "
1151                        "channels\n", dev->minor);
1152                 up(&udfs->sem);
1153                 return -EFAULT;
1154         }
1155
1156 #ifdef CONFIG_COMEDI_DEBUG
1157         printk(KERN_DEBUG "comedi %d: sending commands to the usb device\n",
1158                dev->minor);
1159 #endif
1160         /* 0 means that the AD commands are sent */
1161         result = send_dux_commands(udfs, SENDADCOMMANDS);
1162         if (result < 0) {
1163                 printk(KERN_ERR "comedi%d: adc command could not be submitted."
1164                        "Aborting...\n", dev->minor);
1165                 up(&udfs->sem);
1166                 return result;
1167         }
1168         if (cmd->stop_src == TRIG_COUNT) {
1169                 udfs->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg;
1170                 if (udfs->ai_sample_count < 1) {
1171                         printk(KERN_ERR "comedi%d: "
1172                                "(cmd->stop_arg)*(cmd->scan_end_arg)<1, "
1173                                "aborting.\n", dev->minor);
1174                         up(&udfs->sem);
1175                         return -EFAULT;
1176                 }
1177                 udfs->ai_continous = 0;
1178         } else {
1179                 /* continous aquisition */
1180                 udfs->ai_continous = 1;
1181                 udfs->ai_sample_count = 0;
1182         }
1183
1184         if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
1185                 /* enable this acquisition operation */
1186                 udfs->ai_cmd_running = 1;
1187                 ret = usbduxfastsub_submit_InURBs(udfs);
1188                 if (ret < 0) {
1189                         udfs->ai_cmd_running = 0;
1190                         /* fixme: unlink here?? */
1191                         up(&udfs->sem);
1192                         return ret;
1193                 }
1194                 s->async->inttrig = NULL;
1195         } else {
1196                 /*
1197                  * TRIG_INT
1198                  * don't enable the acquision operation
1199                  * wait for an internal signal
1200                  */
1201                 s->async->inttrig = usbduxfast_ai_inttrig;
1202         }
1203         up(&udfs->sem);
1204
1205         return 0;
1206 }
1207
1208 /*
1209  * Mode 0 is used to get a single conversion on demand.
1210  */
1211 static int usbduxfast_ai_insn_read(struct comedi_device *dev,
1212                                    struct comedi_subdevice *s,
1213                                    struct comedi_insn *insn, unsigned int *data)
1214 {
1215         int i, j, n, actual_length;
1216         int chan, range, rngmask;
1217         int err;
1218         struct usbduxfastsub_s *udfs;
1219
1220         udfs = dev->private;
1221         if (!udfs) {
1222                 printk(KERN_ERR "comedi%d: ai_insn_read: no usb dev.\n",
1223                        dev->minor);
1224                 return -ENODEV;
1225         }
1226 #ifdef CONFIG_COMEDI_DEBUG
1227         printk(KERN_DEBUG "comedi%d: ai_insn_read, insn->n=%d, "
1228                "insn->subdev=%d\n", dev->minor, insn->n, insn->subdev);
1229 #endif
1230         down(&udfs->sem);
1231         if (!udfs->probed) {
1232                 up(&udfs->sem);
1233                 return -ENODEV;
1234         }
1235         if (udfs->ai_cmd_running) {
1236                 printk(KERN_ERR "comedi%d: ai_insn_read not possible. Async "
1237                        "Command is running.\n", dev->minor);
1238                 up(&udfs->sem);
1239                 return -EBUSY;
1240         }
1241         /* sample one channel */
1242         chan = CR_CHAN(insn->chanspec);
1243         range = CR_RANGE(insn->chanspec);
1244         /* set command for the first channel */
1245
1246         if (range > 0)
1247                 rngmask = 0xff - 0x04;
1248         else
1249                 rngmask = 0xff;
1250
1251         /* commit data to the FIFO */
1252         udfs->dux_commands[LENBASE + 0] = 1;
1253         /* data */
1254         udfs->dux_commands[OPBASE + 0] = 0x02;
1255         udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
1256         udfs->dux_commands[LOGBASE + 0] = 0;
1257
1258         /* do the first part of the delay */
1259         udfs->dux_commands[LENBASE + 1] = 12;
1260         udfs->dux_commands[OPBASE + 1] = 0;
1261         udfs->dux_commands[OUTBASE + 1] = 0xFE & rngmask;
1262         udfs->dux_commands[LOGBASE + 1] = 0;
1263
1264         udfs->dux_commands[LENBASE + 2] = 1;
1265         udfs->dux_commands[OPBASE + 2] = 0;
1266         udfs->dux_commands[OUTBASE + 2] = 0xFE & rngmask;
1267         udfs->dux_commands[LOGBASE + 2] = 0;
1268
1269         udfs->dux_commands[LENBASE + 3] = 1;
1270         udfs->dux_commands[OPBASE + 3] = 0;
1271         udfs->dux_commands[OUTBASE + 3] = 0xFE & rngmask;
1272         udfs->dux_commands[LOGBASE + 3] = 0;
1273
1274         udfs->dux_commands[LENBASE + 4] = 1;
1275         udfs->dux_commands[OPBASE + 4] = 0;
1276         udfs->dux_commands[OUTBASE + 4] = 0xFE & rngmask;
1277         udfs->dux_commands[LOGBASE + 4] = 0;
1278
1279         /* second part */
1280         udfs->dux_commands[LENBASE + 5] = 12;
1281         udfs->dux_commands[OPBASE + 5] = 0;
1282         udfs->dux_commands[OUTBASE + 5] = 0xFF & rngmask;
1283         udfs->dux_commands[LOGBASE + 5] = 0;
1284
1285         udfs->dux_commands[LENBASE + 6] = 1;
1286         udfs->dux_commands[OPBASE + 6] = 0;
1287         udfs->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
1288         udfs->dux_commands[LOGBASE + 0] = 0;
1289
1290 #ifdef CONFIG_COMEDI_DEBUG
1291         printk(KERN_DEBUG "comedi %d: sending commands to the usb device\n",
1292                dev->minor);
1293 #endif
1294         /* 0 means that the AD commands are sent */
1295         err = send_dux_commands(udfs, SENDADCOMMANDS);
1296         if (err < 0) {
1297                 printk(KERN_ERR "comedi%d: adc command could not be submitted."
1298                        "Aborting...\n", dev->minor);
1299                 up(&udfs->sem);
1300                 return err;
1301         }
1302 #ifdef CONFIG_COMEDI_DEBUG
1303         printk(KERN_DEBUG "comedi%d: usbduxfast: submitting in-urb: "
1304                "0x%p,0x%p\n", udfs->comedidev->minor, udfs->urbIn->context,
1305                udfs->urbIn->dev);
1306 #endif
1307         for (i = 0; i < PACKETS_TO_IGNORE; i++) {
1308                 err = usb_bulk_msg(udfs->usbdev,
1309                                    usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
1310                                    udfs->transfer_buffer, SIZEINBUF,
1311                                    &actual_length, 10000);
1312                 if (err < 0) {
1313                         printk(KERN_ERR "comedi%d: insn timeout. No data.\n",
1314                                dev->minor);
1315                         up(&udfs->sem);
1316                         return err;
1317                 }
1318         }
1319         /* data points */
1320         for (i = 0; i < insn->n;) {
1321                 err = usb_bulk_msg(udfs->usbdev,
1322                                    usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
1323                                    udfs->transfer_buffer, SIZEINBUF,
1324                                    &actual_length, 10000);
1325                 if (err < 0) {
1326                         printk(KERN_ERR "comedi%d: insn data error: %d\n",
1327                                dev->minor, err);
1328                         up(&udfs->sem);
1329                         return err;
1330                 }
1331                 n = actual_length / sizeof(uint16_t);
1332                 if ((n % 16) != 0) {
1333                         printk(KERN_ERR "comedi%d: insn data packet "
1334                                "corrupted.\n", dev->minor);
1335                         up(&udfs->sem);
1336                         return -EINVAL;
1337                 }
1338                 for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
1339                         data[i] = ((uint16_t *) (udfs->transfer_buffer))[j];
1340                         i++;
1341                 }
1342         }
1343         up(&udfs->sem);
1344         return i;
1345 }
1346
1347 #define FIRMWARE_MAX_LEN 0x2000
1348
1349 static int firmwareUpload(struct usbduxfastsub_s *usbduxfastsub,
1350                           const u8 * firmwareBinary, int sizeFirmware)
1351 {
1352         int ret;
1353         uint8_t *fwBuf;
1354
1355         if (!firmwareBinary)
1356                 return 0;
1357
1358         if (sizeFirmware > FIRMWARE_MAX_LEN) {
1359                 dev_err(&usbduxfastsub->interface->dev,
1360                         "comedi_: usbduxfast firmware binary it too large for FX2.\n");
1361                 return -ENOMEM;
1362         }
1363
1364         /* we generate a local buffer for the firmware */
1365         fwBuf = kzalloc(sizeFirmware, GFP_KERNEL);
1366         if (!fwBuf) {
1367                 dev_err(&usbduxfastsub->interface->dev,
1368                         "comedi_: mem alloc for firmware failed\n");
1369                 return -ENOMEM;
1370         }
1371         memcpy(fwBuf, firmwareBinary, sizeFirmware);
1372
1373         ret = usbduxfastsub_stop(usbduxfastsub);
1374         if (ret < 0) {
1375                 dev_err(&usbduxfastsub->interface->dev,
1376                         "comedi_: can not stop firmware\n");
1377                 kfree(fwBuf);
1378                 return ret;
1379         }
1380
1381         ret = usbduxfastsub_upload(usbduxfastsub, fwBuf, 0, sizeFirmware);
1382         if (ret < 0) {
1383                 dev_err(&usbduxfastsub->interface->dev,
1384                         "comedi_: firmware upload failed\n");
1385                 kfree(fwBuf);
1386                 return ret;
1387         }
1388         ret = usbduxfastsub_start(usbduxfastsub);
1389         if (ret < 0) {
1390                 dev_err(&usbduxfastsub->interface->dev,
1391                         "comedi_: can not start firmware\n");
1392                 kfree(fwBuf);
1393                 return ret;
1394         }
1395         kfree(fwBuf);
1396         return 0;
1397 }
1398
1399 static void tidy_up(struct usbduxfastsub_s *udfs)
1400 {
1401 #ifdef CONFIG_COMEDI_DEBUG
1402         printk(KERN_DEBUG "comedi_: usbduxfast: tiding up\n");
1403 #endif
1404
1405         if (!udfs)
1406                 return;
1407
1408         /* shows the usb subsystem that the driver is down */
1409         if (udfs->interface)
1410                 usb_set_intfdata(udfs->interface, NULL);
1411
1412         udfs->probed = 0;
1413
1414         if (udfs->urbIn) {
1415                 /* waits until a running transfer is over */
1416                 usb_kill_urb(udfs->urbIn);
1417
1418                 kfree(udfs->transfer_buffer);
1419                 udfs->transfer_buffer = NULL;
1420
1421                 usb_free_urb(udfs->urbIn);
1422                 udfs->urbIn = NULL;
1423         }
1424
1425         kfree(udfs->insnBuffer);
1426         udfs->insnBuffer = NULL;
1427
1428         kfree(udfs->dux_commands);
1429         udfs->dux_commands = NULL;
1430
1431         udfs->ai_cmd_running = 0;
1432 }
1433
1434 static void usbduxfast_firmware_request_complete_handler(const struct firmware
1435                                                          *fw, void *context)
1436 {
1437         struct usbduxfastsub_s *usbduxfastsub_tmp = context;
1438         struct usb_device *usbdev = usbduxfastsub_tmp->usbdev;
1439         int ret;
1440
1441         if (fw == NULL)
1442                 return;
1443
1444         /*
1445          * we need to upload the firmware here because fw will be
1446          * freed once we've left this function
1447          */
1448         ret = firmwareUpload(usbduxfastsub_tmp, fw->data, fw->size);
1449
1450         if (ret) {
1451                 dev_err(&usbdev->dev,
1452                         "Could not upload firmware (err=%d)\n", ret);
1453                 goto out;
1454         }
1455
1456         comedi_usb_auto_config(usbdev, BOARDNAME);
1457  out:
1458         release_firmware(fw);
1459 }
1460
1461 /*
1462  * allocate memory for the urbs and initialise them
1463  */
1464 static int usbduxfastsub_probe(struct usb_interface *uinterf,
1465                                const struct usb_device_id *id)
1466 {
1467         struct usb_device *udev = interface_to_usbdev(uinterf);
1468         int i;
1469         int index;
1470         int ret;
1471
1472         if (udev->speed != USB_SPEED_HIGH) {
1473                 printk(KERN_ERR "comedi_: usbduxfast_: This driver needs"
1474                        "USB 2.0 to operate. Aborting...\n");
1475                 return -ENODEV;
1476         }
1477 #ifdef CONFIG_COMEDI_DEBUG
1478         printk(KERN_DEBUG "comedi_: usbduxfast_: finding a free structure for "
1479                "the usb-device\n");
1480 #endif
1481         down(&start_stop_sem);
1482         /* look for a free place in the usbduxfast array */
1483         index = -1;
1484         for (i = 0; i < NUMUSBDUXFAST; i++) {
1485                 if (!usbduxfastsub[i].probed) {
1486                         index = i;
1487                         break;
1488                 }
1489         }
1490
1491         /* no more space */
1492         if (index == -1) {
1493                 printk(KERN_ERR "Too many usbduxfast-devices connected.\n");
1494                 up(&start_stop_sem);
1495                 return -EMFILE;
1496         }
1497 #ifdef CONFIG_COMEDI_DEBUG
1498         printk(KERN_DEBUG "comedi_: usbduxfast: usbduxfastsub[%d] is ready to "
1499                "connect to comedi.\n", index);
1500 #endif
1501
1502         init_MUTEX(&(usbduxfastsub[index].sem));
1503         /* save a pointer to the usb device */
1504         usbduxfastsub[index].usbdev = udev;
1505
1506         /* save the interface itself */
1507         usbduxfastsub[index].interface = uinterf;
1508         /* get the interface number from the interface */
1509         usbduxfastsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
1510         /*
1511          * hand the private data over to the usb subsystem
1512          * will be needed for disconnect
1513          */
1514         usb_set_intfdata(uinterf, &(usbduxfastsub[index]));
1515
1516 #ifdef CONFIG_COMEDI_DEBUG
1517         printk(KERN_DEBUG "comedi_: usbduxfast: ifnum=%d\n",
1518                usbduxfastsub[index].ifnum);
1519 #endif
1520         /* create space for the commands going to the usb device */
1521         usbduxfastsub[index].dux_commands = kmalloc(SIZEOFDUXBUFFER,
1522                                                     GFP_KERNEL);
1523         if (!usbduxfastsub[index].dux_commands) {
1524                 printk(KERN_ERR "comedi_: usbduxfast: error alloc space for "
1525                        "dac commands\n");
1526                 tidy_up(&(usbduxfastsub[index]));
1527                 up(&start_stop_sem);
1528                 return -ENOMEM;
1529         }
1530         /* create space of the instruction buffer */
1531         usbduxfastsub[index].insnBuffer = kmalloc(SIZEINSNBUF, GFP_KERNEL);
1532         if (!usbduxfastsub[index].insnBuffer) {
1533                 printk(KERN_ERR "comedi_: usbduxfast: could not alloc space "
1534                        "for insnBuffer\n");
1535                 tidy_up(&(usbduxfastsub[index]));
1536                 up(&start_stop_sem);
1537                 return -ENOMEM;
1538         }
1539         /* setting to alternate setting 1: enabling bulk ep */
1540         i = usb_set_interface(usbduxfastsub[index].usbdev,
1541                               usbduxfastsub[index].ifnum, 1);
1542         if (i < 0) {
1543                 printk(KERN_ERR "comedi_: usbduxfast%d: could not switch to "
1544                        "alternate setting 1.\n", index);
1545                 tidy_up(&(usbduxfastsub[index]));
1546                 up(&start_stop_sem);
1547                 return -ENODEV;
1548         }
1549         usbduxfastsub[index].urbIn = usb_alloc_urb(0, GFP_KERNEL);
1550         if (!usbduxfastsub[index].urbIn) {
1551                 printk(KERN_ERR "comedi_: usbduxfast%d: Could not alloc."
1552                        "urb\n", index);
1553                 tidy_up(&(usbduxfastsub[index]));
1554                 up(&start_stop_sem);
1555                 return -ENOMEM;
1556         }
1557         usbduxfastsub[index].transfer_buffer = kmalloc(SIZEINBUF, GFP_KERNEL);
1558         if (!usbduxfastsub[index].transfer_buffer) {
1559                 printk(KERN_ERR "comedi_: usbduxfast%d: could not alloc. "
1560                        "transb.\n", index);
1561                 tidy_up(&(usbduxfastsub[index]));
1562                 up(&start_stop_sem);
1563                 return -ENOMEM;
1564         }
1565         /* we've reached the bottom of the function */
1566         usbduxfastsub[index].probed = 1;
1567         up(&start_stop_sem);
1568
1569         ret = request_firmware_nowait(THIS_MODULE,
1570                                       FW_ACTION_HOTPLUG,
1571                                       "usbduxfast_firmware.bin",
1572                                       &udev->dev,
1573                                       GFP_KERNEL,
1574                                       usbduxfastsub + index,
1575                                       usbduxfast_firmware_request_complete_handler);
1576
1577         if (ret) {
1578                 dev_err(&udev->dev, "could not load firmware (err=%d)\n", ret);
1579                 return ret;
1580         }
1581
1582         printk(KERN_INFO "comedi_: usbduxfast%d has been successfully "
1583                "initialized.\n", index);
1584         /* success */
1585         return 0;
1586 }
1587
1588 static void usbduxfastsub_disconnect(struct usb_interface *intf)
1589 {
1590         struct usbduxfastsub_s *udfs = usb_get_intfdata(intf);
1591         struct usb_device *udev = interface_to_usbdev(intf);
1592
1593         if (!udfs) {
1594                 printk(KERN_ERR "comedi_: usbduxfast: disconnect called with "
1595                        "null pointer.\n");
1596                 return;
1597         }
1598         if (udfs->usbdev != udev) {
1599                 printk(KERN_ERR "comedi_: usbduxfast: BUG! called with wrong "
1600                        "ptr!!!\n");
1601                 return;
1602         }
1603
1604         comedi_usb_auto_unconfig(udev);
1605
1606         down(&start_stop_sem);
1607         down(&udfs->sem);
1608         tidy_up(udfs);
1609         up(&udfs->sem);
1610         up(&start_stop_sem);
1611
1612 #ifdef CONFIG_COMEDI_DEBUG
1613         printk(KERN_DEBUG "comedi_: usbduxfast: disconnected from the usb\n");
1614 #endif
1615 }
1616
1617 /*
1618  * is called when comedi-config is called
1619  */
1620 static int usbduxfast_attach(struct comedi_device *dev,
1621                              struct comedi_devconfig *it)
1622 {
1623         int ret;
1624         int index;
1625         int i;
1626         struct comedi_subdevice *s = NULL;
1627         dev->private = NULL;
1628
1629         down(&start_stop_sem);
1630         /*
1631          * find a valid device which has been detected by the
1632          * probe function of the usb
1633          */
1634         index = -1;
1635         for (i = 0; i < NUMUSBDUXFAST; i++) {
1636                 if (usbduxfastsub[i].probed && !usbduxfastsub[i].attached) {
1637                         index = i;
1638                         break;
1639                 }
1640         }
1641
1642         if (index < 0) {
1643                 printk(KERN_ERR "comedi%d: usbduxfast: error: attach failed, "
1644                        "no usbduxfast devs connected to the usb bus.\n",
1645                        dev->minor);
1646                 up(&start_stop_sem);
1647                 return -ENODEV;
1648         }
1649
1650         down(&(usbduxfastsub[index].sem));
1651         /* pointer back to the corresponding comedi device */
1652         usbduxfastsub[index].comedidev = dev;
1653
1654         /* trying to upload the firmware into the chip */
1655         if (comedi_aux_data(it->options, 0) &&
1656             it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
1657                 firmwareUpload(&usbduxfastsub[index],
1658                                comedi_aux_data(it->options, 0),
1659                                it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
1660         }
1661
1662         dev->board_name = BOARDNAME;
1663
1664         /* set number of subdevices */
1665         dev->n_subdevices = N_SUBDEVICES;
1666
1667         /* allocate space for the subdevices */
1668         ret = alloc_subdevices(dev, N_SUBDEVICES);
1669         if (ret < 0) {
1670                 printk(KERN_ERR "comedi%d: usbduxfast: error alloc space for "
1671                        "subdev\n", dev->minor);
1672                 up(&(usbduxfastsub[index].sem));
1673                 up(&start_stop_sem);
1674                 return ret;
1675         }
1676
1677         printk(KERN_INFO "comedi%d: usbduxfast: usb-device %d is attached to "
1678                "comedi.\n", dev->minor, index);
1679         /* private structure is also simply the usb-structure */
1680         dev->private = usbduxfastsub + index;
1681         /* the first subdevice is the A/D converter */
1682         s = dev->subdevices + SUBDEV_AD;
1683         /*
1684          * the URBs get the comedi subdevice which is responsible for reading
1685          * this is the subdevice which reads data
1686          */
1687         dev->read_subdev = s;
1688         /* the subdevice receives as private structure the usb-structure */
1689         s->private = NULL;
1690         /* analog input */
1691         s->type = COMEDI_SUBD_AI;
1692         /* readable and ref is to ground */
1693         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
1694         /* 16 channels */
1695         s->n_chan = 16;
1696         /* length of the channellist */
1697         s->len_chanlist = 16;
1698         /* callback functions */
1699         s->insn_read = usbduxfast_ai_insn_read;
1700         s->do_cmdtest = usbduxfast_ai_cmdtest;
1701         s->do_cmd = usbduxfast_ai_cmd;
1702         s->cancel = usbduxfast_ai_cancel;
1703         /* max value from the A/D converter (12bit+1 bit for overflow) */
1704         s->maxdata = 0x1000;
1705         /* range table to convert to physical units */
1706         s->range_table = &range_usbduxfast_ai_range;
1707
1708         /* finally decide that it's attached */
1709         usbduxfastsub[index].attached = 1;
1710
1711         up(&(usbduxfastsub[index].sem));
1712         up(&start_stop_sem);
1713         printk(KERN_INFO "comedi%d: successfully attached to usbduxfast.\n",
1714                dev->minor);
1715
1716         return 0;
1717 }
1718
1719 static int usbduxfast_detach(struct comedi_device *dev)
1720 {
1721         struct usbduxfastsub_s *udfs;
1722
1723         if (!dev) {
1724                 printk(KERN_ERR "comedi?: usbduxfast: detach without dev "
1725                        "variable...\n");
1726                 return -EFAULT;
1727         }
1728 #ifdef CONFIG_COMEDI_DEBUG
1729         printk(KERN_DEBUG "comedi%d: usbduxfast: detach usb device\n",
1730                dev->minor);
1731 #endif
1732
1733         udfs = dev->private;
1734         if (!udfs) {
1735                 printk(KERN_ERR "comedi?: usbduxfast: detach without ptr to "
1736                        "usbduxfastsub[]\n");
1737                 return -EFAULT;
1738         }
1739
1740         down(&udfs->sem);
1741         down(&start_stop_sem);
1742         /*
1743          * Don't allow detach to free the private structure
1744          * It's one entry of of usbduxfastsub[]
1745          */
1746         dev->private = NULL;
1747         udfs->attached = 0;
1748         udfs->comedidev = NULL;
1749 #ifdef CONFIG_COMEDI_DEBUG
1750         printk(KERN_DEBUG "comedi%d: usbduxfast: detach: successfully "
1751                "removed\n", dev->minor);
1752 #endif
1753         up(&start_stop_sem);
1754         up(&udfs->sem);
1755         return 0;
1756 }
1757
1758 /*
1759  * main driver struct
1760  */
1761 static struct comedi_driver driver_usbduxfast = {
1762         .driver_name = "usbduxfast",
1763         .module = THIS_MODULE,
1764         .attach = usbduxfast_attach,
1765         .detach = usbduxfast_detach
1766 };
1767
1768 /*
1769  * Table with the USB-devices: just now only testing IDs
1770  */
1771 static const struct usb_device_id usbduxfastsub_table[] = {
1772         /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
1773         {USB_DEVICE(0x13d8, 0x0010)},   /* real ID */
1774         {USB_DEVICE(0x13d8, 0x0011)},   /* real ID */
1775         {}                      /* Terminating entry */
1776 };
1777
1778 MODULE_DEVICE_TABLE(usb, usbduxfastsub_table);
1779
1780 /*
1781  * The usbduxfastsub-driver
1782  */
1783 static struct usb_driver usbduxfastsub_driver = {
1784 #ifdef COMEDI_HAVE_USB_DRIVER_OWNER
1785         .owner = THIS_MODULE,
1786 #endif
1787         .name = BOARDNAME,
1788         .probe = usbduxfastsub_probe,
1789         .disconnect = usbduxfastsub_disconnect,
1790         .id_table = usbduxfastsub_table
1791 };
1792
1793 /*
1794  * Can't use the nice macro as I have also to initialise the USB subsystem:
1795  * registering the usb-system _and_ the comedi-driver
1796  */
1797 static int __init init_usbduxfast(void)
1798 {
1799         printk(KERN_INFO
1800                KBUILD_MODNAME ": " DRIVER_VERSION ":" DRIVER_DESC "\n");
1801         usb_register(&usbduxfastsub_driver);
1802         comedi_driver_register(&driver_usbduxfast);
1803         return 0;
1804 }
1805
1806 /*
1807  * deregistering the comedi driver and the usb-subsystem
1808  */
1809 static void __exit exit_usbduxfast(void)
1810 {
1811         comedi_driver_unregister(&driver_usbduxfast);
1812         usb_deregister(&usbduxfastsub_driver);
1813 }
1814
1815 module_init(init_usbduxfast);
1816 module_exit(exit_usbduxfast);
1817
1818 MODULE_AUTHOR(DRIVER_AUTHOR);
1819 MODULE_DESCRIPTION(DRIVER_DESC);
1820 MODULE_LICENSE("GPL");