]> Pileus Git - ~andy/linux/blob - drivers/staging/comedi/drivers/usbduxsigma.c
staging: comedi: usbduxsigma: remove a space before tab
[~andy/linux] / drivers / staging / comedi / drivers / usbduxsigma.c
1 /*
2    comedi/drivers/usbdux.c
3    Copyright (C) 2011 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: usbduxsigma
17 Description: University of Stirling USB DAQ & INCITE Technology Limited
18 Devices: [ITL] USB-DUX (usbduxsigma.o)
19 Author: Bernd Porr <BerndPorr@f2s.com>
20 Updated: 8 Nov 2011
21 Status: testing
22 */
23 /*
24  * I must give credit here to Chris Baugher who
25  * wrote the driver for AT-MIO-16d. I used some parts of this
26  * driver. I also must give credits to David Brownell
27  * who supported me with the USB development.
28  *
29  * Note: the raw data from the A/D converter is 24 bit big endian
30  * anything else is little endian to/from the dux board
31  *
32  *
33  * Revision history:
34  *   0.1: initial version
35  *   0.2: all basic functions implemented, digital I/O only for one port
36  *   0.3: proper vendor ID and driver name
37  *   0.4: fixed D/A voltage range
38  *   0.5: various bug fixes, health check at startup
39  *   0.6: corrected wrong input range
40  */
41
42 #include <linux/kernel.h>
43 #include <linux/module.h>
44 #include <linux/init.h>
45 #include <linux/slab.h>
46 #include <linux/input.h>
47 #include <linux/usb.h>
48 #include <linux/fcntl.h>
49 #include <linux/compiler.h>
50
51 #include "comedi_fc.h"
52 #include "../comedidev.h"
53
54 /* timeout for the USB-transfer in ms*/
55 #define BULK_TIMEOUT 1000
56
57 /* constants for "firmware" upload and download */
58 #define FIRMWARE                "usbduxsigma_firmware.bin"
59 #define FIRMWARE_MAX_LEN        0x4000
60 #define USBDUXSUB_FIRMWARE      0xa0
61 #define VENDOR_DIR_IN           0xc0
62 #define VENDOR_DIR_OUT          0x40
63
64 /* internal addresses of the 8051 processor */
65 #define USBDUXSUB_CPUCS 0xE600
66
67 /* USB endpoints */
68 #define USBDUXSIGMA_CMD_OUT_EP          1       /* command output */
69 #define USBDUXSIGMA_ISO_OUT_EP          2       /* analog output ISO/IRQ */
70 #define USBDUXSIGMA_PWM_OUT_EP          4       /* pwm output */
71 #define USBDUXSIGMA_ISO_IN_EP           6       /* analog input ISO/IRQ */
72 #define USBDUXSIGMA_CMD_IN_EP           8       /* command input */
73
74 /* 300Hz max frequ under PWM */
75 #define MIN_PWM_PERIOD  ((long)(1E9/300))
76
77 /* Default PWM frequency */
78 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
79
80 /* Number of channels (16 AD and offset)*/
81 #define NUMCHANNELS 16
82
83 #define USBDUXSIGMA_NUM_AO_CHAN         4
84
85 /* Size of one A/D value */
86 #define SIZEADIN          ((sizeof(int32_t)))
87
88 /*
89  * Size of the async input-buffer IN BYTES, the DIO state is transmitted
90  * as the first byte.
91  */
92 #define SIZEINBUF         (((NUMCHANNELS+1)*SIZEADIN))
93
94 /* 16 bytes. */
95 #define SIZEINSNBUF       16
96
97 /* Number of DA channels */
98 #define NUMOUTCHANNELS    8
99
100 /* size of one value for the D/A converter: channel and value */
101 #define SIZEDAOUT          ((sizeof(uint8_t)+sizeof(int16_t)))
102
103 /*
104  * Size of the output-buffer in bytes
105  * Actually only the first 4 triplets are used but for the
106  * high speed mode we need to pad it to 8 (microframes).
107  */
108 #define SIZEOUTBUF         ((8*SIZEDAOUT))
109
110 /*
111  * Size of the buffer for the dux commands: just now max size is determined
112  * by the analogue out + command byte + panic bytes...
113  */
114 #define SIZEOFDUXBUFFER    ((8*SIZEDAOUT+2))
115
116 /* Number of in-URBs which receive the data: min=2 */
117 #define NUMOFINBUFFERSFULL     5
118
119 /* Number of out-URBs which send the data: min=2 */
120 #define NUMOFOUTBUFFERSFULL    5
121
122 /* Number of in-URBs which receive the data: min=5 */
123 /* must have more buffers due to buggy USB ctr */
124 #define NUMOFINBUFFERSHIGH     10
125
126 /* Number of out-URBs which send the data: min=5 */
127 /* must have more buffers due to buggy USB ctr */
128 #define NUMOFOUTBUFFERSHIGH    10
129
130 /* number of retries to get the right dux command */
131 #define RETRIES 10
132
133 /* bulk transfer commands to usbduxsigma */
134 #define USBBUXSIGMA_AD_CMD              0
135 #define USBDUXSIGMA_DA_CMD              1
136 #define USBDUXSIGMA_DIO_CFG_CMD         2
137 #define USBDUXSIGMA_DIO_BITS_CMD        3
138 #define USBDUXSIGMA_SINGLE_AD_CMD       4
139 #define USBDUXSIGMA_PWM_ON_CMD          7
140 #define USBDUXSIGMA_PWM_OFF_CMD         8
141
142 static const struct comedi_lrange usbduxsigma_ai_range = {
143         1, {
144                 BIP_RANGE(2.65 / 2.0)
145         }
146 };
147
148 struct usbduxsigma_private {
149         /* actual number of in-buffers */
150         int n_ai_urbs;
151         /* actual number of out-buffers */
152         int n_ao_urbs;
153         /* ISO-transfer handling: buffers */
154         struct urb **ai_urbs;
155         struct urb **ao_urbs;
156         /* pwm-transfer handling */
157         struct urb *pwm_urb;
158         /* PWM period */
159         unsigned int pwm_period;
160         /* PWM internal delay for the GPIF in the FX2 */
161         uint8_t pwm_delay;
162         /* size of the PWM buffer which holds the bit pattern */
163         int pwm_buf_sz;
164         /* input buffer for the ISO-transfer */
165         int32_t *in_buf;
166         /* input buffer for single insn */
167         int8_t *insn_buf;
168
169         unsigned int ao_readback[USBDUXSIGMA_NUM_AO_CHAN];
170
171         unsigned high_speed:1;
172         unsigned ai_cmd_running:1;
173         unsigned ai_continuous:1;
174         unsigned ao_cmd_running:1;
175         unsigned ao_continuous:1;
176         unsigned pwm_cmd_running:1;
177
178         /* number of samples to acquire */
179         int ai_sample_count;
180         int ao_sample_count;
181         /* time between samples in units of the timer */
182         unsigned int ai_timer;
183         unsigned int ao_timer;
184         /* counter between acquisitions */
185         unsigned int ai_counter;
186         unsigned int ao_counter;
187         /* interval in frames/uframes */
188         unsigned int ai_interval;
189         /* D/A commands */
190         uint8_t *dac_commands;
191         /* commands */
192         uint8_t *dux_commands;
193         struct semaphore sem;
194 };
195
196 static void usbduxsigma_ai_stop(struct comedi_device *dev, int do_unlink)
197 {
198         struct usbduxsigma_private *devpriv = dev->private;
199
200         if (do_unlink) {
201                 int i;
202
203                 for (i = 0; i < devpriv->n_ai_urbs; i++) {
204                         if (devpriv->ai_urbs[i])
205                                 usb_kill_urb(devpriv->ai_urbs[i]);
206                 }
207         }
208
209         devpriv->ai_cmd_running = 0;
210 }
211
212 static int usbduxsigma_ai_cancel(struct comedi_device *dev,
213                                  struct comedi_subdevice *s)
214 {
215         struct usbduxsigma_private *devpriv = dev->private;
216
217         down(&devpriv->sem);
218         /* unlink only if it is really running */
219         usbduxsigma_ai_stop(dev, devpriv->ai_cmd_running);
220         up(&devpriv->sem);
221
222         return 0;
223 }
224
225 static void usbduxsigma_ai_urb_complete(struct urb *urb)
226 {
227         struct comedi_device *dev = urb->context;
228         struct usbduxsigma_private *devpriv = dev->private;
229         struct comedi_subdevice *s = dev->read_subdev;
230         unsigned int dio_state;
231         int32_t val;
232         int ret;
233         int i;
234
235         /* first we test if something unusual has just happened */
236         switch (urb->status) {
237         case 0:
238                 /* copy the result in the transfer buffer */
239                 memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF);
240                 break;
241         case -EILSEQ:
242                 /*
243                  * error in the ISOchronous data
244                  * we don't copy the data into the transfer buffer
245                  * and recycle the last data byte
246                  */
247                 dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
248
249                 break;
250
251         case -ECONNRESET:
252         case -ENOENT:
253         case -ESHUTDOWN:
254         case -ECONNABORTED:
255                 /* happens after an unlink command */
256                 if (devpriv->ai_cmd_running) {
257                         usbduxsigma_ai_stop(dev, 0);    /* w/o unlink */
258                         /* we are still running a command, tell comedi */
259                         s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
260                         comedi_event(dev, s);
261                 }
262                 return;
263
264         default:
265                 /*
266                  * a real error on the bus
267                  * pass error to comedi if we are really running a command
268                  */
269                 if (devpriv->ai_cmd_running) {
270                         dev_err(dev->class_dev,
271                                 "%s: non-zero urb status (%d)\n",
272                                 __func__, urb->status);
273                         usbduxsigma_ai_stop(dev, 0);    /* w/o unlink */
274                         s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
275                         comedi_event(dev, s);
276                 }
277                 return;
278         }
279
280         if (unlikely(!devpriv->ai_cmd_running))
281                 return;
282
283         urb->dev = comedi_to_usb_dev(dev);
284
285         ret = usb_submit_urb(urb, GFP_ATOMIC);
286         if (unlikely(ret < 0)) {
287                 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
288                         __func__, ret);
289                 if (ret == -EL2NSYNC)
290                         dev_err(dev->class_dev,
291                                 "buggy USB host controller or bug in IRQ handler\n");
292                 usbduxsigma_ai_stop(dev, 0);    /* w/o unlink */
293                 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
294                 comedi_event(dev, s);
295                 return;
296         }
297
298         /* get the state of the dio pins to allow external trigger */
299         dio_state = be32_to_cpu(devpriv->in_buf[0]);
300
301         devpriv->ai_counter--;
302         if (likely(devpriv->ai_counter > 0))
303                 return;
304
305         /* timer zero, transfer measurements to comedi */
306         devpriv->ai_counter = devpriv->ai_timer;
307
308         if (!devpriv->ai_continuous) {
309                 /* not continuous, fixed number of samples */
310                 devpriv->ai_sample_count--;
311                 if (devpriv->ai_sample_count < 0) {
312                         usbduxsigma_ai_stop(dev, 0);    /* w/o unlink */
313                         /* acquistion is over, tell comedi */
314                         s->async->events |= COMEDI_CB_EOA;
315                         comedi_event(dev, s);
316                         return;
317                 }
318         }
319
320         /* get the data from the USB bus and hand it over to comedi */
321         for (i = 0; i < s->async->cmd.chanlist_len; i++) {
322                 /* transfer data, note first byte is the DIO state */
323                 val = be32_to_cpu(devpriv->in_buf[i+1]);
324                 val &= 0x00ffffff;      /* strip status byte */
325                 val ^= 0x00800000;      /* convert to unsigned */
326
327                 ret = cfc_write_array_to_buffer(s, &val, sizeof(uint32_t));
328                 if (unlikely(ret == 0)) {
329                         /* buffer overflow */
330                         usbduxsigma_ai_stop(dev, 0);    /* w/o unlink */
331                         return;
332                 }
333         }
334         /* tell comedi that data is there */
335         s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
336         comedi_event(dev, s);
337 }
338
339 static void usbduxsigma_ao_stop(struct comedi_device *dev, int do_unlink)
340 {
341         struct usbduxsigma_private *devpriv = dev->private;
342
343         if (do_unlink) {
344                 int i;
345
346                 for (i = 0; i < devpriv->n_ao_urbs; i++) {
347                         if (devpriv->ao_urbs[i])
348                                 usb_kill_urb(devpriv->ao_urbs[i]);
349                 }
350         }
351
352         devpriv->ao_cmd_running = 0;
353 }
354
355 static int usbduxsigma_ao_cancel(struct comedi_device *dev,
356                                  struct comedi_subdevice *s)
357 {
358         struct usbduxsigma_private *devpriv = dev->private;
359
360         down(&devpriv->sem);
361         /* unlink only if it is really running */
362         usbduxsigma_ao_stop(dev, devpriv->ao_cmd_running);
363         up(&devpriv->sem);
364
365         return 0;
366 }
367
368 static void usbduxsigma_ao_urb_complete(struct urb *urb)
369 {
370         struct comedi_device *dev = urb->context;
371         struct usbduxsigma_private *devpriv = dev->private;
372         struct comedi_subdevice *s = dev->write_subdev;
373         uint8_t *datap;
374         int len;
375         int ret;
376         int i;
377
378         switch (urb->status) {
379         case 0:
380                 /* success */
381                 break;
382
383         case -ECONNRESET:
384         case -ENOENT:
385         case -ESHUTDOWN:
386         case -ECONNABORTED:
387                 /* happens after an unlink command */
388                 if (devpriv->ao_cmd_running) {
389                         usbduxsigma_ao_stop(dev, 0);    /* w/o unlink */
390                         s->async->events |= COMEDI_CB_EOA;
391                         comedi_event(dev, s);
392                 }
393                 return;
394
395         default:
396                 /* a real error */
397                 if (devpriv->ao_cmd_running) {
398                         dev_err(dev->class_dev,
399                                 "%s: non-zero urb status (%d)\n",
400                                 __func__, urb->status);
401                         usbduxsigma_ao_stop(dev, 0);    /* w/o unlink */
402                         s->async->events |= (COMEDI_CB_ERROR | COMEDI_CB_EOA);
403                         comedi_event(dev, s);
404                 }
405                 return;
406         }
407
408         if (!devpriv->ao_cmd_running)
409                 return;
410
411         devpriv->ao_counter--;
412         if ((int)devpriv->ao_counter <= 0) {
413                 /* timer zero, transfer from comedi */
414                 devpriv->ao_counter = devpriv->ao_timer;
415
416                 if (!devpriv->ao_continuous) {
417                         /* not continuous, fixed number of samples */
418                         devpriv->ao_sample_count--;
419                         if (devpriv->ao_sample_count < 0) {
420                                 usbduxsigma_ao_stop(dev, 0);    /* w/o unlink */
421                                 /* acquistion is over, tell comedi */
422                                 s->async->events |= COMEDI_CB_EOA;
423                                 comedi_event(dev, s);
424                                 return;
425                         }
426                 }
427
428                 /* transmit data to the USB bus */
429                 datap = urb->transfer_buffer;
430                 len = s->async->cmd.chanlist_len;
431                 *datap++ = len;
432                 for (i = 0; i < len; i++) {
433                         unsigned int chan = devpriv->dac_commands[i];
434                         short val;
435
436                         ret = comedi_buf_get(s->async, &val);
437                         if (ret < 0) {
438                                 dev_err(dev->class_dev, "buffer underflow\n");
439                                 s->async->events |= (COMEDI_CB_EOA |
440                                                      COMEDI_CB_OVERFLOW);
441                         }
442                         *datap++ = val;
443                         *datap++ = chan;
444                         devpriv->ao_readback[chan] = val;
445
446                         s->async->events |= COMEDI_CB_BLOCK;
447                         comedi_event(dev, s);
448                 }
449         }
450
451         urb->transfer_buffer_length = SIZEOUTBUF;
452         urb->dev = comedi_to_usb_dev(dev);
453         urb->status = 0;
454         if (devpriv->high_speed)
455                 urb->interval = 8;      /* uframes */
456         else
457                 urb->interval = 1;      /* frames */
458         urb->number_of_packets = 1;
459         urb->iso_frame_desc[0].offset = 0;
460         urb->iso_frame_desc[0].length = SIZEOUTBUF;
461         urb->iso_frame_desc[0].status = 0;
462         ret = usb_submit_urb(urb, GFP_ATOMIC);
463         if (ret < 0) {
464                 dev_err(dev->class_dev,
465                         "%s: urb resubmit failed (%d)\n",
466                         __func__, ret);
467                 if (ret == EL2NSYNC)
468                         dev_err(dev->class_dev,
469                                 "buggy USB host controller or bug in IRQ handler\n");
470                 usbduxsigma_ao_stop(dev, 0);    /* w/o unlink */
471                 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
472                 comedi_event(dev, s);
473         }
474 }
475
476 static int usbduxsigma_submit_urbs(struct comedi_device *dev,
477                                    struct urb **urbs, int num_urbs,
478                                    int input_urb)
479 {
480         struct usb_device *usb = comedi_to_usb_dev(dev);
481         struct usbduxsigma_private *devpriv = dev->private;
482         struct urb *urb;
483         int ret;
484         int i;
485
486         /* Submit all URBs and start the transfer on the bus */
487         for (i = 0; i < num_urbs; i++) {
488                 urb = urbs[i];
489
490                 /* in case of a resubmission after an unlink... */
491                 if (input_urb)
492                         urb->interval = devpriv->ai_interval;
493                 urb->context = dev;
494                 urb->dev = usb;
495                 urb->status = 0;
496                 urb->transfer_flags = URB_ISO_ASAP;
497
498                 ret = usb_submit_urb(urb, GFP_ATOMIC);
499                 if (ret)
500                         return ret;
501         }
502         return 0;
503 }
504
505 static int usbduxsigma_chans_to_interval(int num_chan)
506 {
507         if (num_chan <= 2)
508                 return 2;       /* 4kHz */
509         if (num_chan <= 8)
510                 return 4;       /* 2kHz */
511         return 8;               /* 1kHz */
512 }
513
514 static int usbduxsigma_ai_cmdtest(struct comedi_device *dev,
515                                   struct comedi_subdevice *s,
516                                   struct comedi_cmd *cmd)
517 {
518         struct usbduxsigma_private *devpriv = dev->private;
519         int high_speed = devpriv->high_speed;
520         int interval = usbduxsigma_chans_to_interval(cmd->chanlist_len);
521         int err = 0;
522
523         /* Step 1 : check if triggers are trivially valid */
524
525         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
526         err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
527         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
528         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
529         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
530
531         if (err)
532                 return 1;
533
534         /* Step 2a : make sure trigger sources are unique */
535
536         err |= cfc_check_trigger_is_unique(cmd->start_src);
537         err |= cfc_check_trigger_is_unique(cmd->stop_src);
538
539         /* Step 2b : and mutually compatible */
540
541         if (err)
542                 return 2;
543
544         /* Step 3: check if arguments are trivially valid */
545
546         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
547
548         if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
549                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
550
551         if (cmd->scan_begin_src == TRIG_TIMER) {
552                 unsigned int tmp;
553
554                 if (high_speed) {
555                         /*
556                          * In high speed mode microframes are possible.
557                          * However, during one microframe we can roughly
558                          * sample two channels. Thus, the more channels
559                          * are in the channel list the more time we need.
560                          */
561                         err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
562                                                 (1000000 / 8 * interval));
563
564                         tmp = (cmd->scan_begin_arg / 125000) * 125000;
565                 } else {
566                         /* full speed */
567                         /* 1kHz scans every USB frame */
568                         err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
569                                                          1000000);
570
571                         tmp = (cmd->scan_begin_arg / 1000000) * 1000000;
572                 }
573                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, tmp);
574         }
575
576         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
577
578         if (cmd->stop_src == TRIG_COUNT) {
579                 /* any count is allowed */
580         } else {
581                 /* TRIG_NONE */
582                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
583         }
584
585         if (err)
586                 return 3;
587
588         /* Step 4: fix up any arguments */
589
590         if (high_speed) {
591                 /*
592                  * every 2 channels get a time window of 125us. Thus, if we
593                  * sample all 16 channels we need 1ms. If we sample only one
594                  * channel we need only 125us
595                  */
596                 devpriv->ai_interval = interval;
597                 devpriv->ai_timer = cmd->scan_begin_arg / (125000 * interval);
598         } else {
599                 /* interval always 1ms */
600                 devpriv->ai_interval = 1;
601                 devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
602         }
603         if (devpriv->ai_timer < 1)
604                 err |= -EINVAL;
605
606         if (cmd->stop_src == TRIG_COUNT) {
607                 /* data arrives as one packet */
608                 devpriv->ai_sample_count = cmd->stop_arg;
609                 devpriv->ai_continuous = 0;
610         } else {
611                 /* continuous acquisition */
612                 devpriv->ai_continuous = 1;
613                 devpriv->ai_sample_count = 0;
614         }
615
616         if (err)
617                 return 4;
618
619         return 0;
620 }
621
622 /*
623  * creates the ADC command for the MAX1271
624  * range is the range value from comedi
625  */
626 static void create_adc_command(unsigned int chan,
627                                uint8_t *muxsg0,
628                                uint8_t *muxsg1)
629 {
630         if (chan < 8)
631                 (*muxsg0) = (*muxsg0) | (1 << chan);
632         else if (chan < 16)
633                 (*muxsg1) = (*muxsg1) | (1 << (chan-8));
634 }
635
636 static int usbbuxsigma_send_cmd(struct comedi_device *dev, int cmd_type)
637 {
638         struct usb_device *usb = comedi_to_usb_dev(dev);
639         struct usbduxsigma_private *devpriv = dev->private;
640         int nsent;
641
642         devpriv->dux_commands[0] = cmd_type;
643
644         return usb_bulk_msg(usb, usb_sndbulkpipe(usb, USBDUXSIGMA_CMD_OUT_EP),
645                             devpriv->dux_commands, SIZEOFDUXBUFFER,
646                             &nsent, BULK_TIMEOUT);
647 }
648
649 static int usbduxsigma_receive_cmd(struct comedi_device *dev, int command)
650 {
651         struct usb_device *usb = comedi_to_usb_dev(dev);
652         struct usbduxsigma_private *devpriv = dev->private;
653         int nrec;
654         int ret;
655         int i;
656
657         for (i = 0; i < RETRIES; i++) {
658                 ret = usb_bulk_msg(usb,
659                                    usb_rcvbulkpipe(usb, USBDUXSIGMA_CMD_IN_EP),
660                                    devpriv->insn_buf, SIZEINSNBUF,
661                                    &nrec, BULK_TIMEOUT);
662                 if (ret < 0)
663                         return ret;
664
665                 if (devpriv->insn_buf[0] == command)
666                         return 0;
667         }
668         /*
669          * This is only reached if the data has been requested a
670          * couple of times and the command was not received.
671          */
672         return -EFAULT;
673 }
674
675 static int usbduxsigma_ai_inttrig(struct comedi_device *dev,
676                                   struct comedi_subdevice *s,
677                                   unsigned int trignum)
678 {
679         struct usbduxsigma_private *devpriv = dev->private;
680         int ret;
681
682         if (trignum != 0)
683                 return -EINVAL;
684
685         down(&devpriv->sem);
686         if (!devpriv->ai_cmd_running) {
687                 ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
688                                               devpriv->n_ai_urbs, 1);
689                 if (ret < 0) {
690                         up(&devpriv->sem);
691                         return ret;
692                 }
693                 devpriv->ai_cmd_running = 1;
694                 s->async->inttrig = NULL;
695         }
696         up(&devpriv->sem);
697
698         return 1;
699 }
700
701 static int usbduxsigma_ai_cmd(struct comedi_device *dev,
702                               struct comedi_subdevice *s)
703 {
704         struct usbduxsigma_private *devpriv = dev->private;
705         struct comedi_cmd *cmd = &s->async->cmd;
706         unsigned int len = cmd->chanlist_len;
707         uint8_t muxsg0 = 0;
708         uint8_t muxsg1 = 0;
709         uint8_t sysred = 0;
710         int ret;
711         int i;
712
713         down(&devpriv->sem);
714
715         /* set current channel of the running acquisition to zero */
716         s->async->cur_chan = 0;
717         for (i = 0; i < len; i++) {
718                 unsigned int chan  = CR_CHAN(cmd->chanlist[i]);
719
720                 create_adc_command(chan, &muxsg0, &muxsg1);
721         }
722
723         devpriv->dux_commands[1] = len;  /* num channels per time step */
724         devpriv->dux_commands[2] = 0x12; /* CONFIG0 */
725         devpriv->dux_commands[3] = 0x03; /* CONFIG1: 23kHz sample, delay 0us */
726         devpriv->dux_commands[4] = 0x00; /* CONFIG3: diff. channels off */
727         devpriv->dux_commands[5] = muxsg0;
728         devpriv->dux_commands[6] = muxsg1;
729         devpriv->dux_commands[7] = sysred;
730
731         ret = usbbuxsigma_send_cmd(dev, USBBUXSIGMA_AD_CMD);
732         if (ret < 0) {
733                 up(&devpriv->sem);
734                 return ret;
735         }
736
737         devpriv->ai_counter = devpriv->ai_timer;
738
739         if (cmd->start_src == TRIG_NOW) {
740                 /* enable this acquisition operation */
741                 ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
742                                               devpriv->n_ai_urbs, 1);
743                 if (ret < 0) {
744                         up(&devpriv->sem);
745                         return ret;
746                 }
747                 s->async->inttrig = NULL;
748                 devpriv->ai_cmd_running = 1;
749         } else {        /* TRIG_INT */
750                 /* wait for an internal signal and submit the urbs later */
751                 s->async->inttrig = usbduxsigma_ai_inttrig;
752         }
753
754         up(&devpriv->sem);
755
756         return 0;
757 }
758
759 static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
760                                     struct comedi_subdevice *s,
761                                     struct comedi_insn *insn,
762                                     unsigned int *data)
763 {
764         struct usbduxsigma_private *devpriv = dev->private;
765         unsigned int chan = CR_CHAN(insn->chanspec);
766         uint8_t muxsg0 = 0;
767         uint8_t muxsg1 = 0;
768         uint8_t sysred = 0;
769         int ret;
770         int i;
771
772         down(&devpriv->sem);
773         if (devpriv->ai_cmd_running) {
774                 up(&devpriv->sem);
775                 return -EBUSY;
776         }
777
778         create_adc_command(chan, &muxsg0, &muxsg1);
779
780         /* Mode 0 is used to get a single conversion on demand */
781         devpriv->dux_commands[1] = 0x16; /* CONFIG0: chopper on */
782         devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
783         devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
784         devpriv->dux_commands[4] = muxsg0;
785         devpriv->dux_commands[5] = muxsg1;
786         devpriv->dux_commands[6] = sysred;
787
788         /* adc commands */
789         ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
790         if (ret < 0) {
791                 up(&devpriv->sem);
792                 return ret;
793         }
794
795         for (i = 0; i < insn->n; i++) {
796                 int32_t val;
797
798                 ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
799                 if (ret < 0) {
800                         up(&devpriv->sem);
801                         return ret;
802                 }
803
804                 /* 32 bits big endian from the A/D converter */
805                 val = be32_to_cpu(*((int32_t *)((devpriv->insn_buf) + 1)));
806                 val &= 0x00ffffff;      /* strip status byte */
807                 val ^= 0x00800000;      /* convert to unsigned */
808
809                 data[i] = val;
810         }
811         up(&devpriv->sem);
812
813         return insn->n;
814 }
815
816 static int usbduxsigma_ao_insn_read(struct comedi_device *dev,
817                                     struct comedi_subdevice *s,
818                                     struct comedi_insn *insn,
819                                     unsigned int *data)
820 {
821         struct usbduxsigma_private *devpriv = dev->private;
822         unsigned int chan = CR_CHAN(insn->chanspec);
823         int i;
824
825         down(&devpriv->sem);
826         for (i = 0; i < insn->n; i++)
827                 data[i] = devpriv->ao_readback[chan];
828         up(&devpriv->sem);
829
830         return insn->n;
831 }
832
833 static int usbduxsigma_ao_insn_write(struct comedi_device *dev,
834                                      struct comedi_subdevice *s,
835                                      struct comedi_insn *insn,
836                                      unsigned int *data)
837 {
838         struct usbduxsigma_private *devpriv = dev->private;
839         unsigned int chan = CR_CHAN(insn->chanspec);
840         int ret;
841         int i;
842
843         down(&devpriv->sem);
844         if (devpriv->ao_cmd_running) {
845                 up(&devpriv->sem);
846                 return -EBUSY;
847         }
848
849         for (i = 0; i < insn->n; i++) {
850                 devpriv->dux_commands[1] = 1;           /* num channels */
851                 devpriv->dux_commands[2] = data[i];     /* value */
852                 devpriv->dux_commands[3] = chan;        /* channel number */
853                 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DA_CMD);
854                 if (ret < 0) {
855                         up(&devpriv->sem);
856                         return ret;
857                 }
858                 devpriv->ao_readback[chan] = data[i];
859         }
860         up(&devpriv->sem);
861
862         return insn->n;
863 }
864
865 static int usbduxsigma_ao_inttrig(struct comedi_device *dev,
866                                   struct comedi_subdevice *s,
867                                   unsigned int trignum)
868 {
869         struct usbduxsigma_private *devpriv = dev->private;
870         int ret;
871
872         if (trignum != 0)
873                 return -EINVAL;
874
875         down(&devpriv->sem);
876         if (!devpriv->ao_cmd_running) {
877                 ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
878                                               devpriv->n_ao_urbs, 0);
879                 if (ret < 0) {
880                         up(&devpriv->sem);
881                         return ret;
882                 }
883                 devpriv->ao_cmd_running = 1;
884                 s->async->inttrig = NULL;
885         }
886         up(&devpriv->sem);
887
888         return 1;
889 }
890
891 static int usbduxsigma_ao_cmdtest(struct comedi_device *dev,
892                                   struct comedi_subdevice *s,
893                                   struct comedi_cmd *cmd)
894 {
895         struct usbduxsigma_private *devpriv = dev->private;
896         int err = 0;
897         int high_speed;
898         unsigned int flags;
899
900         /* high speed conversions are not used yet */
901         high_speed = 0;         /* (devpriv->high_speed) */
902
903         /* Step 1 : check if triggers are trivially valid */
904
905         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
906
907         if (high_speed) {
908                 /*
909                  * start immediately a new scan
910                  * the sampling rate is set by the coversion rate
911                  */
912                 flags = TRIG_FOLLOW;
913         } else {
914                 /* start a new scan (output at once) with a timer */
915                 flags = TRIG_TIMER;
916         }
917         err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
918
919         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
920         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
921         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
922
923         if (err) {
924                 up(&devpriv->sem);
925                 return 1;
926         }
927
928         /* Step 2a : make sure trigger sources are unique */
929
930         err |= cfc_check_trigger_is_unique(cmd->start_src);
931         err |= cfc_check_trigger_is_unique(cmd->stop_src);
932
933         /* Step 2b : and mutually compatible */
934
935         if (err)
936                 return 2;
937
938         /* Step 3: check if arguments are trivially valid */
939
940         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
941
942         if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
943                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
944
945         if (cmd->scan_begin_src == TRIG_TIMER)
946                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
947                                                  1000000);
948
949         /* not used now, is for later use */
950         if (cmd->convert_src == TRIG_TIMER)
951                 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
952
953         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
954
955         if (cmd->stop_src == TRIG_COUNT) {
956                 /* any count is allowed */
957         } else {
958                 /* TRIG_NONE */
959                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
960         }
961
962         if (err)
963                 return 3;
964
965         /* Step 4: fix up any arguments */
966
967         /* we count in timer steps */
968         if (high_speed) {
969                 /* timing of the conversion itself: every 125 us */
970                 devpriv->ao_timer = cmd->convert_arg / 125000;
971         } else {
972                 /*
973                  * timing of the scan: every 1ms
974                  * we get all channels at once
975                  */
976                 devpriv->ao_timer = cmd->scan_begin_arg / 1000000;
977         }
978         if (devpriv->ao_timer < 1)
979                 err |= -EINVAL;
980
981         if (cmd->stop_src == TRIG_COUNT) {
982                 /* not continuous, use counter */
983                 if (high_speed) {
984                         /* high speed also scans everything at once */
985                         devpriv->ao_sample_count = cmd->stop_arg *
986                                                    cmd->scan_end_arg;
987                 } else {
988                         /*
989                          * There's no scan as the scan has been
990                          * handled inside the FX2. Data arrives as
991                          * one packet.
992                          */
993                         devpriv->ao_sample_count = cmd->stop_arg;
994                 }
995                 devpriv->ao_continuous = 0;
996         } else {
997                 /* continuous acquisition */
998                 devpriv->ao_continuous = 1;
999                 devpriv->ao_sample_count = 0;
1000         }
1001
1002         if (err)
1003                 return 4;
1004
1005         return 0;
1006 }
1007
1008 static int usbduxsigma_ao_cmd(struct comedi_device *dev,
1009                               struct comedi_subdevice *s)
1010 {
1011         struct usbduxsigma_private *devpriv = dev->private;
1012         struct comedi_cmd *cmd = &s->async->cmd;
1013         int ret;
1014         int i;
1015
1016         down(&devpriv->sem);
1017
1018         /* set current channel of the running acquisition to zero */
1019         s->async->cur_chan = 0;
1020         for (i = 0; i < cmd->chanlist_len; ++i)
1021                 devpriv->dac_commands[i] = CR_CHAN(cmd->chanlist[i]);
1022
1023         devpriv->ao_counter = devpriv->ao_timer;
1024
1025         if (cmd->start_src == TRIG_NOW) {
1026                 /* enable this acquisition operation */
1027                 ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
1028                                               devpriv->n_ao_urbs, 0);
1029                 if (ret < 0) {
1030                         up(&devpriv->sem);
1031                         return ret;
1032                 }
1033                 s->async->inttrig = NULL;
1034                 devpriv->ao_cmd_running = 1;
1035         } else {        /* TRIG_INT */
1036                 /* wait for an internal signal and submit the urbs later */
1037                 s->async->inttrig = usbduxsigma_ao_inttrig;
1038         }
1039
1040         up(&devpriv->sem);
1041
1042         return 0;
1043 }
1044
1045 static int usbduxsigma_dio_insn_config(struct comedi_device *dev,
1046                                        struct comedi_subdevice *s,
1047                                        struct comedi_insn *insn,
1048                                        unsigned int *data)
1049 {
1050         unsigned int chan = CR_CHAN(insn->chanspec);
1051         unsigned int mask = 1 << chan;
1052
1053         switch (data[0]) {
1054         case INSN_CONFIG_DIO_OUTPUT:
1055                 s->io_bits |= mask;
1056                 break;
1057         case INSN_CONFIG_DIO_INPUT:
1058                 s->io_bits &= ~mask;
1059                 break;
1060         case INSN_CONFIG_DIO_QUERY:
1061                 data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
1062                 break;
1063         default:
1064                 return -EINVAL;
1065                 break;
1066         }
1067
1068         /*
1069          * We don't tell the firmware here as it would take 8 frames
1070          * to submit the information. We do it in the (*insn_bits).
1071          */
1072         return insn->n;
1073 }
1074
1075 static int usbduxsigma_dio_insn_bits(struct comedi_device *dev,
1076                                      struct comedi_subdevice *s,
1077                                      struct comedi_insn *insn,
1078                                      unsigned int *data)
1079 {
1080         struct usbduxsigma_private *devpriv = dev->private;
1081         unsigned int mask = data[0];
1082         unsigned int bits = data[1];
1083         int ret;
1084
1085         down(&devpriv->sem);
1086
1087         s->state &= ~mask;
1088         s->state |= (bits & mask);
1089
1090         devpriv->dux_commands[1] = s->io_bits & 0xff;
1091         devpriv->dux_commands[4] = s->state & 0xff;
1092         devpriv->dux_commands[2] = (s->io_bits >> 8) & 0xff;
1093         devpriv->dux_commands[5] = (s->state >> 8) & 0xff;
1094         devpriv->dux_commands[3] = (s->io_bits >> 16) & 0xff;
1095         devpriv->dux_commands[6] = (s->state >> 16) & 0xff;
1096
1097         ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
1098         if (ret < 0)
1099                 goto done;
1100         ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
1101         if (ret < 0)
1102                 goto done;
1103
1104         s->state = devpriv->insn_buf[1] |
1105                    (devpriv->insn_buf[2] << 8) |
1106                    (devpriv->insn_buf[3] << 16);
1107
1108         data[1] = s->state;
1109         ret = insn->n;
1110
1111 done:
1112         up(&devpriv->sem);
1113
1114         return ret;
1115 }
1116
1117 static void usbduxsigma_pwm_stop(struct comedi_device *dev, int do_unlink)
1118 {
1119         struct usbduxsigma_private *devpriv = dev->private;
1120
1121         if (do_unlink) {
1122                 if (devpriv->pwm_urb)
1123                         usb_kill_urb(devpriv->pwm_urb);
1124         }
1125
1126         devpriv->pwm_cmd_running = 0;
1127 }
1128
1129 static int usbduxsigma_pwm_cancel(struct comedi_device *dev,
1130                                   struct comedi_subdevice *s)
1131 {
1132         struct usbduxsigma_private *devpriv = dev->private;
1133
1134         /* unlink only if it is really running */
1135         usbduxsigma_pwm_stop(dev, devpriv->pwm_cmd_running);
1136
1137         return usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_OFF_CMD);
1138 }
1139
1140 static void usbduxsigma_pwm_urb_complete(struct urb *urb)
1141 {
1142         struct comedi_device *dev = urb->context;
1143         struct usbduxsigma_private *devpriv = dev->private;
1144         int ret;
1145
1146         switch (urb->status) {
1147         case 0:
1148                 /* success */
1149                 break;
1150
1151         case -ECONNRESET:
1152         case -ENOENT:
1153         case -ESHUTDOWN:
1154         case -ECONNABORTED:
1155                 /* happens after an unlink command */
1156                 if (devpriv->pwm_cmd_running)
1157                         usbduxsigma_pwm_stop(dev, 0);   /* w/o unlink */
1158                 return;
1159
1160         default:
1161                 /* a real error */
1162                 if (devpriv->pwm_cmd_running) {
1163                         dev_err(dev->class_dev,
1164                                 "%s: non-zero urb status (%d)\n",
1165                                 __func__, urb->status);
1166                         usbduxsigma_pwm_stop(dev, 0);   /* w/o unlink */
1167                 }
1168                 return;
1169         }
1170
1171         if (!devpriv->pwm_cmd_running)
1172                 return;
1173
1174         urb->transfer_buffer_length = devpriv->pwm_buf_sz;
1175         urb->dev = comedi_to_usb_dev(dev);
1176         urb->status = 0;
1177         ret = usb_submit_urb(urb, GFP_ATOMIC);
1178         if (ret < 0) {
1179                 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
1180                         __func__, ret);
1181                 if (ret == EL2NSYNC)
1182                         dev_err(dev->class_dev,
1183                                 "buggy USB host controller or bug in IRQ handler\n");
1184                 usbduxsigma_pwm_stop(dev, 0);   /* w/o unlink */
1185         }
1186 }
1187
1188 static int usbduxsigma_submit_pwm_urb(struct comedi_device *dev)
1189 {
1190         struct usb_device *usb = comedi_to_usb_dev(dev);
1191         struct usbduxsigma_private *devpriv = dev->private;
1192         struct urb *urb = devpriv->pwm_urb;
1193
1194         /* in case of a resubmission after an unlink... */
1195         usb_fill_bulk_urb(urb,
1196                           usb, usb_sndbulkpipe(usb, USBDUXSIGMA_PWM_OUT_EP),
1197                           urb->transfer_buffer, devpriv->pwm_buf_sz,
1198                           usbduxsigma_pwm_urb_complete, dev);
1199
1200         return usb_submit_urb(urb, GFP_ATOMIC);
1201 }
1202
1203 static int usbduxsigma_pwm_period(struct comedi_device *dev,
1204                                   struct comedi_subdevice *s,
1205                                   unsigned int period)
1206 {
1207         struct usbduxsigma_private *devpriv = dev->private;
1208         int fx2delay = 255;
1209
1210         if (period < MIN_PWM_PERIOD) {
1211                 return -EAGAIN;
1212         } else {
1213                 fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
1214                 if (fx2delay > 255)
1215                         return -EAGAIN;
1216         }
1217         devpriv->pwm_delay = fx2delay;
1218         devpriv->pwm_period = period;
1219         return 0;
1220 }
1221
1222 static int usbduxsigma_pwm_start(struct comedi_device *dev,
1223                                  struct comedi_subdevice *s)
1224 {
1225         struct usbduxsigma_private *devpriv = dev->private;
1226         int ret;
1227
1228         if (devpriv->pwm_cmd_running)
1229                 return 0;
1230
1231         devpriv->dux_commands[1] = devpriv->pwm_delay;
1232         ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_ON_CMD);
1233         if (ret < 0)
1234                 return ret;
1235
1236         memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);
1237
1238         ret = usbduxsigma_submit_pwm_urb(dev);
1239         if (ret < 0)
1240                 return ret;
1241         devpriv->pwm_cmd_running = 1;
1242
1243         return 0;
1244 }
1245
1246 static int usbduxsigma_pwm_pattern(struct comedi_device *dev,
1247                                    struct comedi_subdevice *s,
1248                                    unsigned int chan,
1249                                    unsigned int value,
1250                                    unsigned int sign)
1251 {
1252         struct usbduxsigma_private *devpriv = dev->private;
1253         char pwm_mask = (1 << chan);    /* DIO bit for the PWM data */
1254         char sgn_mask = (16 << chan);   /* DIO bit for the sign */
1255         char *buf = (char *)(devpriv->pwm_urb->transfer_buffer);
1256         int szbuf = devpriv->pwm_buf_sz;
1257         int i;
1258
1259         for (i = 0; i < szbuf; i++) {
1260                 char c = *buf;
1261
1262                 c &= ~pwm_mask;
1263                 if (i < value)
1264                         c |= pwm_mask;
1265                 if (!sign)
1266                         c &= ~sgn_mask;
1267                 else
1268                         c |= sgn_mask;
1269                 *buf++ = c;
1270         }
1271         return 1;
1272 }
1273
1274 static int usbduxsigma_pwm_write(struct comedi_device *dev,
1275                                  struct comedi_subdevice *s,
1276                                  struct comedi_insn *insn,
1277                                  unsigned int *data)
1278 {
1279         unsigned int chan = CR_CHAN(insn->chanspec);
1280
1281         /*
1282          * It doesn't make sense to support more than one value here
1283          * because it would just overwrite the PWM buffer.
1284          */
1285         if (insn->n != 1)
1286                 return -EINVAL;
1287
1288         /*
1289          * The sign is set via a special INSN only, this gives us 8 bits
1290          * for normal operation, sign is 0 by default.
1291          */
1292         return usbduxsigma_pwm_pattern(dev, s, chan, data[0], 0);
1293 }
1294
1295 static int usbduxsigma_pwm_config(struct comedi_device *dev,
1296                                   struct comedi_subdevice *s,
1297                                   struct comedi_insn *insn,
1298                                   unsigned int *data)
1299 {
1300         struct usbduxsigma_private *devpriv = dev->private;
1301         unsigned int chan = CR_CHAN(insn->chanspec);
1302
1303         switch (data[0]) {
1304         case INSN_CONFIG_ARM:
1305                 /*
1306                  * if not zero the PWM is limited to a certain time which is
1307                  * not supported here
1308                  */
1309                 if (data[1] != 0)
1310                         return -EINVAL;
1311                 return usbduxsigma_pwm_start(dev, s);
1312         case INSN_CONFIG_DISARM:
1313                 return usbduxsigma_pwm_cancel(dev, s);
1314         case INSN_CONFIG_GET_PWM_STATUS:
1315                 data[1] = devpriv->pwm_cmd_running;
1316                 return 0;
1317         case INSN_CONFIG_PWM_SET_PERIOD:
1318                 return usbduxsigma_pwm_period(dev, s, data[1]);
1319         case INSN_CONFIG_PWM_GET_PERIOD:
1320                 data[1] = devpriv->pwm_period;
1321                 return 0;
1322         case INSN_CONFIG_PWM_SET_H_BRIDGE:
1323                 /*
1324                  * data[1] = value
1325                  * data[2] = sign (for a relay)
1326                  */
1327                 return usbduxsigma_pwm_pattern(dev, s, chan,
1328                                                data[1], (data[2] != 0));
1329         case INSN_CONFIG_PWM_GET_H_BRIDGE:
1330                 /* values are not kept in this driver, nothing to return */
1331                 return -EINVAL;
1332         }
1333         return -EINVAL;
1334 }
1335
1336 static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan)
1337 {
1338         struct usbduxsigma_private *devpriv = dev->private;
1339         uint8_t sysred;
1340         uint32_t val;
1341         int ret;
1342
1343         switch (chan) {
1344         default:
1345         case 0:
1346                 sysred = 0;             /* ADC zero */
1347                 break;
1348         case 1:
1349                 sysred = 1;             /* ADC offset */
1350                 break;
1351         case 2:
1352                 sysred = 4;             /* VCC */
1353                 break;
1354         case 3:
1355                 sysred = 8;             /* temperature */
1356                 break;
1357         case 4:
1358                 sysred = 16;            /* gain */
1359                 break;
1360         case 5:
1361                 sysred =  32;           /* ref */
1362                 break;
1363         }
1364
1365         devpriv->dux_commands[1] = 0x12; /* CONFIG0 */
1366         devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
1367         devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
1368         devpriv->dux_commands[4] = 0;
1369         devpriv->dux_commands[5] = 0;
1370         devpriv->dux_commands[6] = sysred;
1371         ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
1372         if (ret < 0)
1373                 return ret;
1374
1375         ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
1376         if (ret < 0)
1377                 return ret;
1378
1379         /* 32 bits big endian from the A/D converter */
1380         val = be32_to_cpu(*((int32_t *)((devpriv->insn_buf)+1)));
1381         val &= 0x00ffffff;      /* strip status byte */
1382         val ^= 0x00800000;      /* convert to unsigned */
1383
1384         return (int)val;
1385 }
1386
1387 static int usbduxsigma_attach_common(struct comedi_device *dev)
1388 {
1389         struct usbduxsigma_private *devpriv = dev->private;
1390         struct comedi_subdevice *s;
1391         int n_subdevs;
1392         int offset;
1393         int ret;
1394
1395         down(&devpriv->sem);
1396
1397         if (devpriv->high_speed)
1398                 n_subdevs = 4;  /* with pwm */
1399         else
1400                 n_subdevs = 3;  /* without pwm */
1401         ret = comedi_alloc_subdevices(dev, n_subdevs);
1402         if (ret) {
1403                 up(&devpriv->sem);
1404                 return ret;
1405         }
1406
1407         /* Analog Input subdevice */
1408         s = &dev->subdevices[0];
1409         dev->read_subdev = s;
1410         s->type         = COMEDI_SUBD_AI;
1411         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ | SDF_LSAMPL;
1412         s->n_chan       = NUMCHANNELS;
1413         s->len_chanlist = NUMCHANNELS;
1414         s->maxdata      = 0x00ffffff;
1415         s->range_table  = &usbduxsigma_ai_range;
1416         s->insn_read    = usbduxsigma_ai_insn_read;
1417         s->do_cmdtest   = usbduxsigma_ai_cmdtest;
1418         s->do_cmd       = usbduxsigma_ai_cmd;
1419         s->cancel       = usbduxsigma_ai_cancel;
1420
1421         /* Analog Output subdevice */
1422         s = &dev->subdevices[1];
1423         dev->write_subdev = s;
1424         s->type         = COMEDI_SUBD_AO;
1425         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1426         s->n_chan       = USBDUXSIGMA_NUM_AO_CHAN;
1427         s->len_chanlist = s->n_chan;
1428         s->maxdata      = 0x00ff;
1429         s->range_table  = &range_unipolar2_5;
1430         s->insn_write   = usbduxsigma_ao_insn_write;
1431         s->insn_read    = usbduxsigma_ao_insn_read;
1432         s->do_cmdtest   = usbduxsigma_ao_cmdtest;
1433         s->do_cmd       = usbduxsigma_ao_cmd;
1434         s->cancel       = usbduxsigma_ao_cancel;
1435
1436         /* Digital I/O subdevice */
1437         s = &dev->subdevices[2];
1438         s->type         = COMEDI_SUBD_DIO;
1439         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1440         s->n_chan       = 24;
1441         s->maxdata      = 1;
1442         s->range_table  = &range_digital;
1443         s->insn_bits    = usbduxsigma_dio_insn_bits;
1444         s->insn_config  = usbduxsigma_dio_insn_config;
1445
1446         if (devpriv->high_speed) {
1447                 /* Timer / pwm subdevice */
1448                 s = &dev->subdevices[3];
1449                 s->type         = COMEDI_SUBD_PWM;
1450                 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1451                 s->n_chan       = 8;
1452                 s->maxdata      = devpriv->pwm_buf_sz;
1453                 s->insn_write   = usbduxsigma_pwm_write;
1454                 s->insn_config  = usbduxsigma_pwm_config;
1455
1456                 usbduxsigma_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1457         }
1458
1459         up(&devpriv->sem);
1460
1461         offset = usbduxsigma_getstatusinfo(dev, 0);
1462         if (offset < 0)
1463                 dev_err(dev->class_dev,
1464                         "Communication to USBDUXSIGMA failed! Check firmware and cabling\n");
1465
1466         dev_info(dev->class_dev, "attached, ADC_zero = %x\n", offset);
1467
1468         return 0;
1469 }
1470
1471 static int usbduxsigma_firmware_upload(struct comedi_device *dev,
1472                                        const u8 *data, size_t size,
1473                                        unsigned long context)
1474 {
1475         struct usb_device *usb = comedi_to_usb_dev(dev);
1476         uint8_t *buf;
1477         uint8_t *tmp;
1478         int ret;
1479
1480         if (!data)
1481                 return 0;
1482
1483         if (size > FIRMWARE_MAX_LEN) {
1484                 dev_err(dev->class_dev, "firmware binary too large for FX2\n");
1485                 return -ENOMEM;
1486         }
1487
1488         /* we generate a local buffer for the firmware */
1489         buf = kmemdup(data, size, GFP_KERNEL);
1490         if (!buf)
1491                 return -ENOMEM;
1492
1493         /* we need a malloc'ed buffer for usb_control_msg() */
1494         tmp = kmalloc(1, GFP_KERNEL);
1495         if (!tmp) {
1496                 kfree(buf);
1497                 return -ENOMEM;
1498         }
1499
1500         /* stop the current firmware on the device */
1501         *tmp = 1;       /* 7f92 to one */
1502         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1503                               USBDUXSUB_FIRMWARE,
1504                               VENDOR_DIR_OUT,
1505                               USBDUXSUB_CPUCS, 0x0000,
1506                               tmp, 1,
1507                               BULK_TIMEOUT);
1508         if (ret < 0) {
1509                 dev_err(dev->class_dev, "can not stop firmware\n");
1510                 goto done;
1511         }
1512
1513         /* upload the new firmware to the device */
1514         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1515                               USBDUXSUB_FIRMWARE,
1516                               VENDOR_DIR_OUT,
1517                               0, 0x0000,
1518                               buf, size,
1519                               BULK_TIMEOUT);
1520         if (ret < 0) {
1521                 dev_err(dev->class_dev, "firmware upload failed\n");
1522                 goto done;
1523         }
1524
1525         /* start the new firmware on the device */
1526         *tmp = 0;       /* 7f92 to zero */
1527         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1528                               USBDUXSUB_FIRMWARE,
1529                               VENDOR_DIR_OUT,
1530                               USBDUXSUB_CPUCS, 0x0000,
1531                               tmp, 1,
1532                               BULK_TIMEOUT);
1533         if (ret < 0)
1534                 dev_err(dev->class_dev, "can not start firmware\n");
1535
1536 done:
1537         kfree(tmp);
1538         kfree(buf);
1539         return ret;
1540 }
1541
1542 static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev)
1543 {
1544         struct usb_device *usb = comedi_to_usb_dev(dev);
1545         struct usbduxsigma_private *devpriv = dev->private;
1546         struct urb *urb;
1547         int i;
1548
1549         devpriv->dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
1550         devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1551         devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL);
1552         devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1553         devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(*urb),
1554                                    GFP_KERNEL);
1555         devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(*urb),
1556                                    GFP_KERNEL);
1557         if (!devpriv->dac_commands || !devpriv->dux_commands ||
1558             !devpriv->in_buf || !devpriv->insn_buf ||
1559             !devpriv->ai_urbs || !devpriv->ao_urbs)
1560                 return -ENOMEM;
1561
1562         for (i = 0; i < devpriv->n_ai_urbs; i++) {
1563                 /* one frame: 1ms */
1564                 urb = usb_alloc_urb(1, GFP_KERNEL);
1565                 if (!urb)
1566                         return -ENOMEM;
1567                 devpriv->ai_urbs[i] = urb;
1568                 urb->dev = usb;
1569                 /* will be filled later with a pointer to the comedi-device */
1570                 /* and ONLY then the urb should be submitted */
1571                 urb->context = NULL;
1572                 urb->pipe = usb_rcvisocpipe(usb, USBDUXSIGMA_ISO_IN_EP);
1573                 urb->transfer_flags = URB_ISO_ASAP;
1574                 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1575                 if (!urb->transfer_buffer)
1576                         return -ENOMEM;
1577                 urb->complete = usbduxsigma_ai_urb_complete;
1578                 urb->number_of_packets = 1;
1579                 urb->transfer_buffer_length = SIZEINBUF;
1580                 urb->iso_frame_desc[0].offset = 0;
1581                 urb->iso_frame_desc[0].length = SIZEINBUF;
1582         }
1583
1584         for (i = 0; i < devpriv->n_ao_urbs; i++) {
1585                 /* one frame: 1ms */
1586                 urb = usb_alloc_urb(1, GFP_KERNEL);
1587                 if (!urb)
1588                         return -ENOMEM;
1589                 devpriv->ao_urbs[i] = urb;
1590                 urb->dev = usb;
1591                 /* will be filled later with a pointer to the comedi-device */
1592                 /* and ONLY then the urb should be submitted */
1593                 urb->context = NULL;
1594                 urb->pipe = usb_sndisocpipe(usb, USBDUXSIGMA_ISO_OUT_EP);
1595                 urb->transfer_flags = URB_ISO_ASAP;
1596                 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1597                 if (!urb->transfer_buffer)
1598                         return -ENOMEM;
1599                 urb->complete = usbduxsigma_ao_urb_complete;
1600                 urb->number_of_packets = 1;
1601                 urb->transfer_buffer_length = SIZEOUTBUF;
1602                 urb->iso_frame_desc[0].offset = 0;
1603                 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1604                 if (devpriv->high_speed)
1605                         urb->interval = 8;      /* uframes */
1606                 else
1607                         urb->interval = 1;      /* frames */
1608         }
1609
1610         if (devpriv->high_speed) {
1611                 /* max bulk ep size in high speed */
1612                 devpriv->pwm_buf_sz = 512;
1613                 urb = usb_alloc_urb(0, GFP_KERNEL);
1614                 if (!urb)
1615                         return -ENOMEM;
1616                 devpriv->pwm_urb = urb;
1617                 urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz, GFP_KERNEL);
1618                 if (!urb->transfer_buffer)
1619                         return -ENOMEM;
1620         } else {
1621                 devpriv->pwm_urb = NULL;
1622                 devpriv->pwm_buf_sz = 0;
1623         }
1624
1625         return 0;
1626 }
1627
1628 static void usbduxsigma_free_usb_buffers(struct comedi_device *dev)
1629 {
1630         struct usbduxsigma_private *devpriv = dev->private;
1631         struct urb *urb;
1632         int i;
1633
1634         /* force unlink all urbs */
1635         usbduxsigma_ai_stop(dev, 1);
1636         usbduxsigma_ao_stop(dev, 1);
1637         usbduxsigma_pwm_stop(dev, 1);
1638
1639         urb = devpriv->pwm_urb;
1640         if (urb) {
1641                 kfree(urb->transfer_buffer);
1642                 usb_free_urb(urb);
1643         }
1644         if (devpriv->ao_urbs) {
1645                 for (i = 0; i < devpriv->n_ao_urbs; i++) {
1646                         urb = devpriv->ao_urbs[i];
1647                         if (urb) {
1648                                 kfree(urb->transfer_buffer);
1649                                 usb_free_urb(urb);
1650                         }
1651                 }
1652                 kfree(devpriv->ao_urbs);
1653         }
1654         if (devpriv->ai_urbs) {
1655                 for (i = 0; i < devpriv->n_ai_urbs; i++) {
1656                         urb = devpriv->ai_urbs[i];
1657                         if (urb) {
1658                                 kfree(urb->transfer_buffer);
1659                                 usb_free_urb(urb);
1660                         }
1661                 }
1662                 kfree(devpriv->ai_urbs);
1663         }
1664         kfree(devpriv->insn_buf);
1665         kfree(devpriv->in_buf);
1666         kfree(devpriv->dux_commands);
1667         kfree(devpriv->dac_commands);
1668 }
1669
1670 static int usbduxsigma_auto_attach(struct comedi_device *dev,
1671                                    unsigned long context_unused)
1672 {
1673         struct usb_interface *intf = comedi_to_usb_interface(dev);
1674         struct usb_device *usb = comedi_to_usb_dev(dev);
1675         struct usbduxsigma_private *devpriv;
1676         int ret;
1677
1678         devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1679         if (!devpriv)
1680                 return -ENOMEM;
1681         dev->private = devpriv;
1682
1683         sema_init(&devpriv->sem, 1);
1684         usb_set_intfdata(intf, devpriv);
1685
1686         ret = usb_set_interface(usb,
1687                                 intf->altsetting->desc.bInterfaceNumber, 3);
1688         if (ret < 0) {
1689                 dev_err(dev->class_dev,
1690                         "could not set alternate setting 3 in high speed\n");
1691                 return -ENODEV;
1692         }
1693
1694         /* test if it is high speed (USB 2.0) */
1695         devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1696         if (devpriv->high_speed) {
1697                 devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH;
1698                 devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH;
1699         } else {
1700                 devpriv->n_ai_urbs = NUMOFINBUFFERSFULL;
1701                 devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL;
1702         }
1703
1704         ret = usbduxsigma_alloc_usb_buffers(dev);
1705         if (ret)
1706                 return ret;
1707
1708         ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1709                                    usbduxsigma_firmware_upload, 0);
1710         if (ret)
1711                 return ret;
1712
1713         return usbduxsigma_attach_common(dev);
1714 }
1715
1716 static void usbduxsigma_detach(struct comedi_device *dev)
1717 {
1718         struct usb_interface *intf = comedi_to_usb_interface(dev);
1719         struct usbduxsigma_private *devpriv = dev->private;
1720
1721         if (!devpriv)
1722                 return;
1723
1724         usb_set_intfdata(intf, NULL);
1725
1726         down(&devpriv->sem);
1727         usbduxsigma_free_usb_buffers(dev);
1728         up(&devpriv->sem);
1729 }
1730
1731 static struct comedi_driver usbduxsigma_driver = {
1732         .driver_name    = "usbduxsigma",
1733         .module         = THIS_MODULE,
1734         .auto_attach    = usbduxsigma_auto_attach,
1735         .detach         = usbduxsigma_detach,
1736 };
1737
1738 static int usbduxsigma_usb_probe(struct usb_interface *intf,
1739                                  const struct usb_device_id *id)
1740 {
1741         return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0);
1742 }
1743
1744 static const struct usb_device_id usbduxsigma_usb_table[] = {
1745         { USB_DEVICE(0x13d8, 0x0020) },
1746         { USB_DEVICE(0x13d8, 0x0021) },
1747         { USB_DEVICE(0x13d8, 0x0022) },
1748         { }
1749 };
1750 MODULE_DEVICE_TABLE(usb, usbduxsigma_usb_table);
1751
1752 static struct usb_driver usbduxsigma_usb_driver = {
1753         .name           = "usbduxsigma",
1754         .probe          = usbduxsigma_usb_probe,
1755         .disconnect     = comedi_usb_auto_unconfig,
1756         .id_table       = usbduxsigma_usb_table,
1757 };
1758 module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver);
1759
1760 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1761 MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com");
1762 MODULE_LICENSE("GPL");
1763 MODULE_FIRMWARE(FIRMWARE);