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