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