Version:  2.0.40 2.2.26 2.4.37 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 3.16 3.17 3.18

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

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