Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

Linux/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/slab.h>
 84 #include <linux/input.h>
 85 #include <linux/usb.h>
 86 #include <linux/fcntl.h>
 87 #include <linux/compiler.h>
 88 
 89 #include "../comedidev.h"
 90 
 91 #include "comedi_fc.h"
 92 
 93 /* constants for firmware upload and download */
 94 #define USBDUX_FIRMWARE         "usbdux_firmware.bin"
 95 #define USBDUX_FIRMWARE_MAX_LEN 0x2000
 96 #define USBDUX_FIRMWARE_CMD     0xa0
 97 #define VENDOR_DIR_IN           0xc0
 98 #define VENDOR_DIR_OUT          0x40
 99 #define USBDUX_CPU_CS           0xe600
100 
101 /* usbdux bulk transfer commands */
102 #define USBDUX_CMD_MULT_AI      0
103 #define USBDUX_CMD_AO           1
104 #define USBDUX_CMD_DIO_CFG      2
105 #define USBDUX_CMD_DIO_BITS     3
106 #define USBDUX_CMD_SINGLE_AI    4
107 #define USBDUX_CMD_TIMER_RD     5
108 #define USBDUX_CMD_TIMER_WR     6
109 #define USBDUX_CMD_PWM_ON       7
110 #define USBDUX_CMD_PWM_OFF      8
111 
112 #define USBDUX_NUM_AO_CHAN      4
113 
114 /* timeout for the USB-transfer in ms */
115 #define BULK_TIMEOUT            1000
116 
117 /* 300Hz max frequ under PWM */
118 #define MIN_PWM_PERIOD  ((long)(1E9/300))
119 
120 /* Default PWM frequency */
121 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
122 
123 /* Size of one A/D value */
124 #define SIZEADIN          ((sizeof(uint16_t)))
125 
126 /*
127  * Size of the input-buffer IN BYTES
128  * Always multiple of 8 for 8 microframes which is needed in the highspeed mode
129  */
130 #define SIZEINBUF         ((8*SIZEADIN))
131 
132 /* 16 bytes. */
133 #define SIZEINSNBUF       16
134 
135 /* size of one value for the D/A converter: channel and value */
136 #define SIZEDAOUT          ((sizeof(uint8_t)+sizeof(uint16_t)))
137 
138 /*
139  * Size of the output-buffer in bytes
140  * Actually only the first 4 triplets are used but for the
141  * high speed mode we need to pad it to 8 (microframes).
142  */
143 #define SIZEOUTBUF         ((8*SIZEDAOUT))
144 
145 /*
146  * Size of the buffer for the dux commands: just now max size is determined
147  * by the analogue out + command byte + panic bytes...
148  */
149 #define SIZEOFDUXBUFFER    ((8*SIZEDAOUT+2))
150 
151 /* Number of in-URBs which receive the data: min=2 */
152 #define NUMOFINBUFFERSFULL     5
153 
154 /* Number of out-URBs which send the data: min=2 */
155 #define NUMOFOUTBUFFERSFULL    5
156 
157 /* Number of in-URBs which receive the data: min=5 */
158 /* must have more buffers due to buggy USB ctr */
159 #define NUMOFINBUFFERSHIGH     10
160 
161 /* Number of out-URBs which send the data: min=5 */
162 /* must have more buffers due to buggy USB ctr */
163 #define NUMOFOUTBUFFERSHIGH    10
164 
165 /* number of retries to get the right dux command */
166 #define RETRIES 10
167 
168 static const struct comedi_lrange range_usbdux_ai_range = {
169         4, {
170                 BIP_RANGE(4.096),
171                 BIP_RANGE(4.096 / 2),
172                 UNI_RANGE(4.096),
173                 UNI_RANGE(4.096 / 2)
174         }
175 };
176 
177 static const struct comedi_lrange range_usbdux_ao_range = {
178         2, {
179                 BIP_RANGE(4.096),
180                 UNI_RANGE(4.096)
181         }
182 };
183 
184 struct usbdux_private {
185         /* actual number of in-buffers */
186         int n_ai_urbs;
187         /* actual number of out-buffers */
188         int n_ao_urbs;
189         /* ISO-transfer handling: buffers */
190         struct urb **ai_urbs;
191         struct urb **ao_urbs;
192         /* pwm-transfer handling */
193         struct urb *pwm_urb;
194         /* PWM period */
195         unsigned int pwm_period;
196         /* PWM internal delay for the GPIF in the FX2 */
197         uint8_t pwm_delay;
198         /* size of the PWM buffer which holds the bit pattern */
199         int pwm_buf_sz;
200         /* input buffer for the ISO-transfer */
201         uint16_t *in_buf;
202         /* input buffer for single insn */
203         uint16_t *insn_buf;
204 
205         uint8_t ao_chanlist[USBDUX_NUM_AO_CHAN];
206         unsigned int ao_readback[USBDUX_NUM_AO_CHAN];
207 
208         unsigned int high_speed:1;
209         unsigned int ai_cmd_running:1;
210         unsigned int ai_continous:1;
211         unsigned int ao_cmd_running:1;
212         unsigned int ao_continous:1;
213         unsigned int pwm_cmd_running:1;
214 
215         /* number of samples to acquire */
216         int ai_sample_count;
217         int ao_sample_count;
218         /* time between samples in units of the timer */
219         unsigned int ai_timer;
220         unsigned int ao_timer;
221         /* counter between aquisitions */
222         unsigned int ai_counter;
223         unsigned int ao_counter;
224         /* interval in frames/uframes */
225         unsigned int ai_interval;
226         /* commands */
227         uint8_t *dux_commands;
228         struct semaphore sem;
229 };
230 
231 static void usbdux_unlink_urbs(struct urb **urbs, int num_urbs)
232 {
233         int i;
234 
235         for (i = 0; i < num_urbs; i++)
236                 usb_kill_urb(urbs[i]);
237 }
238 
239 static void usbdux_ai_stop(struct comedi_device *dev, int do_unlink)
240 {
241         struct usbdux_private *devpriv = dev->private;
242 
243         if (do_unlink && devpriv->ai_urbs)
244                 usbdux_unlink_urbs(devpriv->ai_urbs, devpriv->n_ai_urbs);
245 
246         devpriv->ai_cmd_running = 0;
247 }
248 
249 static int usbdux_ai_cancel(struct comedi_device *dev,
250                             struct comedi_subdevice *s)
251 {
252         struct usbdux_private *devpriv = dev->private;
253 
254         /* prevent other CPUs from submitting new commands just now */
255         down(&devpriv->sem);
256         /* unlink only if the urb really has been submitted */
257         usbdux_ai_stop(dev, devpriv->ai_cmd_running);
258         up(&devpriv->sem);
259 
260         return 0;
261 }
262 
263 /* analogue IN - interrupt service routine */
264 static void usbduxsub_ai_isoc_irq(struct urb *urb)
265 {
266         struct comedi_device *dev = urb->context;
267         struct comedi_subdevice *s = dev->read_subdev;
268         struct usbdux_private *devpriv = dev->private;
269         int i, err, n;
270 
271         /* first we test if something unusual has just happened */
272         switch (urb->status) {
273         case 0:
274                 /* copy the result in the transfer buffer */
275                 memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF);
276                 break;
277         case -EILSEQ:
278                 /* error in the ISOchronous data */
279                 /* we don't copy the data into the transfer buffer */
280                 /* and recycle the last data byte */
281                 dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
282                 break;
283 
284         case -ECONNRESET:
285         case -ENOENT:
286         case -ESHUTDOWN:
287         case -ECONNABORTED:
288                 /* happens after an unlink command */
289                 if (devpriv->ai_cmd_running) {
290                         s->async->events |= COMEDI_CB_EOA;
291                         s->async->events |= COMEDI_CB_ERROR;
292                         comedi_event(dev, s);
293                         /* stop the transfer w/o unlink */
294                         usbdux_ai_stop(dev, 0);
295                 }
296                 return;
297 
298         default:
299                 /* a real error on the bus */
300                 /* pass error to comedi if we are really running a command */
301                 if (devpriv->ai_cmd_running) {
302                         dev_err(dev->class_dev,
303                                 "Non-zero urb status received in ai intr context: %d\n",
304                                 urb->status);
305                         s->async->events |= COMEDI_CB_EOA;
306                         s->async->events |= COMEDI_CB_ERROR;
307                         comedi_event(dev, s);
308                         /* don't do an unlink here */
309                         usbdux_ai_stop(dev, 0);
310                 }
311                 return;
312         }
313 
314         /*
315          * at this point we are reasonably sure that nothing dodgy has happened
316          * are we running a command?
317          */
318         if (unlikely(!devpriv->ai_cmd_running)) {
319                 /*
320                  * not running a command, do not continue execution if no
321                  * asynchronous command is running in particular not resubmit
322                  */
323                 return;
324         }
325 
326         urb->dev = comedi_to_usb_dev(dev);
327 
328         /* resubmit the urb */
329         err = usb_submit_urb(urb, GFP_ATOMIC);
330         if (unlikely(err < 0)) {
331                 dev_err(dev->class_dev,
332                         "urb resubmit failed in int-context! err=%d\n", err);
333                 if (err == -EL2NSYNC)
334                         dev_err(dev->class_dev,
335                                 "buggy USB host controller or bug in IRQ handler!\n");
336                 s->async->events |= COMEDI_CB_EOA;
337                 s->async->events |= COMEDI_CB_ERROR;
338                 comedi_event(dev, s);
339                 /* don't do an unlink here */
340                 usbdux_ai_stop(dev, 0);
341                 return;
342         }
343 
344         devpriv->ai_counter--;
345         if (likely(devpriv->ai_counter > 0))
346                 return;
347 
348         /* timer zero, transfer measurements to comedi */
349         devpriv->ai_counter = devpriv->ai_timer;
350 
351         /* test, if we transmit only a fixed number of samples */
352         if (!devpriv->ai_continous) {
353                 /* not continuous, fixed number of samples */
354                 devpriv->ai_sample_count--;
355                 /* all samples received? */
356                 if (devpriv->ai_sample_count < 0) {
357                         /* prevent a resubmit next time */
358                         usbdux_ai_stop(dev, 0);
359                         /* say comedi that the acquistion is over */
360                         s->async->events |= COMEDI_CB_EOA;
361                         comedi_event(dev, s);
362                         return;
363                 }
364         }
365         /* get the data from the USB bus and hand it over to comedi */
366         n = s->async->cmd.chanlist_len;
367         for (i = 0; i < n; i++) {
368                 unsigned int range = CR_RANGE(s->async->cmd.chanlist[i]);
369                 uint16_t val = le16_to_cpu(devpriv->in_buf[i]);
370 
371                 /* bipolar data is two's-complement */
372                 if (comedi_range_is_bipolar(s, range))
373                         val ^= ((s->maxdata + 1) >> 1);
374 
375                 /* transfer data */
376                 err = comedi_buf_put(s->async, val);
377                 if (unlikely(err == 0)) {
378                         /* buffer overflow */
379                         usbdux_ai_stop(dev, 0);
380                         return;
381                 }
382         }
383         /* tell comedi that data is there */
384         s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
385         comedi_event(dev, s);
386 }
387 
388 static void usbdux_ao_stop(struct comedi_device *dev, int do_unlink)
389 {
390         struct usbdux_private *devpriv = dev->private;
391 
392         if (do_unlink && devpriv->ao_urbs)
393                 usbdux_unlink_urbs(devpriv->ao_urbs, devpriv->n_ao_urbs);
394 
395         devpriv->ao_cmd_running = 0;
396 }
397 
398 static int usbdux_ao_cancel(struct comedi_device *dev,
399                             struct comedi_subdevice *s)
400 {
401         struct usbdux_private *devpriv = dev->private;
402 
403         /* prevent other CPUs from submitting a command just now */
404         down(&devpriv->sem);
405         /* unlink only if it is really running */
406         usbdux_ao_stop(dev, devpriv->ao_cmd_running);
407         up(&devpriv->sem);
408 
409         return 0;
410 }
411 
412 static void usbduxsub_ao_isoc_irq(struct urb *urb)
413 {
414         struct comedi_device *dev = urb->context;
415         struct comedi_subdevice *s = dev->write_subdev;
416         struct usbdux_private *devpriv = dev->private;
417         uint8_t *datap;
418         int len;
419         int ret;
420         int i;
421 
422         switch (urb->status) {
423         case 0:
424                 /* success */
425                 break;
426 
427         case -ECONNRESET:
428         case -ENOENT:
429         case -ESHUTDOWN:
430         case -ECONNABORTED:
431                 /* after an unlink command, unplug, ... etc */
432                 /* no unlink needed here. Already shutting down. */
433                 if (devpriv->ao_cmd_running) {
434                         s->async->events |= COMEDI_CB_EOA;
435                         comedi_event(dev, s);
436                         usbdux_ao_stop(dev, 0);
437                 }
438                 return;
439 
440         default:
441                 /* a real error */
442                 if (devpriv->ao_cmd_running) {
443                         dev_err(dev->class_dev,
444                                 "Non-zero urb status received in ao intr context: %d\n",
445                                 urb->status);
446                         s->async->events |= COMEDI_CB_ERROR;
447                         s->async->events |= COMEDI_CB_EOA;
448                         comedi_event(dev, s);
449                         /* we do an unlink if we are in the high speed mode */
450                         usbdux_ao_stop(dev, 0);
451                 }
452                 return;
453         }
454 
455         /* are we actually running? */
456         if (!devpriv->ao_cmd_running)
457                 return;
458 
459         /* normal operation: executing a command in this subdevice */
460         devpriv->ao_counter--;
461         if ((int)devpriv->ao_counter <= 0) {
462                 /* timer zero */
463                 devpriv->ao_counter = devpriv->ao_timer;
464 
465                 /* handle non continous acquisition */
466                 if (!devpriv->ao_continous) {
467                         /* fixed number of samples */
468                         devpriv->ao_sample_count--;
469                         if (devpriv->ao_sample_count < 0) {
470                                 /* all samples transmitted */
471                                 usbdux_ao_stop(dev, 0);
472                                 s->async->events |= COMEDI_CB_EOA;
473                                 comedi_event(dev, s);
474                                 /* no resubmit of the urb */
475                                 return;
476                         }
477                 }
478 
479                 /* transmit data to the USB bus */
480                 datap = urb->transfer_buffer;
481                 len = s->async->cmd.chanlist_len;
482                 *datap++ = len;
483                 for (i = 0; i < s->async->cmd.chanlist_len; i++) {
484                         unsigned int chan = devpriv->ao_chanlist[i];
485                         unsigned short val;
486 
487                         ret = comedi_buf_get(s->async, &val);
488                         if (ret < 0) {
489                                 dev_err(dev->class_dev, "buffer underflow\n");
490                                 s->async->events |= (COMEDI_CB_EOA |
491                                                      COMEDI_CB_OVERFLOW);
492                         }
493                         /* pointer to the DA */
494                         *datap++ = val & 0xff;
495                         *datap++ = (val >> 8) & 0xff;
496                         *datap++ = chan << 6;
497                         devpriv->ao_readback[chan] = val;
498 
499                         s->async->events |= COMEDI_CB_BLOCK;
500                         comedi_event(dev, s);
501                 }
502         }
503         urb->transfer_buffer_length = SIZEOUTBUF;
504         urb->dev = comedi_to_usb_dev(dev);
505         urb->status = 0;
506         if (devpriv->ao_cmd_running) {
507                 if (devpriv->high_speed)
508                         urb->interval = 8;      /* uframes */
509                 else
510                         urb->interval = 1;      /* frames */
511                 urb->number_of_packets = 1;
512                 urb->iso_frame_desc[0].offset = 0;
513                 urb->iso_frame_desc[0].length = SIZEOUTBUF;
514                 urb->iso_frame_desc[0].status = 0;
515                 ret = usb_submit_urb(urb, GFP_ATOMIC);
516                 if (ret < 0) {
517                         dev_err(dev->class_dev,
518                                 "ao urb resubm failed in int-cont. ret=%d",
519                                 ret);
520                         if (ret == EL2NSYNC)
521                                 dev_err(dev->class_dev,
522                                         "buggy USB host controller or bug in IRQ handling!\n");
523 
524                         s->async->events |= COMEDI_CB_EOA;
525                         s->async->events |= COMEDI_CB_ERROR;
526                         comedi_event(dev, s);
527                         /* don't do an unlink here */
528                         usbdux_ao_stop(dev, 0);
529                 }
530         }
531 }
532 
533 static int usbdux_submit_urbs(struct comedi_device *dev,
534                               struct urb **urbs, int num_urbs,
535                               int input_urb)
536 {
537         struct usb_device *usb = comedi_to_usb_dev(dev);
538         struct usbdux_private *devpriv = dev->private;
539         struct urb *urb;
540         int ret;
541         int i;
542 
543         /* Submit all URBs and start the transfer on the bus */
544         for (i = 0; i < num_urbs; i++) {
545                 urb = urbs[i];
546 
547                 /* in case of a resubmission after an unlink... */
548                 if (input_urb)
549                         urb->interval = devpriv->ai_interval;
550                 urb->context = dev;
551                 urb->dev = usb;
552                 urb->status = 0;
553                 urb->transfer_flags = URB_ISO_ASAP;
554 
555                 ret = usb_submit_urb(urb, GFP_ATOMIC);
556                 if (ret)
557                         return ret;
558         }
559         return 0;
560 }
561 
562 static int usbdux_ai_cmdtest(struct comedi_device *dev,
563                              struct comedi_subdevice *s, struct comedi_cmd *cmd)
564 {
565         struct usbdux_private *this_usbduxsub = dev->private;
566         int err = 0, i;
567         unsigned int tmp_timer;
568 
569         /* Step 1 : check if triggers are trivially valid */
570 
571         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
572         err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
573         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
574         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
575         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
576 
577         if (err)
578                 return 1;
579 
580         /* Step 2a : make sure trigger sources are unique */
581 
582         err |= cfc_check_trigger_is_unique(cmd->start_src);
583         err |= cfc_check_trigger_is_unique(cmd->stop_src);
584 
585         /* Step 2b : and mutually compatible */
586 
587         if (err)
588                 return 2;
589 
590         /* Step 3: check if arguments are trivially valid */
591 
592         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
593 
594         if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
595                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
596 
597         if (cmd->scan_begin_src == TRIG_TIMER) {
598                 if (this_usbduxsub->high_speed) {
599                         /*
600                          * In high speed mode microframes are possible.
601                          * However, during one microframe we can roughly
602                          * sample one channel. Thus, the more channels
603                          * are in the channel list the more time we need.
604                          */
605                         i = 1;
606                         /* find a power of 2 for the number of channels */
607                         while (i < (cmd->chanlist_len))
608                                 i = i * 2;
609 
610                         err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
611                                                          1000000 / 8 * i);
612                         /* now calc the real sampling rate with all the
613                          * rounding errors */
614                         tmp_timer =
615                             ((unsigned int)(cmd->scan_begin_arg / 125000)) *
616                             125000;
617                 } else {
618                         /* full speed */
619                         /* 1kHz scans every USB frame */
620                         err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
621                                                          1000000);
622                         /*
623                          * calc the real sampling rate with the rounding errors
624                          */
625                         tmp_timer = ((unsigned int)(cmd->scan_begin_arg /
626                                                    1000000)) * 1000000;
627                 }
628                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
629                                                 tmp_timer);
630         }
631 
632         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
633 
634         if (cmd->stop_src == TRIG_COUNT) {
635                 /* any count is allowed */
636         } else {
637                 /* TRIG_NONE */
638                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
639         }
640 
641         if (err)
642                 return 3;
643 
644         return 0;
645 }
646 
647 /*
648  * creates the ADC command for the MAX1271
649  * range is the range value from comedi
650  */
651 static uint8_t create_adc_command(unsigned int chan, unsigned int range)
652 {
653         uint8_t p = (range <= 1);
654         uint8_t r = ((range % 2) == 0);
655 
656         return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
657 }
658 
659 static int send_dux_commands(struct comedi_device *dev, unsigned 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, unsigned 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         uint16_t *p = (uint16_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                 devpriv->ao_chanlist[i] = CR_CHAN(cmd->chanlist[i]);
1045 
1046         /* we count in steps of 1ms (125us) */
1047         /* 125us mode not used yet */
1048         if (0) {                /* (devpriv->high_speed) */
1049                 /* 125us */
1050                 /* timing of the conversion itself: every 125 us */
1051                 devpriv->ao_timer = cmd->convert_arg / 125000;
1052         } else {
1053                 /* 1ms */
1054                 /* timing of the scan: we get all channels at once */
1055                 devpriv->ao_timer = cmd->scan_begin_arg / 1000000;
1056                 if (devpriv->ao_timer < 1) {
1057                         ret = -EINVAL;
1058                         goto ao_cmd_exit;
1059                 }
1060         }
1061 
1062         devpriv->ao_counter = devpriv->ao_timer;
1063 
1064         if (cmd->stop_src == TRIG_COUNT) {
1065                 /* not continuous */
1066                 /* counter */
1067                 /* high speed also scans everything at once */
1068                 if (0) {        /* (devpriv->high_speed) */
1069                         devpriv->ao_sample_count = cmd->stop_arg *
1070                                                    cmd->scan_end_arg;
1071                 } else {
1072                         /* there's no scan as the scan has been */
1073                         /* perf inside the FX2 */
1074                         /* data arrives as one packet */
1075                         devpriv->ao_sample_count = cmd->stop_arg;
1076                 }
1077                 devpriv->ao_continous = 0;
1078         } else {
1079                 /* continous acquisition */
1080                 devpriv->ao_continous = 1;
1081                 devpriv->ao_sample_count = 0;
1082         }
1083 
1084         if (cmd->start_src == TRIG_NOW) {
1085                 /* enable this acquisition operation */
1086                 devpriv->ao_cmd_running = 1;
1087                 ret = usbdux_submit_urbs(dev, devpriv->ao_urbs,
1088                                          devpriv->n_ao_urbs, 0);
1089                 if (ret < 0) {
1090                         devpriv->ao_cmd_running = 0;
1091                         /* fixme: unlink here?? */
1092                         goto ao_cmd_exit;
1093                 }
1094                 s->async->inttrig = NULL;
1095         } else {
1096                 /* TRIG_INT */
1097                 /* submit the urbs later */
1098                 /* wait for an internal signal */
1099                 s->async->inttrig = usbdux_ao_inttrig;
1100         }
1101 
1102 ao_cmd_exit:
1103         up(&devpriv->sem);
1104 
1105         return ret;
1106 }
1107 
1108 static int usbdux_dio_insn_config(struct comedi_device *dev,
1109                                   struct comedi_subdevice *s,
1110                                   struct comedi_insn *insn,
1111                                   unsigned int *data)
1112 {
1113         int ret;
1114 
1115         ret = comedi_dio_insn_config(dev, s, insn, data, 0);
1116         if (ret)
1117                 return ret;
1118 
1119         /*
1120          * We don't tell the firmware here as it would take 8 frames
1121          * to submit the information. We do it in the insn_bits.
1122          */
1123         return insn->n;
1124 }
1125 
1126 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1127                                 struct comedi_subdevice *s,
1128                                 struct comedi_insn *insn,
1129                                 unsigned int *data)
1130 {
1131 
1132         struct usbdux_private *devpriv = dev->private;
1133         int ret;
1134 
1135         down(&devpriv->sem);
1136 
1137         comedi_dio_update_state(s, data);
1138 
1139         /* Always update the hardware. See the (*insn_config). */
1140         devpriv->dux_commands[1] = s->io_bits;
1141         devpriv->dux_commands[2] = s->state;
1142 
1143         /*
1144          * This command also tells the firmware to return
1145          * the digital input lines.
1146          */
1147         ret = send_dux_commands(dev, USBDUX_CMD_DIO_BITS);
1148         if (ret < 0)
1149                 goto dio_exit;
1150         ret = receive_dux_commands(dev, USBDUX_CMD_DIO_BITS);
1151         if (ret < 0)
1152                 goto dio_exit;
1153 
1154         data[1] = le16_to_cpu(devpriv->insn_buf[1]);
1155 
1156 dio_exit:
1157         up(&devpriv->sem);
1158 
1159         return ret ? ret : insn->n;
1160 }
1161 
1162 static int usbdux_counter_read(struct comedi_device *dev,
1163                                struct comedi_subdevice *s,
1164                                struct comedi_insn *insn,
1165                                unsigned int *data)
1166 {
1167         struct usbdux_private *devpriv = dev->private;
1168         unsigned int chan = CR_CHAN(insn->chanspec);
1169         int ret = 0;
1170         int i;
1171 
1172         down(&devpriv->sem);
1173 
1174         for (i = 0; i < insn->n; i++) {
1175                 ret = send_dux_commands(dev, USBDUX_CMD_TIMER_RD);
1176                 if (ret < 0)
1177                         goto counter_read_exit;
1178                 ret = receive_dux_commands(dev, USBDUX_CMD_TIMER_RD);
1179                 if (ret < 0)
1180                         goto counter_read_exit;
1181 
1182                 data[i] = le16_to_cpu(devpriv->insn_buf[chan + 1]);
1183         }
1184 
1185 counter_read_exit:
1186         up(&devpriv->sem);
1187 
1188         return ret ? ret : insn->n;
1189 }
1190 
1191 static int usbdux_counter_write(struct comedi_device *dev,
1192                                 struct comedi_subdevice *s,
1193                                 struct comedi_insn *insn,
1194                                 unsigned int *data)
1195 {
1196         struct usbdux_private *devpriv = dev->private;
1197         unsigned int chan = CR_CHAN(insn->chanspec);
1198         uint16_t *p = (uint16_t *)&devpriv->dux_commands[2];
1199         int ret = 0;
1200         int i;
1201 
1202         down(&devpriv->sem);
1203 
1204         devpriv->dux_commands[1] = chan;
1205 
1206         for (i = 0; i < insn->n; i++) {
1207                 *p = cpu_to_le16(data[i]);
1208 
1209                 ret = send_dux_commands(dev, USBDUX_CMD_TIMER_WR);
1210                 if (ret < 0)
1211                         break;
1212         }
1213 
1214         up(&devpriv->sem);
1215 
1216         return ret ? ret : insn->n;
1217 }
1218 
1219 static int usbdux_counter_config(struct comedi_device *dev,
1220                                  struct comedi_subdevice *s,
1221                                  struct comedi_insn *insn, unsigned int *data)
1222 {
1223         /* nothing to do so far */
1224         return 2;
1225 }
1226 
1227 static void usbduxsub_unlink_pwm_urbs(struct comedi_device *dev)
1228 {
1229         struct usbdux_private *devpriv = dev->private;
1230 
1231         usb_kill_urb(devpriv->pwm_urb);
1232 }
1233 
1234 static void usbdux_pwm_stop(struct comedi_device *dev, int do_unlink)
1235 {
1236         struct usbdux_private *devpriv = dev->private;
1237 
1238         if (do_unlink)
1239                 usbduxsub_unlink_pwm_urbs(dev);
1240 
1241         devpriv->pwm_cmd_running = 0;
1242 }
1243 
1244 static int usbdux_pwm_cancel(struct comedi_device *dev,
1245                              struct comedi_subdevice *s)
1246 {
1247         struct usbdux_private *devpriv = dev->private;
1248         int ret;
1249 
1250         down(&devpriv->sem);
1251         /* unlink only if it is really running */
1252         usbdux_pwm_stop(dev, devpriv->pwm_cmd_running);
1253         ret = send_dux_commands(dev, USBDUX_CMD_PWM_OFF);
1254         up(&devpriv->sem);
1255 
1256         return ret;
1257 }
1258 
1259 static void usbduxsub_pwm_irq(struct urb *urb)
1260 {
1261         struct comedi_device *dev = urb->context;
1262         struct usbdux_private *devpriv = dev->private;
1263         int ret;
1264 
1265         switch (urb->status) {
1266         case 0:
1267                 /* success */
1268                 break;
1269 
1270         case -ECONNRESET:
1271         case -ENOENT:
1272         case -ESHUTDOWN:
1273         case -ECONNABORTED:
1274                 /*
1275                  * after an unlink command, unplug, ... etc
1276                  * no unlink needed here. Already shutting down.
1277                  */
1278                 if (devpriv->pwm_cmd_running)
1279                         usbdux_pwm_stop(dev, 0);
1280 
1281                 return;
1282 
1283         default:
1284                 /* a real error */
1285                 if (devpriv->pwm_cmd_running) {
1286                         dev_err(dev->class_dev,
1287                                 "Non-zero urb status received in pwm intr context: %d\n",
1288                                 urb->status);
1289                         usbdux_pwm_stop(dev, 0);
1290                 }
1291                 return;
1292         }
1293 
1294         /* are we actually running? */
1295         if (!devpriv->pwm_cmd_running)
1296                 return;
1297 
1298         urb->transfer_buffer_length = devpriv->pwm_buf_sz;
1299         urb->dev = comedi_to_usb_dev(dev);
1300         urb->status = 0;
1301         if (devpriv->pwm_cmd_running) {
1302                 ret = usb_submit_urb(urb, GFP_ATOMIC);
1303                 if (ret < 0) {
1304                         dev_err(dev->class_dev,
1305                                 "pwm urb resubm failed in int-cont. ret=%d",
1306                                 ret);
1307                         if (ret == EL2NSYNC)
1308                                 dev_err(dev->class_dev,
1309                                         "buggy USB host controller or bug in IRQ handling!\n");
1310 
1311                         /* don't do an unlink here */
1312                         usbdux_pwm_stop(dev, 0);
1313                 }
1314         }
1315 }
1316 
1317 static int usbduxsub_submit_pwm_urbs(struct comedi_device *dev)
1318 {
1319         struct usb_device *usb = comedi_to_usb_dev(dev);
1320         struct usbdux_private *devpriv = dev->private;
1321         struct urb *urb = devpriv->pwm_urb;
1322 
1323         /* in case of a resubmission after an unlink... */
1324         usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, 4),
1325                           urb->transfer_buffer,
1326                           devpriv->pwm_buf_sz,
1327                           usbduxsub_pwm_irq,
1328                           dev);
1329 
1330         return usb_submit_urb(urb, GFP_ATOMIC);
1331 }
1332 
1333 static int usbdux_pwm_period(struct comedi_device *dev,
1334                              struct comedi_subdevice *s,
1335                              unsigned int period)
1336 {
1337         struct usbdux_private *devpriv = dev->private;
1338         int fx2delay = 255;
1339 
1340         if (period < MIN_PWM_PERIOD) {
1341                 return -EAGAIN;
1342         } else {
1343                 fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
1344                 if (fx2delay > 255)
1345                         return -EAGAIN;
1346         }
1347         devpriv->pwm_delay = fx2delay;
1348         devpriv->pwm_period = period;
1349 
1350         return 0;
1351 }
1352 
1353 static int usbdux_pwm_start(struct comedi_device *dev,
1354                             struct comedi_subdevice *s)
1355 {
1356         struct usbdux_private *devpriv = dev->private;
1357         int ret = 0;
1358 
1359         down(&devpriv->sem);
1360 
1361         if (devpriv->pwm_cmd_running)
1362                 goto pwm_start_exit;
1363 
1364         devpriv->dux_commands[1] = devpriv->pwm_delay;
1365         ret = send_dux_commands(dev, USBDUX_CMD_PWM_ON);
1366         if (ret < 0)
1367                 goto pwm_start_exit;
1368 
1369         /* initialise the buffer */
1370         memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);
1371 
1372         devpriv->pwm_cmd_running = 1;
1373         ret = usbduxsub_submit_pwm_urbs(dev);
1374         if (ret < 0)
1375                 devpriv->pwm_cmd_running = 0;
1376 
1377 pwm_start_exit:
1378         up(&devpriv->sem);
1379 
1380         return ret;
1381 }
1382 
1383 static void usbdux_pwm_pattern(struct comedi_device *dev,
1384                                struct comedi_subdevice *s,
1385                                unsigned int chan,
1386                                unsigned int value,
1387                                unsigned int sign)
1388 {
1389         struct usbdux_private *devpriv = dev->private;
1390         char pwm_mask = (1 << chan);    /* DIO bit for the PWM data */
1391         char sgn_mask = (16 << chan);   /* DIO bit for the sign */
1392         char *buf = (char *)(devpriv->pwm_urb->transfer_buffer);
1393         int szbuf = devpriv->pwm_buf_sz;
1394         int i;
1395 
1396         for (i = 0; i < szbuf; i++) {
1397                 char c = *buf;
1398 
1399                 c &= ~pwm_mask;
1400                 if (i < value)
1401                         c |= pwm_mask;
1402                 if (!sign)
1403                         c &= ~sgn_mask;
1404                 else
1405                         c |= sgn_mask;
1406                 *buf++ = c;
1407         }
1408 }
1409 
1410 static int usbdux_pwm_write(struct comedi_device *dev,
1411                             struct comedi_subdevice *s,
1412                             struct comedi_insn *insn,
1413                             unsigned int *data)
1414 {
1415         unsigned int chan = CR_CHAN(insn->chanspec);
1416 
1417         /*
1418          * It doesn't make sense to support more than one value here
1419          * because it would just overwrite the PWM buffer.
1420          */
1421         if (insn->n != 1)
1422                 return -EINVAL;
1423 
1424         /*
1425          * The sign is set via a special INSN only, this gives us 8 bits
1426          * for normal operation, sign is 0 by default.
1427          */
1428         usbdux_pwm_pattern(dev, s, chan, data[0], 0);
1429 
1430         return insn->n;
1431 }
1432 
1433 static int usbdux_pwm_config(struct comedi_device *dev,
1434                              struct comedi_subdevice *s,
1435                              struct comedi_insn *insn,
1436                              unsigned int *data)
1437 {
1438         struct usbdux_private *devpriv = dev->private;
1439         unsigned int chan = CR_CHAN(insn->chanspec);
1440 
1441         switch (data[0]) {
1442         case INSN_CONFIG_ARM:
1443                 /*
1444                  * if not zero the PWM is limited to a certain time which is
1445                  * not supported here
1446                  */
1447                 if (data[1] != 0)
1448                         return -EINVAL;
1449                 return usbdux_pwm_start(dev, s);
1450         case INSN_CONFIG_DISARM:
1451                 return usbdux_pwm_cancel(dev, s);
1452         case INSN_CONFIG_GET_PWM_STATUS:
1453                 data[1] = devpriv->pwm_cmd_running;
1454                 return 0;
1455         case INSN_CONFIG_PWM_SET_PERIOD:
1456                 return usbdux_pwm_period(dev, s, data[1]);
1457         case INSN_CONFIG_PWM_GET_PERIOD:
1458                 data[1] = devpriv->pwm_period;
1459                 return 0;
1460         case INSN_CONFIG_PWM_SET_H_BRIDGE:
1461                 /*
1462                  * data[1] = value
1463                  * data[2] = sign (for a relay)
1464                  */
1465                 usbdux_pwm_pattern(dev, s, chan, data[1], (data[2] != 0));
1466                 return 0;
1467         case INSN_CONFIG_PWM_GET_H_BRIDGE:
1468                 /* values are not kept in this driver, nothing to return here */
1469                 return -EINVAL;
1470         }
1471         return -EINVAL;
1472 }
1473 
1474 static int usbdux_firmware_upload(struct comedi_device *dev,
1475                                   const u8 *data, size_t size,
1476                                   unsigned long context)
1477 {
1478         struct usb_device *usb = comedi_to_usb_dev(dev);
1479         uint8_t *buf;
1480         uint8_t *tmp;
1481         int ret;
1482 
1483         if (!data)
1484                 return 0;
1485 
1486         if (size > USBDUX_FIRMWARE_MAX_LEN) {
1487                 dev_err(dev->class_dev,
1488                         "usbdux firmware binary it too large for FX2.\n");
1489                 return -ENOMEM;
1490         }
1491 
1492         /* we generate a local buffer for the firmware */
1493         buf = kmemdup(data, size, GFP_KERNEL);
1494         if (!buf)
1495                 return -ENOMEM;
1496 
1497         /* we need a malloc'ed buffer for usb_control_msg() */
1498         tmp = kmalloc(1, GFP_KERNEL);
1499         if (!tmp) {
1500                 kfree(buf);
1501                 return -ENOMEM;
1502         }
1503 
1504         /* stop the current firmware on the device */
1505         *tmp = 1;       /* 7f92 to one */
1506         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1507                               USBDUX_FIRMWARE_CMD,
1508                               VENDOR_DIR_OUT,
1509                               USBDUX_CPU_CS, 0x0000,
1510                               tmp, 1,
1511                               BULK_TIMEOUT);
1512         if (ret < 0) {
1513                 dev_err(dev->class_dev, "can not stop firmware\n");
1514                 goto done;
1515         }
1516 
1517         /* upload the new firmware to the device */
1518         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1519                               USBDUX_FIRMWARE_CMD,
1520                               VENDOR_DIR_OUT,
1521                               0, 0x0000,
1522                               buf, size,
1523                               BULK_TIMEOUT);
1524         if (ret < 0) {
1525                 dev_err(dev->class_dev, "firmware upload failed\n");
1526                 goto done;
1527         }
1528 
1529         /* start the new firmware on the device */
1530         *tmp = 0;       /* 7f92 to zero */
1531         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1532                               USBDUX_FIRMWARE_CMD,
1533                               VENDOR_DIR_OUT,
1534                               USBDUX_CPU_CS, 0x0000,
1535                               tmp, 1,
1536                               BULK_TIMEOUT);
1537         if (ret < 0)
1538                 dev_err(dev->class_dev, "can not start firmware\n");
1539 
1540 done:
1541         kfree(tmp);
1542         kfree(buf);
1543         return ret;
1544 }
1545 
1546 static int usbdux_alloc_usb_buffers(struct comedi_device *dev)
1547 {
1548         struct usb_device *usb = comedi_to_usb_dev(dev);
1549         struct usbdux_private *devpriv = dev->private;
1550         struct urb *urb;
1551         int i;
1552 
1553         devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1554         devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL);
1555         devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1556         devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(void *),
1557                                    GFP_KERNEL);
1558         devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(void *),
1559                                    GFP_KERNEL);
1560         if (!devpriv->dux_commands || !devpriv->in_buf || !devpriv->insn_buf ||
1561             !devpriv->ai_urbs || !devpriv->ao_urbs)
1562                 return -ENOMEM;
1563 
1564         for (i = 0; i < devpriv->n_ai_urbs; i++) {
1565                 /* one frame: 1ms */
1566                 urb = usb_alloc_urb(1, GFP_KERNEL);
1567                 if (!urb)
1568                         return -ENOMEM;
1569                 devpriv->ai_urbs[i] = urb;
1570 
1571                 urb->dev = usb;
1572                 urb->context = dev;
1573                 urb->pipe = usb_rcvisocpipe(usb, 6);
1574                 urb->transfer_flags = URB_ISO_ASAP;
1575                 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1576                 if (!urb->transfer_buffer)
1577                         return -ENOMEM;
1578 
1579                 urb->complete = usbduxsub_ai_isoc_irq;
1580                 urb->number_of_packets = 1;
1581                 urb->transfer_buffer_length = SIZEINBUF;
1582                 urb->iso_frame_desc[0].offset = 0;
1583                 urb->iso_frame_desc[0].length = SIZEINBUF;
1584         }
1585 
1586         for (i = 0; i < devpriv->n_ao_urbs; i++) {
1587                 /* one frame: 1ms */
1588                 urb = usb_alloc_urb(1, GFP_KERNEL);
1589                 if (!urb)
1590                         return -ENOMEM;
1591                 devpriv->ao_urbs[i] = urb;
1592 
1593                 urb->dev = usb;
1594                 urb->context = dev;
1595                 urb->pipe = usb_sndisocpipe(usb, 2);
1596                 urb->transfer_flags = URB_ISO_ASAP;
1597                 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1598                 if (!urb->transfer_buffer)
1599                         return -ENOMEM;
1600 
1601                 urb->complete = usbduxsub_ao_isoc_irq;
1602                 urb->number_of_packets = 1;
1603                 urb->transfer_buffer_length = SIZEOUTBUF;
1604                 urb->iso_frame_desc[0].offset = 0;
1605                 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1606                 if (devpriv->high_speed)
1607                         urb->interval = 8;      /* uframes */
1608                 else
1609                         urb->interval = 1;      /* frames */
1610         }
1611 
1612         /* pwm */
1613         if (devpriv->pwm_buf_sz) {
1614                 urb = usb_alloc_urb(0, GFP_KERNEL);
1615                 if (!urb)
1616                         return -ENOMEM;
1617                 devpriv->pwm_urb = urb;
1618 
1619                 /* max bulk ep size in high speed */
1620                 urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz,
1621                                                GFP_KERNEL);
1622                 if (!urb->transfer_buffer)
1623                         return -ENOMEM;
1624         }
1625 
1626         return 0;
1627 }
1628 
1629 static void usbdux_free_usb_buffers(struct comedi_device *dev)
1630 {
1631         struct usbdux_private *devpriv = dev->private;
1632         struct urb *urb;
1633         int i;
1634 
1635         urb = devpriv->pwm_urb;
1636         if (urb) {
1637                 kfree(urb->transfer_buffer);
1638                 usb_free_urb(urb);
1639         }
1640         if (devpriv->ao_urbs) {
1641                 for (i = 0; i < devpriv->n_ao_urbs; i++) {
1642                         urb = devpriv->ao_urbs[i];
1643                         if (urb) {
1644                                 kfree(urb->transfer_buffer);
1645                                 usb_free_urb(urb);
1646                         }
1647                 }
1648                 kfree(devpriv->ao_urbs);
1649         }
1650         if (devpriv->ai_urbs) {
1651                 for (i = 0; i < devpriv->n_ai_urbs; i++) {
1652                         urb = devpriv->ai_urbs[i];
1653                         if (urb) {
1654                                 kfree(urb->transfer_buffer);
1655                                 usb_free_urb(urb);
1656                         }
1657                 }
1658                 kfree(devpriv->ai_urbs);
1659         }
1660         kfree(devpriv->insn_buf);
1661         kfree(devpriv->in_buf);
1662         kfree(devpriv->dux_commands);
1663 }
1664 
1665 static int usbdux_auto_attach(struct comedi_device *dev,
1666                               unsigned long context_unused)
1667 {
1668         struct usb_interface *intf = comedi_to_usb_interface(dev);
1669         struct usb_device *usb = comedi_to_usb_dev(dev);
1670         struct usbdux_private *devpriv;
1671         struct comedi_subdevice *s;
1672         int ret;
1673 
1674         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1675         if (!devpriv)
1676                 return -ENOMEM;
1677 
1678         sema_init(&devpriv->sem, 1);
1679 
1680         usb_set_intfdata(intf, devpriv);
1681 
1682         devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1683         if (devpriv->high_speed) {
1684                 devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH;
1685                 devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH;
1686                 devpriv->pwm_buf_sz = 512;
1687         } else {
1688                 devpriv->n_ai_urbs = NUMOFINBUFFERSFULL;
1689                 devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL;
1690         }
1691 
1692         ret = usbdux_alloc_usb_buffers(dev);
1693         if (ret)
1694                 return ret;
1695 
1696         /* setting to alternate setting 3: enabling iso ep and bulk ep. */
1697         ret = usb_set_interface(usb, intf->altsetting->desc.bInterfaceNumber,
1698                                 3);
1699         if (ret < 0) {
1700                 dev_err(dev->class_dev,
1701                         "could not set alternate setting 3 in high speed\n");
1702                 return ret;
1703         }
1704 
1705         ret = comedi_load_firmware(dev, &usb->dev, USBDUX_FIRMWARE,
1706                                    usbdux_firmware_upload, 0);
1707         if (ret < 0)
1708                 return ret;
1709 
1710         ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 5 : 4);
1711         if (ret)
1712                 return ret;
1713 
1714         /* Analog Input subdevice */
1715         s = &dev->subdevices[0];
1716         dev->read_subdev = s;
1717         s->type         = COMEDI_SUBD_AI;
1718         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
1719         s->n_chan       = 8;
1720         s->maxdata      = 0x0fff;
1721         s->len_chanlist = 8;
1722         s->range_table  = &range_usbdux_ai_range;
1723         s->insn_read    = usbdux_ai_insn_read;
1724         s->do_cmdtest   = usbdux_ai_cmdtest;
1725         s->do_cmd       = usbdux_ai_cmd;
1726         s->cancel       = usbdux_ai_cancel;
1727 
1728         /* Analog Output subdevice */
1729         s = &dev->subdevices[1];
1730         dev->write_subdev = s;
1731         s->type         = COMEDI_SUBD_AO;
1732         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1733         s->n_chan       = USBDUX_NUM_AO_CHAN;
1734         s->maxdata      = 0x0fff;
1735         s->len_chanlist = s->n_chan;
1736         s->range_table  = &range_usbdux_ao_range;
1737         s->do_cmdtest   = usbdux_ao_cmdtest;
1738         s->do_cmd       = usbdux_ao_cmd;
1739         s->cancel       = usbdux_ao_cancel;
1740         s->insn_read    = usbdux_ao_insn_read;
1741         s->insn_write   = usbdux_ao_insn_write;
1742 
1743         /* Digital I/O subdevice */
1744         s = &dev->subdevices[2];
1745         s->type         = COMEDI_SUBD_DIO;
1746         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1747         s->n_chan       = 8;
1748         s->maxdata      = 1;
1749         s->range_table  = &range_digital;
1750         s->insn_bits    = usbdux_dio_insn_bits;
1751         s->insn_config  = usbdux_dio_insn_config;
1752 
1753         /* Counter subdevice */
1754         s = &dev->subdevices[3];
1755         s->type         = COMEDI_SUBD_COUNTER;
1756         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1757         s->n_chan       = 4;
1758         s->maxdata      = 0xffff;
1759         s->insn_read    = usbdux_counter_read;
1760         s->insn_write   = usbdux_counter_write;
1761         s->insn_config  = usbdux_counter_config;
1762 
1763         if (devpriv->high_speed) {
1764                 /* PWM subdevice */
1765                 s = &dev->subdevices[4];
1766                 s->type         = COMEDI_SUBD_PWM;
1767                 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1768                 s->n_chan       = 8;
1769                 s->maxdata      = devpriv->pwm_buf_sz;
1770                 s->insn_write   = usbdux_pwm_write;
1771                 s->insn_config  = usbdux_pwm_config;
1772 
1773                 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1774         }
1775 
1776         return 0;
1777 }
1778 
1779 static void usbdux_detach(struct comedi_device *dev)
1780 {
1781         struct usb_interface *intf = comedi_to_usb_interface(dev);
1782         struct usbdux_private *devpriv = dev->private;
1783 
1784         usb_set_intfdata(intf, NULL);
1785 
1786         if (!devpriv)
1787                 return;
1788 
1789         down(&devpriv->sem);
1790 
1791         /* force unlink all urbs */
1792         usbdux_pwm_stop(dev, 1);
1793         usbdux_ao_stop(dev, 1);
1794         usbdux_ai_stop(dev, 1);
1795 
1796         usbdux_free_usb_buffers(dev);
1797 
1798         up(&devpriv->sem);
1799 }
1800 
1801 static struct comedi_driver usbdux_driver = {
1802         .driver_name    = "usbdux",
1803         .module         = THIS_MODULE,
1804         .auto_attach    = usbdux_auto_attach,
1805         .detach         = usbdux_detach,
1806 };
1807 
1808 static int usbdux_usb_probe(struct usb_interface *intf,
1809                             const struct usb_device_id *id)
1810 {
1811         return comedi_usb_auto_config(intf, &usbdux_driver, 0);
1812 }
1813 
1814 static const struct usb_device_id usbdux_usb_table[] = {
1815         { USB_DEVICE(0x13d8, 0x0001) },
1816         { USB_DEVICE(0x13d8, 0x0002) },
1817         { }
1818 };
1819 MODULE_DEVICE_TABLE(usb, usbdux_usb_table);
1820 
1821 static struct usb_driver usbdux_usb_driver = {
1822         .name           = "usbdux",
1823         .probe          = usbdux_usb_probe,
1824         .disconnect     = comedi_usb_auto_unconfig,
1825         .id_table       = usbdux_usb_table,
1826 };
1827 module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver);
1828 
1829 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1830 MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com");
1831 MODULE_LICENSE("GPL");
1832 MODULE_FIRMWARE(USBDUX_FIRMWARE);
1833 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us