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