]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/comedi/drivers/usbdux.c
Merge remote-tracking branch 'staging/staging-next'
[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(uint16_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(uint8_t)+sizeof(uint16_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         uint8_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         uint16_t *in_buf;
203         /* input buffer for single insn */
204         uint16_t *insn_buf;
205
206         uint8_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         uint8_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                 uint16_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         uint8_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                         unsigned 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 uint8_t create_adc_command(unsigned int chan, unsigned int range)
653 {
654         uint8_t p = (range <= 1);
655         uint8_t r = ((range % 2) == 0);
656
657         return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
658 }
659
660 static int send_dux_commands(struct comedi_device *dev, unsigned int cmd_type)
661 {
662         struct usb_device *usb = comedi_to_usb_dev(dev);
663         struct usbdux_private *devpriv = dev->private;
664         int nsent;
665
666         devpriv->dux_commands[0] = cmd_type;
667
668         return usb_bulk_msg(usb, usb_sndbulkpipe(usb, 1),
669                             devpriv->dux_commands, SIZEOFDUXBUFFER,
670                             &nsent, BULK_TIMEOUT);
671 }
672
673 static int receive_dux_commands(struct comedi_device *dev, unsigned int command)
674 {
675         struct usb_device *usb = comedi_to_usb_dev(dev);
676         struct usbdux_private *devpriv = dev->private;
677         int ret;
678         int nrec;
679         int i;
680
681         for (i = 0; i < RETRIES; i++) {
682                 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, 8),
683                                       devpriv->insn_buf, SIZEINSNBUF,
684                                       &nrec, BULK_TIMEOUT);
685                 if (ret < 0)
686                         return ret;
687                 if (le16_to_cpu(devpriv->insn_buf[0]) == command)
688                         return ret;
689         }
690         /* command not received */
691         return -EFAULT;
692 }
693
694 static int usbdux_ai_inttrig(struct comedi_device *dev,
695                              struct comedi_subdevice *s,
696                              unsigned int trignum)
697 {
698         struct usbdux_private *devpriv = dev->private;
699         int ret = -EINVAL;
700
701         down(&devpriv->sem);
702
703         if (trignum != 0)
704                 goto ai_trig_exit;
705
706         if (!devpriv->ai_cmd_running) {
707                 devpriv->ai_cmd_running = 1;
708                 ret = usbdux_submit_urbs(dev, devpriv->ai_urbs,
709                                          devpriv->n_ai_urbs, 1);
710                 if (ret < 0) {
711                         devpriv->ai_cmd_running = 0;
712                         goto ai_trig_exit;
713                 }
714                 s->async->inttrig = NULL;
715         } else {
716                 ret = -EBUSY;
717         }
718
719 ai_trig_exit:
720         up(&devpriv->sem);
721         return ret;
722 }
723
724 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
725 {
726         struct usbdux_private *devpriv = dev->private;
727         struct comedi_cmd *cmd = &s->async->cmd;
728         int len = cmd->chanlist_len;
729         int ret = -EBUSY;
730         int i;
731
732         /* block other CPUs from starting an ai_cmd */
733         down(&devpriv->sem);
734
735         if (devpriv->ai_cmd_running)
736                 goto ai_cmd_exit;
737
738         /* set current channel of the running acquisition to zero */
739         s->async->cur_chan = 0;
740
741         devpriv->dux_commands[1] = len;
742         for (i = 0; i < len; ++i) {
743                 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
744                 unsigned int range = CR_RANGE(cmd->chanlist[i]);
745
746                 devpriv->dux_commands[i + 2] = create_adc_command(chan, range);
747         }
748
749         ret = send_dux_commands(dev, USBDUX_CMD_MULT_AI);
750         if (ret < 0)
751                 goto ai_cmd_exit;
752
753         if (devpriv->high_speed) {
754                 /*
755                  * every channel gets a time window of 125us. Thus, if we
756                  * sample all 8 channels we need 1ms. If we sample only one
757                  * channel we need only 125us
758                  */
759                 devpriv->ai_interval = 1;
760                 /* find a power of 2 for the interval */
761                 while (devpriv->ai_interval < len)
762                         devpriv->ai_interval *= 2;
763
764                 devpriv->ai_timer = cmd->scan_begin_arg /
765                                     (125000 * devpriv->ai_interval);
766         } else {
767                 /* interval always 1ms */
768                 devpriv->ai_interval = 1;
769                 devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
770         }
771         if (devpriv->ai_timer < 1) {
772                 ret = -EINVAL;
773                 goto ai_cmd_exit;
774         }
775
776         devpriv->ai_counter = devpriv->ai_timer;
777
778         if (cmd->stop_src == TRIG_COUNT) {
779                 /* data arrives as one packet */
780                 devpriv->ai_sample_count = cmd->stop_arg;
781                 devpriv->ai_continous = 0;
782         } else {
783                 /* continous acquisition */
784                 devpriv->ai_continous = 1;
785                 devpriv->ai_sample_count = 0;
786         }
787
788         if (cmd->start_src == TRIG_NOW) {
789                 /* enable this acquisition operation */
790                 devpriv->ai_cmd_running = 1;
791                 ret = usbdux_submit_urbs(dev, devpriv->ai_urbs,
792                                          devpriv->n_ai_urbs, 1);
793                 if (ret < 0) {
794                         devpriv->ai_cmd_running = 0;
795                         /* fixme: unlink here?? */
796                         goto ai_cmd_exit;
797                 }
798                 s->async->inttrig = NULL;
799         } else {
800                 /* TRIG_INT */
801                 /* don't enable the acquision operation */
802                 /* wait for an internal signal */
803                 s->async->inttrig = usbdux_ai_inttrig;
804         }
805
806 ai_cmd_exit:
807         up(&devpriv->sem);
808
809         return ret;
810 }
811
812 /* Mode 0 is used to get a single conversion on demand */
813 static int usbdux_ai_insn_read(struct comedi_device *dev,
814                                struct comedi_subdevice *s,
815                                struct comedi_insn *insn,
816                                unsigned int *data)
817 {
818         struct usbdux_private *devpriv = dev->private;
819         unsigned int chan = CR_CHAN(insn->chanspec);
820         unsigned int range = CR_RANGE(insn->chanspec);
821         unsigned int val;
822         int ret = -EBUSY;
823         int i;
824
825         down(&devpriv->sem);
826
827         if (devpriv->ai_cmd_running)
828                 goto ai_read_exit;
829
830         /* set command for the first channel */
831         devpriv->dux_commands[1] = create_adc_command(chan, range);
832
833         /* adc commands */
834         ret = send_dux_commands(dev, USBDUX_CMD_SINGLE_AI);
835         if (ret < 0)
836                 goto ai_read_exit;
837
838         for (i = 0; i < insn->n; i++) {
839                 ret = receive_dux_commands(dev, USBDUX_CMD_SINGLE_AI);
840                 if (ret < 0)
841                         goto ai_read_exit;
842
843                 val = le16_to_cpu(devpriv->insn_buf[1]);
844
845                 /* bipolar data is two's-complement */
846                 if (comedi_range_is_bipolar(s, range))
847                         val ^= ((s->maxdata + 1) >> 1);
848
849                 data[i] = val;
850         }
851
852 ai_read_exit:
853         up(&devpriv->sem);
854
855         return ret ? ret : insn->n;
856 }
857
858 static int usbdux_ao_insn_read(struct comedi_device *dev,
859                                struct comedi_subdevice *s,
860                                struct comedi_insn *insn,
861                                unsigned int *data)
862 {
863         struct usbdux_private *devpriv = dev->private;
864         unsigned int chan = CR_CHAN(insn->chanspec);
865         int i;
866
867         down(&devpriv->sem);
868         for (i = 0; i < insn->n; i++)
869                 data[i] = devpriv->ao_readback[chan];
870         up(&devpriv->sem);
871
872         return insn->n;
873 }
874
875 static int usbdux_ao_insn_write(struct comedi_device *dev,
876                                 struct comedi_subdevice *s,
877                                 struct comedi_insn *insn,
878                                 unsigned int *data)
879 {
880         struct usbdux_private *devpriv = dev->private;
881         unsigned int chan = CR_CHAN(insn->chanspec);
882         unsigned int val = devpriv->ao_readback[chan];
883         uint16_t *p = (uint16_t *)&devpriv->dux_commands[2];
884         int ret = -EBUSY;
885         int i;
886
887         down(&devpriv->sem);
888
889         if (devpriv->ao_cmd_running)
890                 goto ao_write_exit;
891
892         /* number of channels: 1 */
893         devpriv->dux_commands[1] = 1;
894         /* channel number */
895         devpriv->dux_commands[4] = chan << 6;
896
897         for (i = 0; i < insn->n; i++) {
898                 val = data[i];
899
900                 /* one 16 bit value */
901                 *p = cpu_to_le16(val);
902
903                 ret = send_dux_commands(dev, USBDUX_CMD_AO);
904                 if (ret < 0)
905                         goto ao_write_exit;
906         }
907         devpriv->ao_readback[chan] = val;
908
909 ao_write_exit:
910         up(&devpriv->sem);
911
912         return ret ? ret : insn->n;
913 }
914
915 static int usbdux_ao_inttrig(struct comedi_device *dev,
916                              struct comedi_subdevice *s,
917                              unsigned int trignum)
918 {
919         struct usbdux_private *devpriv = dev->private;
920         int ret = -EINVAL;
921
922         down(&devpriv->sem);
923
924         if (trignum != 0)
925                 goto ao_trig_exit;
926
927         if (!devpriv->ao_cmd_running) {
928                 devpriv->ao_cmd_running = 1;
929                 ret = usbdux_submit_urbs(dev, devpriv->ao_urbs,
930                                          devpriv->n_ao_urbs, 0);
931                 if (ret < 0) {
932                         devpriv->ao_cmd_running = 0;
933                         goto ao_trig_exit;
934                 }
935                 s->async->inttrig = NULL;
936         } else {
937                 ret = -EBUSY;
938         }
939
940 ao_trig_exit:
941         up(&devpriv->sem);
942         return ret;
943 }
944
945 static int usbdux_ao_cmdtest(struct comedi_device *dev,
946                              struct comedi_subdevice *s, struct comedi_cmd *cmd)
947 {
948         struct usbdux_private *this_usbduxsub = dev->private;
949         int err = 0;
950         unsigned int flags;
951
952         if (!this_usbduxsub)
953                 return -EFAULT;
954
955         /* Step 1 : check if triggers are trivially valid */
956
957         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
958
959         if (0) {                /* (this_usbduxsub->high_speed) */
960                 /* the sampling rate is set by the coversion rate */
961                 flags = TRIG_FOLLOW;
962         } else {
963                 /* start a new scan (output at once) with a timer */
964                 flags = TRIG_TIMER;
965         }
966         err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
967
968         if (0) {                /* (this_usbduxsub->high_speed) */
969                 /*
970                  * in usb-2.0 only one conversion it transmitted
971                  * but with 8kHz/n
972                  */
973                 flags = TRIG_TIMER;
974         } else {
975                 /*
976                  * all conversion events happen simultaneously with
977                  * a rate of 1kHz/n
978                  */
979                 flags = TRIG_NOW;
980         }
981         err |= cfc_check_trigger_src(&cmd->convert_src, flags);
982
983         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
984         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
985
986         if (err)
987                 return 1;
988
989         /* Step 2a : make sure trigger sources are unique */
990
991         err |= cfc_check_trigger_is_unique(cmd->start_src);
992         err |= cfc_check_trigger_is_unique(cmd->stop_src);
993
994         /* Step 2b : and mutually compatible */
995
996         if (err)
997                 return 2;
998
999         /* Step 3: check if arguments are trivially valid */
1000
1001         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1002
1003         if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
1004                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1005
1006         if (cmd->scan_begin_src == TRIG_TIMER)
1007                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1008                                                  1000000);
1009
1010         /* not used now, is for later use */
1011         if (cmd->convert_src == TRIG_TIMER)
1012                 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
1013
1014         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1015
1016         if (cmd->stop_src == TRIG_COUNT) {
1017                 /* any count is allowed */
1018         } else {
1019                 /* TRIG_NONE */
1020                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1021         }
1022
1023         if (err)
1024                 return 3;
1025
1026         return 0;
1027 }
1028
1029 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1030 {
1031         struct usbdux_private *devpriv = dev->private;
1032         struct comedi_cmd *cmd = &s->async->cmd;
1033         int ret = -EBUSY;
1034         int i;
1035
1036         down(&devpriv->sem);
1037
1038         if (devpriv->ao_cmd_running)
1039                 goto ao_cmd_exit;
1040
1041         /* set current channel of the running acquisition to zero */
1042         s->async->cur_chan = 0;
1043
1044         for (i = 0; i < cmd->chanlist_len; ++i) {
1045                 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
1046
1047                 devpriv->ao_chanlist[i] = chan << 6;
1048         }
1049
1050         /* we count in steps of 1ms (125us) */
1051         /* 125us mode not used yet */
1052         if (0) {                /* (devpriv->high_speed) */
1053                 /* 125us */
1054                 /* timing of the conversion itself: every 125 us */
1055                 devpriv->ao_timer = cmd->convert_arg / 125000;
1056         } else {
1057                 /* 1ms */
1058                 /* timing of the scan: we get all channels at once */
1059                 devpriv->ao_timer = cmd->scan_begin_arg / 1000000;
1060                 if (devpriv->ao_timer < 1) {
1061                         ret = -EINVAL;
1062                         goto ao_cmd_exit;
1063                 }
1064         }
1065
1066         devpriv->ao_counter = devpriv->ao_timer;
1067
1068         if (cmd->stop_src == TRIG_COUNT) {
1069                 /* not continuous */
1070                 /* counter */
1071                 /* high speed also scans everything at once */
1072                 if (0) {        /* (devpriv->high_speed) */
1073                         devpriv->ao_sample_count = cmd->stop_arg *
1074                                                    cmd->scan_end_arg;
1075                 } else {
1076                         /* there's no scan as the scan has been */
1077                         /* perf inside the FX2 */
1078                         /* data arrives as one packet */
1079                         devpriv->ao_sample_count = cmd->stop_arg;
1080                 }
1081                 devpriv->ao_continous = 0;
1082         } else {
1083                 /* continous acquisition */
1084                 devpriv->ao_continous = 1;
1085                 devpriv->ao_sample_count = 0;
1086         }
1087
1088         if (cmd->start_src == TRIG_NOW) {
1089                 /* enable this acquisition operation */
1090                 devpriv->ao_cmd_running = 1;
1091                 ret = usbdux_submit_urbs(dev, devpriv->ao_urbs,
1092                                          devpriv->n_ao_urbs, 0);
1093                 if (ret < 0) {
1094                         devpriv->ao_cmd_running = 0;
1095                         /* fixme: unlink here?? */
1096                         goto ao_cmd_exit;
1097                 }
1098                 s->async->inttrig = NULL;
1099         } else {
1100                 /* TRIG_INT */
1101                 /* submit the urbs later */
1102                 /* wait for an internal signal */
1103                 s->async->inttrig = usbdux_ao_inttrig;
1104         }
1105
1106 ao_cmd_exit:
1107         up(&devpriv->sem);
1108
1109         return ret;
1110 }
1111
1112 static int usbdux_dio_insn_config(struct comedi_device *dev,
1113                                   struct comedi_subdevice *s,
1114                                   struct comedi_insn *insn,
1115                                   unsigned int *data)
1116 {
1117         int ret;
1118
1119         ret = comedi_dio_insn_config(dev, s, insn, data, 0);
1120         if (ret)
1121                 return ret;
1122
1123         /*
1124          * We don't tell the firmware here as it would take 8 frames
1125          * to submit the information. We do it in the insn_bits.
1126          */
1127         return insn->n;
1128 }
1129
1130 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1131                                 struct comedi_subdevice *s,
1132                                 struct comedi_insn *insn,
1133                                 unsigned int *data)
1134 {
1135
1136         struct usbdux_private *devpriv = dev->private;
1137         int ret;
1138
1139         down(&devpriv->sem);
1140
1141         comedi_dio_update_state(s, data);
1142
1143         /* Always update the hardware. See the (*insn_config). */
1144         devpriv->dux_commands[1] = s->io_bits;
1145         devpriv->dux_commands[2] = s->state;
1146
1147         /*
1148          * This command also tells the firmware to return
1149          * the digital input lines.
1150          */
1151         ret = send_dux_commands(dev, USBDUX_CMD_DIO_BITS);
1152         if (ret < 0)
1153                 goto dio_exit;
1154         ret = receive_dux_commands(dev, USBDUX_CMD_DIO_BITS);
1155         if (ret < 0)
1156                 goto dio_exit;
1157
1158         data[1] = le16_to_cpu(devpriv->insn_buf[1]);
1159
1160 dio_exit:
1161         up(&devpriv->sem);
1162
1163         return ret ? ret : insn->n;
1164 }
1165
1166 static int usbdux_counter_read(struct comedi_device *dev,
1167                                struct comedi_subdevice *s,
1168                                struct comedi_insn *insn,
1169                                unsigned int *data)
1170 {
1171         struct usbdux_private *devpriv = dev->private;
1172         unsigned int chan = CR_CHAN(insn->chanspec);
1173         int ret = 0;
1174         int i;
1175
1176         down(&devpriv->sem);
1177
1178         for (i = 0; i < insn->n; i++) {
1179                 ret = send_dux_commands(dev, USBDUX_CMD_TIMER_RD);
1180                 if (ret < 0)
1181                         goto counter_read_exit;
1182                 ret = receive_dux_commands(dev, USBDUX_CMD_TIMER_RD);
1183                 if (ret < 0)
1184                         goto counter_read_exit;
1185
1186                 data[i] = le16_to_cpu(devpriv->insn_buf[chan + 1]);
1187         }
1188
1189 counter_read_exit:
1190         up(&devpriv->sem);
1191
1192         return ret ? ret : insn->n;
1193 }
1194
1195 static int usbdux_counter_write(struct comedi_device *dev,
1196                                 struct comedi_subdevice *s,
1197                                 struct comedi_insn *insn,
1198                                 unsigned int *data)
1199 {
1200         struct usbdux_private *devpriv = dev->private;
1201         unsigned int chan = CR_CHAN(insn->chanspec);
1202         uint16_t *p = (uint16_t *)&devpriv->dux_commands[2];
1203         int ret = 0;
1204         int i;
1205
1206         down(&devpriv->sem);
1207
1208         devpriv->dux_commands[1] = chan;
1209
1210         for (i = 0; i < insn->n; i++) {
1211                 *p = cpu_to_le16(data[i]);
1212
1213                 ret = send_dux_commands(dev, USBDUX_CMD_TIMER_WR);
1214                 if (ret < 0)
1215                         break;
1216         }
1217
1218         up(&devpriv->sem);
1219
1220         return ret ? ret : insn->n;
1221 }
1222
1223 static int usbdux_counter_config(struct comedi_device *dev,
1224                                  struct comedi_subdevice *s,
1225                                  struct comedi_insn *insn, unsigned int *data)
1226 {
1227         /* nothing to do so far */
1228         return 2;
1229 }
1230
1231 static void usbduxsub_unlink_pwm_urbs(struct comedi_device *dev)
1232 {
1233         struct usbdux_private *devpriv = dev->private;
1234
1235         usb_kill_urb(devpriv->pwm_urb);
1236 }
1237
1238 static void usbdux_pwm_stop(struct comedi_device *dev, int do_unlink)
1239 {
1240         struct usbdux_private *devpriv = dev->private;
1241
1242         if (do_unlink)
1243                 usbduxsub_unlink_pwm_urbs(dev);
1244
1245         devpriv->pwm_cmd_running = 0;
1246 }
1247
1248 static int usbdux_pwm_cancel(struct comedi_device *dev,
1249                              struct comedi_subdevice *s)
1250 {
1251         struct usbdux_private *devpriv = dev->private;
1252         int ret;
1253
1254         down(&devpriv->sem);
1255         /* unlink only if it is really running */
1256         usbdux_pwm_stop(dev, devpriv->pwm_cmd_running);
1257         ret = send_dux_commands(dev, USBDUX_CMD_PWM_OFF);
1258         up(&devpriv->sem);
1259
1260         return ret;
1261 }
1262
1263 static void usbduxsub_pwm_irq(struct urb *urb)
1264 {
1265         struct comedi_device *dev = urb->context;
1266         struct usbdux_private *devpriv = dev->private;
1267         int ret;
1268
1269         switch (urb->status) {
1270         case 0:
1271                 /* success */
1272                 break;
1273
1274         case -ECONNRESET:
1275         case -ENOENT:
1276         case -ESHUTDOWN:
1277         case -ECONNABORTED:
1278                 /*
1279                  * after an unlink command, unplug, ... etc
1280                  * no unlink needed here. Already shutting down.
1281                  */
1282                 if (devpriv->pwm_cmd_running)
1283                         usbdux_pwm_stop(dev, 0);
1284
1285                 return;
1286
1287         default:
1288                 /* a real error */
1289                 if (devpriv->pwm_cmd_running) {
1290                         dev_err(dev->class_dev,
1291                                 "Non-zero urb status received in pwm intr context: %d\n",
1292                                 urb->status);
1293                         usbdux_pwm_stop(dev, 0);
1294                 }
1295                 return;
1296         }
1297
1298         /* are we actually running? */
1299         if (!devpriv->pwm_cmd_running)
1300                 return;
1301
1302         urb->transfer_buffer_length = devpriv->pwm_buf_sz;
1303         urb->dev = comedi_to_usb_dev(dev);
1304         urb->status = 0;
1305         if (devpriv->pwm_cmd_running) {
1306                 ret = usb_submit_urb(urb, GFP_ATOMIC);
1307                 if (ret < 0) {
1308                         dev_err(dev->class_dev,
1309                                 "pwm urb resubm failed in int-cont. ret=%d",
1310                                 ret);
1311                         if (ret == EL2NSYNC)
1312                                 dev_err(dev->class_dev,
1313                                         "buggy USB host controller or bug in IRQ handling!\n");
1314
1315                         /* don't do an unlink here */
1316                         usbdux_pwm_stop(dev, 0);
1317                 }
1318         }
1319 }
1320
1321 static int usbduxsub_submit_pwm_urbs(struct comedi_device *dev)
1322 {
1323         struct usb_device *usb = comedi_to_usb_dev(dev);
1324         struct usbdux_private *devpriv = dev->private;
1325         struct urb *urb = devpriv->pwm_urb;
1326
1327         /* in case of a resubmission after an unlink... */
1328         usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, 4),
1329                           urb->transfer_buffer,
1330                           devpriv->pwm_buf_sz,
1331                           usbduxsub_pwm_irq,
1332                           dev);
1333
1334         return usb_submit_urb(urb, GFP_ATOMIC);
1335 }
1336
1337 static int usbdux_pwm_period(struct comedi_device *dev,
1338                              struct comedi_subdevice *s,
1339                              unsigned int period)
1340 {
1341         struct usbdux_private *devpriv = dev->private;
1342         int fx2delay = 255;
1343
1344         if (period < MIN_PWM_PERIOD) {
1345                 return -EAGAIN;
1346         } else {
1347                 fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
1348                 if (fx2delay > 255)
1349                         return -EAGAIN;
1350         }
1351         devpriv->pwm_delay = fx2delay;
1352         devpriv->pwm_period = period;
1353
1354         return 0;
1355 }
1356
1357 static int usbdux_pwm_start(struct comedi_device *dev,
1358                             struct comedi_subdevice *s)
1359 {
1360         struct usbdux_private *devpriv = dev->private;
1361         int ret = 0;
1362
1363         down(&devpriv->sem);
1364
1365         if (devpriv->pwm_cmd_running)
1366                 goto pwm_start_exit;
1367
1368         devpriv->dux_commands[1] = devpriv->pwm_delay;
1369         ret = send_dux_commands(dev, USBDUX_CMD_PWM_ON);
1370         if (ret < 0)
1371                 goto pwm_start_exit;
1372
1373         /* initialise the buffer */
1374         memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);
1375
1376         devpriv->pwm_cmd_running = 1;
1377         ret = usbduxsub_submit_pwm_urbs(dev);
1378         if (ret < 0)
1379                 devpriv->pwm_cmd_running = 0;
1380
1381 pwm_start_exit:
1382         up(&devpriv->sem);
1383
1384         return ret;
1385 }
1386
1387 static void usbdux_pwm_pattern(struct comedi_device *dev,
1388                                struct comedi_subdevice *s,
1389                                unsigned int chan,
1390                                unsigned int value,
1391                                unsigned int sign)
1392 {
1393         struct usbdux_private *devpriv = dev->private;
1394         char pwm_mask = (1 << chan);    /* DIO bit for the PWM data */
1395         char sgn_mask = (16 << chan);   /* DIO bit for the sign */
1396         char *buf = (char *)(devpriv->pwm_urb->transfer_buffer);
1397         int szbuf = devpriv->pwm_buf_sz;
1398         int i;
1399
1400         for (i = 0; i < szbuf; i++) {
1401                 char c = *buf;
1402
1403                 c &= ~pwm_mask;
1404                 if (i < value)
1405                         c |= pwm_mask;
1406                 if (!sign)
1407                         c &= ~sgn_mask;
1408                 else
1409                         c |= sgn_mask;
1410                 *buf++ = c;
1411         }
1412 }
1413
1414 static int usbdux_pwm_write(struct comedi_device *dev,
1415                             struct comedi_subdevice *s,
1416                             struct comedi_insn *insn,
1417                             unsigned int *data)
1418 {
1419         unsigned int chan = CR_CHAN(insn->chanspec);
1420
1421         /*
1422          * It doesn't make sense to support more than one value here
1423          * because it would just overwrite the PWM buffer.
1424          */
1425         if (insn->n != 1)
1426                 return -EINVAL;
1427
1428         /*
1429          * The sign is set via a special INSN only, this gives us 8 bits
1430          * for normal operation, sign is 0 by default.
1431          */
1432         usbdux_pwm_pattern(dev, s, chan, data[0], 0);
1433
1434         return insn->n;
1435 }
1436
1437 static int usbdux_pwm_config(struct comedi_device *dev,
1438                              struct comedi_subdevice *s,
1439                              struct comedi_insn *insn,
1440                              unsigned int *data)
1441 {
1442         struct usbdux_private *devpriv = dev->private;
1443         unsigned int chan = CR_CHAN(insn->chanspec);
1444
1445         switch (data[0]) {
1446         case INSN_CONFIG_ARM:
1447                 /*
1448                  * if not zero the PWM is limited to a certain time which is
1449                  * not supported here
1450                  */
1451                 if (data[1] != 0)
1452                         return -EINVAL;
1453                 return usbdux_pwm_start(dev, s);
1454         case INSN_CONFIG_DISARM:
1455                 return usbdux_pwm_cancel(dev, s);
1456         case INSN_CONFIG_GET_PWM_STATUS:
1457                 data[1] = devpriv->pwm_cmd_running;
1458                 return 0;
1459         case INSN_CONFIG_PWM_SET_PERIOD:
1460                 return usbdux_pwm_period(dev, s, data[1]);
1461         case INSN_CONFIG_PWM_GET_PERIOD:
1462                 data[1] = devpriv->pwm_period;
1463                 return 0;
1464         case INSN_CONFIG_PWM_SET_H_BRIDGE:
1465                 /*
1466                  * data[1] = value
1467                  * data[2] = sign (for a relay)
1468                  */
1469                 usbdux_pwm_pattern(dev, s, chan, data[1], (data[2] != 0));
1470                 return 0;
1471         case INSN_CONFIG_PWM_GET_H_BRIDGE:
1472                 /* values are not kept in this driver, nothing to return here */
1473                 return -EINVAL;
1474         }
1475         return -EINVAL;
1476 }
1477
1478 static int usbdux_firmware_upload(struct comedi_device *dev,
1479                                   const u8 *data, size_t size,
1480                                   unsigned long context)
1481 {
1482         struct usb_device *usb = comedi_to_usb_dev(dev);
1483         uint8_t *buf;
1484         uint8_t *tmp;
1485         int ret;
1486
1487         if (!data)
1488                 return 0;
1489
1490         if (size > USBDUX_FIRMWARE_MAX_LEN) {
1491                 dev_err(dev->class_dev,
1492                         "usbdux firmware binary it too large for FX2.\n");
1493                 return -ENOMEM;
1494         }
1495
1496         /* we generate a local buffer for the firmware */
1497         buf = kmemdup(data, size, GFP_KERNEL);
1498         if (!buf)
1499                 return -ENOMEM;
1500
1501         /* we need a malloc'ed buffer for usb_control_msg() */
1502         tmp = kmalloc(1, GFP_KERNEL);
1503         if (!tmp) {
1504                 kfree(buf);
1505                 return -ENOMEM;
1506         }
1507
1508         /* stop the current firmware on the device */
1509         *tmp = 1;       /* 7f92 to one */
1510         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1511                               USBDUX_FIRMWARE_CMD,
1512                               VENDOR_DIR_OUT,
1513                               USBDUX_CPU_CS, 0x0000,
1514                               tmp, 1,
1515                               BULK_TIMEOUT);
1516         if (ret < 0) {
1517                 dev_err(dev->class_dev, "can not stop firmware\n");
1518                 goto done;
1519         }
1520
1521         /* upload the new firmware to the device */
1522         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1523                               USBDUX_FIRMWARE_CMD,
1524                               VENDOR_DIR_OUT,
1525                               0, 0x0000,
1526                               buf, size,
1527                               BULK_TIMEOUT);
1528         if (ret < 0) {
1529                 dev_err(dev->class_dev, "firmware upload failed\n");
1530                 goto done;
1531         }
1532
1533         /* start the new firmware on the device */
1534         *tmp = 0;       /* 7f92 to zero */
1535         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1536                               USBDUX_FIRMWARE_CMD,
1537                               VENDOR_DIR_OUT,
1538                               USBDUX_CPU_CS, 0x0000,
1539                               tmp, 1,
1540                               BULK_TIMEOUT);
1541         if (ret < 0)
1542                 dev_err(dev->class_dev, "can not start firmware\n");
1543
1544 done:
1545         kfree(tmp);
1546         kfree(buf);
1547         return ret;
1548 }
1549
1550 static int usbdux_alloc_usb_buffers(struct comedi_device *dev)
1551 {
1552         struct usb_device *usb = comedi_to_usb_dev(dev);
1553         struct usbdux_private *devpriv = dev->private;
1554         struct urb *urb;
1555         int i;
1556
1557         devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1558         devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL);
1559         devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1560         devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(void *),
1561                                    GFP_KERNEL);
1562         devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(void *),
1563                                    GFP_KERNEL);
1564         if (!devpriv->dux_commands || !devpriv->in_buf || !devpriv->insn_buf ||
1565             !devpriv->ai_urbs || !devpriv->ao_urbs)
1566                 return -ENOMEM;
1567
1568         for (i = 0; i < devpriv->n_ai_urbs; i++) {
1569                 /* one frame: 1ms */
1570                 urb = usb_alloc_urb(1, GFP_KERNEL);
1571                 if (!urb)
1572                         return -ENOMEM;
1573                 devpriv->ai_urbs[i] = urb;
1574
1575                 urb->dev = usb;
1576                 urb->context = dev;
1577                 urb->pipe = usb_rcvisocpipe(usb, 6);
1578                 urb->transfer_flags = URB_ISO_ASAP;
1579                 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1580                 if (!urb->transfer_buffer)
1581                         return -ENOMEM;
1582
1583                 urb->complete = usbduxsub_ai_isoc_irq;
1584                 urb->number_of_packets = 1;
1585                 urb->transfer_buffer_length = SIZEINBUF;
1586                 urb->iso_frame_desc[0].offset = 0;
1587                 urb->iso_frame_desc[0].length = SIZEINBUF;
1588         }
1589
1590         for (i = 0; i < devpriv->n_ao_urbs; i++) {
1591                 /* one frame: 1ms */
1592                 urb = usb_alloc_urb(1, GFP_KERNEL);
1593                 if (!urb)
1594                         return -ENOMEM;
1595                 devpriv->ao_urbs[i] = urb;
1596
1597                 urb->dev = usb;
1598                 urb->context = dev;
1599                 urb->pipe = usb_sndisocpipe(usb, 2);
1600                 urb->transfer_flags = URB_ISO_ASAP;
1601                 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1602                 if (!urb->transfer_buffer)
1603                         return -ENOMEM;
1604
1605                 urb->complete = usbduxsub_ao_isoc_irq;
1606                 urb->number_of_packets = 1;
1607                 urb->transfer_buffer_length = SIZEOUTBUF;
1608                 urb->iso_frame_desc[0].offset = 0;
1609                 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1610                 if (devpriv->high_speed)
1611                         urb->interval = 8;      /* uframes */
1612                 else
1613                         urb->interval = 1;      /* frames */
1614         }
1615
1616         /* pwm */
1617         if (devpriv->pwm_buf_sz) {
1618                 urb = usb_alloc_urb(0, GFP_KERNEL);
1619                 if (!urb)
1620                         return -ENOMEM;
1621                 devpriv->pwm_urb = urb;
1622
1623                 /* max bulk ep size in high speed */
1624                 urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz,
1625                                                GFP_KERNEL);
1626                 if (!urb->transfer_buffer)
1627                         return -ENOMEM;
1628         }
1629
1630         return 0;
1631 }
1632
1633 static void usbdux_free_usb_buffers(struct comedi_device *dev)
1634 {
1635         struct usbdux_private *devpriv = dev->private;
1636         struct urb *urb;
1637         int i;
1638
1639         urb = devpriv->pwm_urb;
1640         if (urb) {
1641                 kfree(urb->transfer_buffer);
1642                 usb_free_urb(urb);
1643         }
1644         if (devpriv->ao_urbs) {
1645                 for (i = 0; i < devpriv->n_ao_urbs; i++) {
1646                         urb = devpriv->ao_urbs[i];
1647                         if (urb) {
1648                                 kfree(urb->transfer_buffer);
1649                                 usb_free_urb(urb);
1650                         }
1651                 }
1652                 kfree(devpriv->ao_urbs);
1653         }
1654         if (devpriv->ai_urbs) {
1655                 for (i = 0; i < devpriv->n_ai_urbs; i++) {
1656                         urb = devpriv->ai_urbs[i];
1657                         if (urb) {
1658                                 kfree(urb->transfer_buffer);
1659                                 usb_free_urb(urb);
1660                         }
1661                 }
1662                 kfree(devpriv->ai_urbs);
1663         }
1664         kfree(devpriv->insn_buf);
1665         kfree(devpriv->in_buf);
1666         kfree(devpriv->dux_commands);
1667 }
1668
1669 static int usbdux_auto_attach(struct comedi_device *dev,
1670                               unsigned long context_unused)
1671 {
1672         struct usb_interface *intf = comedi_to_usb_interface(dev);
1673         struct usb_device *usb = comedi_to_usb_dev(dev);
1674         struct usbdux_private *devpriv;
1675         struct comedi_subdevice *s;
1676         int ret;
1677
1678         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1679         if (!devpriv)
1680                 return -ENOMEM;
1681
1682         sema_init(&devpriv->sem, 1);
1683
1684         usb_set_intfdata(intf, devpriv);
1685
1686         devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1687         if (devpriv->high_speed) {
1688                 devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH;
1689                 devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH;
1690                 devpriv->pwm_buf_sz = 512;
1691         } else {
1692                 devpriv->n_ai_urbs = NUMOFINBUFFERSFULL;
1693                 devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL;
1694         }
1695
1696         ret = usbdux_alloc_usb_buffers(dev);
1697         if (ret)
1698                 return ret;
1699
1700         /* setting to alternate setting 3: enabling iso ep and bulk ep. */
1701         ret = usb_set_interface(usb, intf->altsetting->desc.bInterfaceNumber,
1702                                 3);
1703         if (ret < 0) {
1704                 dev_err(dev->class_dev,
1705                         "could not set alternate setting 3 in high speed\n");
1706                 return ret;
1707         }
1708
1709         ret = comedi_load_firmware(dev, &usb->dev, USBDUX_FIRMWARE,
1710                                    usbdux_firmware_upload, 0);
1711         if (ret < 0)
1712                 return ret;
1713
1714         ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 5 : 4);
1715         if (ret)
1716                 return ret;
1717
1718         /* Analog Input subdevice */
1719         s = &dev->subdevices[0];
1720         dev->read_subdev = s;
1721         s->type         = COMEDI_SUBD_AI;
1722         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
1723         s->n_chan       = 8;
1724         s->maxdata      = 0x0fff;
1725         s->len_chanlist = 8;
1726         s->range_table  = &range_usbdux_ai_range;
1727         s->insn_read    = usbdux_ai_insn_read;
1728         s->do_cmdtest   = usbdux_ai_cmdtest;
1729         s->do_cmd       = usbdux_ai_cmd;
1730         s->cancel       = usbdux_ai_cancel;
1731
1732         /* Analog Output subdevice */
1733         s = &dev->subdevices[1];
1734         dev->write_subdev = s;
1735         s->type         = COMEDI_SUBD_AO;
1736         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1737         s->n_chan       = USBDUX_NUM_AO_CHAN;
1738         s->maxdata      = 0x0fff;
1739         s->len_chanlist = s->n_chan;
1740         s->range_table  = &range_usbdux_ao_range;
1741         s->do_cmdtest   = usbdux_ao_cmdtest;
1742         s->do_cmd       = usbdux_ao_cmd;
1743         s->cancel       = usbdux_ao_cancel;
1744         s->insn_read    = usbdux_ao_insn_read;
1745         s->insn_write   = usbdux_ao_insn_write;
1746
1747         /* Digital I/O subdevice */
1748         s = &dev->subdevices[2];
1749         s->type         = COMEDI_SUBD_DIO;
1750         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1751         s->n_chan       = 8;
1752         s->maxdata      = 1;
1753         s->range_table  = &range_digital;
1754         s->insn_bits    = usbdux_dio_insn_bits;
1755         s->insn_config  = usbdux_dio_insn_config;
1756
1757         /* Counter subdevice */
1758         s = &dev->subdevices[3];
1759         s->type         = COMEDI_SUBD_COUNTER;
1760         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1761         s->n_chan       = 4;
1762         s->maxdata      = 0xffff;
1763         s->insn_read    = usbdux_counter_read;
1764         s->insn_write   = usbdux_counter_write;
1765         s->insn_config  = usbdux_counter_config;
1766
1767         if (devpriv->high_speed) {
1768                 /* PWM subdevice */
1769                 s = &dev->subdevices[4];
1770                 s->type         = COMEDI_SUBD_PWM;
1771                 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1772                 s->n_chan       = 8;
1773                 s->maxdata      = devpriv->pwm_buf_sz;
1774                 s->insn_write   = usbdux_pwm_write;
1775                 s->insn_config  = usbdux_pwm_config;
1776
1777                 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1778         }
1779
1780         return 0;
1781 }
1782
1783 static void usbdux_detach(struct comedi_device *dev)
1784 {
1785         struct usb_interface *intf = comedi_to_usb_interface(dev);
1786         struct usbdux_private *devpriv = dev->private;
1787
1788         usb_set_intfdata(intf, NULL);
1789
1790         if (!devpriv)
1791                 return;
1792
1793         down(&devpriv->sem);
1794
1795         /* force unlink all urbs */
1796         usbdux_pwm_stop(dev, 1);
1797         usbdux_ao_stop(dev, 1);
1798         usbdux_ai_stop(dev, 1);
1799
1800         usbdux_free_usb_buffers(dev);
1801
1802         up(&devpriv->sem);
1803 }
1804
1805 static struct comedi_driver usbdux_driver = {
1806         .driver_name    = "usbdux",
1807         .module         = THIS_MODULE,
1808         .auto_attach    = usbdux_auto_attach,
1809         .detach         = usbdux_detach,
1810 };
1811
1812 static int usbdux_usb_probe(struct usb_interface *intf,
1813                             const struct usb_device_id *id)
1814 {
1815         return comedi_usb_auto_config(intf, &usbdux_driver, 0);
1816 }
1817
1818 static const struct usb_device_id usbdux_usb_table[] = {
1819         { USB_DEVICE(0x13d8, 0x0001) },
1820         { USB_DEVICE(0x13d8, 0x0002) },
1821         { }
1822 };
1823 MODULE_DEVICE_TABLE(usb, usbdux_usb_table);
1824
1825 static struct usb_driver usbdux_usb_driver = {
1826         .name           = "usbdux",
1827         .probe          = usbdux_usb_probe,
1828         .disconnect     = comedi_usb_auto_unconfig,
1829         .id_table       = usbdux_usb_table,
1830 };
1831 module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver);
1832
1833 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1834 MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com");
1835 MODULE_LICENSE("GPL");
1836 MODULE_FIRMWARE(USBDUX_FIRMWARE);