Version:  2.0.40 2.2.26 2.4.37 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 3.19 4.0

Linux/drivers/staging/comedi/drivers/usbduxfast.c

  1 /*
  2  *  Copyright (C) 2004-2014 Bernd Porr, mail@berndporr.me.uk
  3  *
  4  * This program is free software; you can redistribute it and/or modify
  5  * it under the terms of the GNU General Public License as published by
  6  * the Free Software Foundation; either version 2 of the License, or
  7  * (at your option) any later version.
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12  * GNU General Public License for more details.
 13  */
 14 
 15 /*
 16  * Driver: usbduxfast
 17  * Description: University of Stirling USB DAQ & INCITE Technology Limited
 18  * Devices: [ITL] USB-DUX-FAST (usbduxfast)
 19  * Author: Bernd Porr <mail@berndporr.me.uk>
 20  * Updated: 10 Oct 2014
 21  * Status: stable
 22  */
 23 
 24 /*
 25  * I must give credit here to Chris Baugher who
 26  * wrote the driver for AT-MIO-16d. I used some parts of this
 27  * driver. I also must give credits to David Brownell
 28  * who supported me with the USB development.
 29  *
 30  * Bernd Porr
 31  *
 32  *
 33  * Revision history:
 34  * 0.9: Dropping the first data packet which seems to be from the last transfer.
 35  *      Buffer overflows in the FX2 are handed over to comedi.
 36  * 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
 37  *       Added insn command basically for testing. Sample rate is
 38  *       1MHz/16ch=62.5kHz
 39  * 0.99: Ian Abbott pointed out a bug which has been corrected. Thanks!
 40  * 0.99a: added external trigger.
 41  * 1.00: added firmware kernel request to the driver which fixed
 42  *       udev coldplug problem
 43  */
 44 
 45 #include <linux/kernel.h>
 46 #include <linux/module.h>
 47 #include <linux/slab.h>
 48 #include <linux/input.h>
 49 #include <linux/fcntl.h>
 50 #include <linux/compiler.h>
 51 #include "comedi_fc.h"
 52 #include "../comedi_usb.h"
 53 
 54 /*
 55  * timeout for the USB-transfer
 56  */
 57 #define EZTIMEOUT       30
 58 
 59 /*
 60  * constants for "firmware" upload and download
 61  */
 62 #define FIRMWARE                "usbduxfast_firmware.bin"
 63 #define FIRMWARE_MAX_LEN        0x2000
 64 #define USBDUXFASTSUB_FIRMWARE  0xA0
 65 #define VENDOR_DIR_IN           0xC0
 66 #define VENDOR_DIR_OUT          0x40
 67 
 68 /*
 69  * internal addresses of the 8051 processor
 70  */
 71 #define USBDUXFASTSUB_CPUCS     0xE600
 72 
 73 /*
 74  * max lenghth of the transfer-buffer for software upload
 75  */
 76 #define TB_LEN  0x2000
 77 
 78 /*
 79  * input endpoint number
 80  */
 81 #define BULKINEP        6
 82 
 83 /*
 84  * endpoint for the A/D channellist: bulk OUT
 85  */
 86 #define CHANNELLISTEP   4
 87 
 88 /*
 89  * number of channels
 90  */
 91 #define NUMCHANNELS     32
 92 
 93 /*
 94  * size of the waveform descriptor
 95  */
 96 #define WAVESIZE        0x20
 97 
 98 /*
 99  * size of one A/D value
100  */
101 #define SIZEADIN        (sizeof(int16_t))
102 
103 /*
104  * size of the input-buffer IN BYTES
105  */
106 #define SIZEINBUF       512
107 
108 /*
109  * 16 bytes
110  */
111 #define SIZEINSNBUF     512
112 
113 /*
114  * size of the buffer for the dux commands in bytes
115  */
116 #define SIZEOFDUXBUF    256
117 
118 /*
119  * number of in-URBs which receive the data: min=5
120  */
121 #define NUMOFINBUFFERSHIGH      10
122 
123 /*
124  * min delay steps for more than one channel
125  * basically when the mux gives up ;-)
126  *
127  * steps at 30MHz in the FX2
128  */
129 #define MIN_SAMPLING_PERIOD     9
130 
131 /*
132  * max number of 1/30MHz delay steps
133  */
134 #define MAX_SAMPLING_PERIOD     500
135 
136 /*
137  * number of received packets to ignore before we start handing data
138  * over to comedi, it's quad buffering and we have to ignore 4 packets
139  */
140 #define PACKETS_TO_IGNORE       4
141 
142 /*
143  * comedi constants
144  */
145 static const struct comedi_lrange range_usbduxfast_ai_range = {
146         2, {
147                 BIP_RANGE(0.75),
148                 BIP_RANGE(0.5)
149         }
150 };
151 
152 /*
153  * private structure of one subdevice
154  *
155  * this is the structure which holds all the data of this driver
156  * one sub device just now: A/D
157  */
158 struct usbduxfast_private {
159         struct urb *urb;        /* BULK-transfer handling: urb */
160         uint8_t *duxbuf;
161         int8_t *inbuf;
162         short int ai_cmd_running;       /* asynchronous command is running */
163         int ignore;             /* counter which ignores the first
164                                    buffers */
165         struct semaphore sem;
166 };
167 
168 /*
169  * bulk transfers to usbduxfast
170  */
171 #define SENDADCOMMANDS            0
172 #define SENDINITEP6               1
173 
174 static int usbduxfast_send_cmd(struct comedi_device *dev, int cmd_type)
175 {
176         struct usb_device *usb = comedi_to_usb_dev(dev);
177         struct usbduxfast_private *devpriv = dev->private;
178         int nsent;
179         int ret;
180 
181         devpriv->duxbuf[0] = cmd_type;
182 
183         ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, CHANNELLISTEP),
184                            devpriv->duxbuf, SIZEOFDUXBUF,
185                            &nsent, 10000);
186         if (ret < 0)
187                 dev_err(dev->class_dev,
188                         "could not transmit command to the usb-device, err=%d\n",
189                         ret);
190         return ret;
191 }
192 
193 static void usbduxfast_cmd_data(struct comedi_device *dev, int index,
194                                 uint8_t len, uint8_t op, uint8_t out,
195                                 uint8_t log)
196 {
197         struct usbduxfast_private *devpriv = dev->private;
198 
199         /* Set the GPIF bytes, the first byte is the command byte */
200         devpriv->duxbuf[1 + 0x00 + index] = len;
201         devpriv->duxbuf[1 + 0x08 + index] = op;
202         devpriv->duxbuf[1 + 0x10 + index] = out;
203         devpriv->duxbuf[1 + 0x18 + index] = log;
204 }
205 
206 static int usbduxfast_ai_stop(struct comedi_device *dev, int do_unlink)
207 {
208         struct usbduxfast_private *devpriv = dev->private;
209 
210         /* stop aquistion */
211         devpriv->ai_cmd_running = 0;
212 
213         if (do_unlink && devpriv->urb) {
214                 /* kill the running transfer */
215                 usb_kill_urb(devpriv->urb);
216         }
217 
218         return 0;
219 }
220 
221 static int usbduxfast_ai_cancel(struct comedi_device *dev,
222                                 struct comedi_subdevice *s)
223 {
224         struct usbduxfast_private *devpriv = dev->private;
225         int ret;
226 
227         if (!devpriv)
228                 return -EFAULT;
229 
230         down(&devpriv->sem);
231         ret = usbduxfast_ai_stop(dev, 1);
232         up(&devpriv->sem);
233 
234         return ret;
235 }
236 
237 static void usbduxfast_ai_handle_urb(struct comedi_device *dev,
238                                      struct comedi_subdevice *s,
239                                      struct urb *urb)
240 {
241         struct usbduxfast_private *devpriv = dev->private;
242         struct comedi_async *async = s->async;
243         struct comedi_cmd *cmd = &async->cmd;
244         int ret;
245 
246         if (devpriv->ignore) {
247                 devpriv->ignore--;
248         } else {
249                 unsigned int nsamples;
250 
251                 nsamples = comedi_bytes_to_samples(s, urb->actual_length);
252                 nsamples = comedi_nsamples_left(s, nsamples);
253                 comedi_buf_write_samples(s, urb->transfer_buffer, nsamples);
254 
255                 if (cmd->stop_src == TRIG_COUNT &&
256                     async->scans_done >= cmd->stop_arg)
257                         async->events |= COMEDI_CB_EOA;
258         }
259 
260         /* if command is still running, resubmit urb for BULK transfer */
261         if (!(async->events & COMEDI_CB_CANCEL_MASK)) {
262                 urb->dev = comedi_to_usb_dev(dev);
263                 urb->status = 0;
264                 ret = usb_submit_urb(urb, GFP_ATOMIC);
265                 if (ret < 0) {
266                         dev_err(dev->class_dev, "urb resubm failed: %d", ret);
267                         async->events |= COMEDI_CB_ERROR;
268                 }
269         }
270 }
271 
272 static void usbduxfast_ai_interrupt(struct urb *urb)
273 {
274         struct comedi_device *dev = urb->context;
275         struct comedi_subdevice *s = dev->read_subdev;
276         struct comedi_async *async = s->async;
277         struct usbduxfast_private *devpriv = dev->private;
278 
279         /* exit if not running a command, do not resubmit urb */
280         if (!devpriv->ai_cmd_running)
281                 return;
282 
283         switch (urb->status) {
284         case 0:
285                 usbduxfast_ai_handle_urb(dev, s, urb);
286                 break;
287 
288         case -ECONNRESET:
289         case -ENOENT:
290         case -ESHUTDOWN:
291         case -ECONNABORTED:
292                 /* after an unlink command, unplug, ... etc */
293                 async->events |= COMEDI_CB_ERROR;
294                 break;
295 
296         default:
297                 /* a real error */
298                 dev_err(dev->class_dev,
299                         "non-zero urb status received in ai intr context: %d\n",
300                         urb->status);
301                 async->events |= COMEDI_CB_ERROR;
302                 break;
303         }
304 
305         /*
306          * comedi_handle_events() cannot be used in this driver. The (*cancel)
307          * operation would unlink the urb.
308          */
309         if (async->events & COMEDI_CB_CANCEL_MASK)
310                 usbduxfast_ai_stop(dev, 0);
311 
312         comedi_event(dev, s);
313 }
314 
315 static int usbduxfast_submit_urb(struct comedi_device *dev)
316 {
317         struct usb_device *usb = comedi_to_usb_dev(dev);
318         struct usbduxfast_private *devpriv = dev->private;
319         int ret;
320 
321         if (!devpriv)
322                 return -EFAULT;
323 
324         usb_fill_bulk_urb(devpriv->urb, usb, usb_rcvbulkpipe(usb, BULKINEP),
325                           devpriv->inbuf, SIZEINBUF,
326                           usbduxfast_ai_interrupt, dev);
327 
328         ret = usb_submit_urb(devpriv->urb, GFP_ATOMIC);
329         if (ret) {
330                 dev_err(dev->class_dev, "usb_submit_urb error %d\n", ret);
331                 return ret;
332         }
333         return 0;
334 }
335 
336 static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
337                                  struct comedi_subdevice *s,
338                                  struct comedi_cmd *cmd)
339 {
340         int err = 0;
341         long int steps, tmp;
342         int min_sample_period;
343 
344         /* Step 1 : check if triggers are trivially valid */
345 
346         err |= cfc_check_trigger_src(&cmd->start_src,
347                                         TRIG_NOW | TRIG_EXT | TRIG_INT);
348         err |= cfc_check_trigger_src(&cmd->scan_begin_src,
349                                         TRIG_FOLLOW | TRIG_EXT);
350         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
351         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
352         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
353 
354         if (err)
355                 return 1;
356 
357         /* Step 2a : make sure trigger sources are unique */
358 
359         err |= cfc_check_trigger_is_unique(cmd->start_src);
360         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
361         err |= cfc_check_trigger_is_unique(cmd->convert_src);
362         err |= cfc_check_trigger_is_unique(cmd->stop_src);
363 
364         /* Step 2b : and mutually compatible */
365 
366         /* can't have external stop and start triggers at once */
367         if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
368                 err |= -EINVAL;
369 
370         if (err)
371                 return 2;
372 
373         /* Step 3: check if arguments are trivially valid */
374 
375         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
376 
377         if (!cmd->chanlist_len)
378                 err |= -EINVAL;
379 
380         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
381 
382         if (cmd->chanlist_len == 1)
383                 min_sample_period = 1;
384         else
385                 min_sample_period = MIN_SAMPLING_PERIOD;
386 
387         if (cmd->convert_src == TRIG_TIMER) {
388                 steps = cmd->convert_arg * 30;
389                 if (steps < (min_sample_period * 1000))
390                         steps = min_sample_period * 1000;
391 
392                 if (steps > (MAX_SAMPLING_PERIOD * 1000))
393                         steps = MAX_SAMPLING_PERIOD * 1000;
394 
395                 /* calc arg again */
396                 tmp = steps / 30;
397                 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, tmp);
398         }
399 
400         /* stop source */
401         switch (cmd->stop_src) {
402         case TRIG_COUNT:
403                 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
404                 break;
405         case TRIG_NONE:
406                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
407                 break;
408                 /*
409                  * TRIG_EXT doesn't care since it doesn't trigger
410                  * off a numbered channel
411                  */
412         default:
413                 break;
414         }
415 
416         if (err)
417                 return 3;
418 
419         /* step 4: fix up any arguments */
420 
421         return 0;
422 
423 }
424 
425 static int usbduxfast_ai_inttrig(struct comedi_device *dev,
426                                  struct comedi_subdevice *s,
427                                  unsigned int trig_num)
428 {
429         struct usbduxfast_private *devpriv = dev->private;
430         struct comedi_cmd *cmd = &s->async->cmd;
431         int ret;
432 
433         if (!devpriv)
434                 return -EFAULT;
435 
436         if (trig_num != cmd->start_arg)
437                 return -EINVAL;
438 
439         down(&devpriv->sem);
440 
441         if (!devpriv->ai_cmd_running) {
442                 devpriv->ai_cmd_running = 1;
443                 ret = usbduxfast_submit_urb(dev);
444                 if (ret < 0) {
445                         dev_err(dev->class_dev, "urbSubmit: err=%d\n", ret);
446                         devpriv->ai_cmd_running = 0;
447                         up(&devpriv->sem);
448                         return ret;
449                 }
450                 s->async->inttrig = NULL;
451         } else {
452                 dev_err(dev->class_dev, "ai is already running\n");
453         }
454         up(&devpriv->sem);
455         return 1;
456 }
457 
458 static int usbduxfast_ai_cmd(struct comedi_device *dev,
459                              struct comedi_subdevice *s)
460 {
461         struct usbduxfast_private *devpriv = dev->private;
462         struct comedi_cmd *cmd = &s->async->cmd;
463         unsigned int chan, gain, rngmask = 0xff;
464         int i, j, ret;
465         int result;
466         long steps, steps_tmp;
467 
468         if (!devpriv)
469                 return -EFAULT;
470 
471         down(&devpriv->sem);
472         if (devpriv->ai_cmd_running) {
473                 dev_err(dev->class_dev, "ai_cmd not possible\n");
474                 up(&devpriv->sem);
475                 return -EBUSY;
476         }
477 
478         /*
479          * ignore the first buffers from the device if there
480          * is an error condition
481          */
482         devpriv->ignore = PACKETS_TO_IGNORE;
483 
484         gain = CR_RANGE(cmd->chanlist[0]);
485         for (i = 0; i < cmd->chanlist_len; ++i) {
486                 chan = CR_CHAN(cmd->chanlist[i]);
487                 if (chan != i) {
488                         dev_err(dev->class_dev,
489                                 "channels are not consecutive\n");
490                         up(&devpriv->sem);
491                         return -EINVAL;
492                 }
493                 if ((gain != CR_RANGE(cmd->chanlist[i]))
494                         && (cmd->chanlist_len > 3)) {
495                         dev_err(dev->class_dev,
496                                 "gain must be the same for all channels\n");
497                         up(&devpriv->sem);
498                         return -EINVAL;
499                 }
500                 if (i >= NUMCHANNELS) {
501                         dev_err(dev->class_dev, "chanlist too long\n");
502                         break;
503                 }
504         }
505         steps = 0;
506         if (cmd->convert_src == TRIG_TIMER)
507                 steps = (cmd->convert_arg * 30) / 1000;
508 
509         if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
510                 dev_err(dev->class_dev,
511                         "steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n",
512                         steps, cmd->scan_begin_arg);
513                 up(&devpriv->sem);
514                 return -EINVAL;
515         }
516         if (steps > MAX_SAMPLING_PERIOD) {
517                 dev_err(dev->class_dev, "sampling rate too low\n");
518                 up(&devpriv->sem);
519                 return -EINVAL;
520         }
521         if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
522             && (cmd->chanlist_len != 16)) {
523                 dev_err(dev->class_dev,
524                         "TRIG_EXT only with 1 or 16 channels possible\n");
525                 up(&devpriv->sem);
526                 return -EINVAL;
527         }
528 
529         switch (cmd->chanlist_len) {
530         case 1:
531                 /*
532                  * one channel
533                  */
534 
535                 if (CR_RANGE(cmd->chanlist[0]) > 0)
536                         rngmask = 0xff - 0x04;
537                 else
538                         rngmask = 0xff;
539 
540                 /*
541                  * for external trigger: looping in this state until
542                  * the RDY0 pin becomes zero
543                  */
544 
545                 /* we loop here until ready has been set */
546                 if (cmd->start_src == TRIG_EXT) {
547                         /* branch back to state 0 */
548                         /* deceision state w/o data */
549                         /* RDY0 = 0 */
550                         usbduxfast_cmd_data(dev, 0, 0x01, 0x01, rngmask, 0x00);
551                 } else {        /* we just proceed to state 1 */
552                         usbduxfast_cmd_data(dev, 0, 0x01, 0x00, rngmask, 0x00);
553                 }
554 
555                 if (steps < MIN_SAMPLING_PERIOD) {
556                         /* for fast single channel aqu without mux */
557                         if (steps <= 1) {
558                                 /*
559                                  * we just stay here at state 1 and rexecute
560                                  * the same state this gives us 30MHz sampling
561                                  * rate
562                                  */
563 
564                                 /* branch back to state 1 */
565                                 /* deceision state with data */
566                                 /* doesn't matter */
567                                 usbduxfast_cmd_data(dev, 1,
568                                                     0x89, 0x03, rngmask, 0xff);
569                         } else {
570                                 /*
571                                  * we loop through two states: data and delay
572                                  * max rate is 15MHz
573                                  */
574                                 /* data */
575                                 /* doesn't matter */
576                                 usbduxfast_cmd_data(dev, 1, steps - 1,
577                                                     0x02, rngmask, 0x00);
578 
579                                 /* branch back to state 1 */
580                                 /* deceision state w/o data */
581                                 /* doesn't matter */
582                                 usbduxfast_cmd_data(dev, 2,
583                                                     0x09, 0x01, rngmask, 0xff);
584                         }
585                 } else {
586                         /*
587                          * we loop through 3 states: 2x delay and 1x data
588                          * this gives a min sampling rate of 60kHz
589                          */
590 
591                         /* we have 1 state with duration 1 */
592                         steps = steps - 1;
593 
594                         /* do the first part of the delay */
595                         usbduxfast_cmd_data(dev, 1,
596                                             steps / 2, 0x00, rngmask, 0x00);
597 
598                         /* and the second part */
599                         usbduxfast_cmd_data(dev, 2, steps - steps / 2,
600                                             0x00, rngmask, 0x00);
601 
602                         /* get the data and branch back */
603 
604                         /* branch back to state 1 */
605                         /* deceision state w data */
606                         /* doesn't matter */
607                         usbduxfast_cmd_data(dev, 3,
608                                             0x09, 0x03, rngmask, 0xff);
609                 }
610                 break;
611 
612         case 2:
613                 /*
614                  * two channels
615                  * commit data to the FIFO
616                  */
617 
618                 if (CR_RANGE(cmd->chanlist[0]) > 0)
619                         rngmask = 0xff - 0x04;
620                 else
621                         rngmask = 0xff;
622 
623                 /* data */
624                 usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
625 
626                 /* we have 1 state with duration 1: state 0 */
627                 steps_tmp = steps - 1;
628 
629                 if (CR_RANGE(cmd->chanlist[1]) > 0)
630                         rngmask = 0xff - 0x04;
631                 else
632                         rngmask = 0xff;
633 
634                 /* do the first part of the delay */
635                 /* count */
636                 usbduxfast_cmd_data(dev, 1, steps_tmp / 2,
637                                     0x00, 0xfe & rngmask, 0x00);
638 
639                 /* and the second part */
640                 usbduxfast_cmd_data(dev, 2, steps_tmp  - steps_tmp / 2,
641                                     0x00, rngmask, 0x00);
642 
643                 /* data */
644                 usbduxfast_cmd_data(dev, 3, 0x01, 0x02, rngmask, 0x00);
645 
646                 /*
647                  * we have 2 states with duration 1: step 6 and
648                  * the IDLE state
649                  */
650                 steps_tmp = steps - 2;
651 
652                 if (CR_RANGE(cmd->chanlist[0]) > 0)
653                         rngmask = 0xff - 0x04;
654                 else
655                         rngmask = 0xff;
656 
657                 /* do the first part of the delay */
658                 /* reset */
659                 usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
660                                     0x00, (0xff - 0x02) & rngmask, 0x00);
661 
662                 /* and the second part */
663                 usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
664                                     0x00, rngmask, 0x00);
665 
666                 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
667                 break;
668 
669         case 3:
670                 /*
671                  * three channels
672                  */
673                 for (j = 0; j < 1; j++) {
674                         int index = j * 2;
675 
676                         if (CR_RANGE(cmd->chanlist[j]) > 0)
677                                 rngmask = 0xff - 0x04;
678                         else
679                                 rngmask = 0xff;
680                         /*
681                          * commit data to the FIFO and do the first part
682                          * of the delay
683                          */
684                         /* data */
685                         /* no change */
686                         usbduxfast_cmd_data(dev, index, steps / 2,
687                                             0x02, rngmask, 0x00);
688 
689                         if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
690                                 rngmask = 0xff - 0x04;
691                         else
692                                 rngmask = 0xff;
693 
694                         /* do the second part of the delay */
695                         /* no data */
696                         /* count */
697                         usbduxfast_cmd_data(dev, index + 1, steps - steps / 2,
698                                             0x00, 0xfe & rngmask, 0x00);
699                 }
700 
701                 /* 2 steps with duration 1: the idele step and step 6: */
702                 steps_tmp = steps - 2;
703 
704                 /* commit data to the FIFO and do the first part of the delay */
705                 /* data */
706                 usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
707                                     0x02, rngmask, 0x00);
708 
709                 if (CR_RANGE(cmd->chanlist[0]) > 0)
710                         rngmask = 0xff - 0x04;
711                 else
712                         rngmask = 0xff;
713 
714                 /* do the second part of the delay */
715                 /* no data */
716                 /* reset */
717                 usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
718                                     0x00, (0xff - 0x02) & rngmask, 0x00);
719 
720                 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
721                 break;
722 
723         case 16:
724                 if (CR_RANGE(cmd->chanlist[0]) > 0)
725                         rngmask = 0xff - 0x04;
726                 else
727                         rngmask = 0xff;
728 
729                 if (cmd->start_src == TRIG_EXT) {
730                         /*
731                          * we loop here until ready has been set
732                          */
733 
734                         /* branch back to state 0 */
735                         /* deceision state w/o data */
736                         /* reset */
737                         /* RDY0 = 0 */
738                         usbduxfast_cmd_data(dev, 0, 0x01, 0x01,
739                                             (0xff - 0x02) & rngmask, 0x00);
740                 } else {
741                         /*
742                          * we just proceed to state 1
743                          */
744 
745                         /* 30us reset pulse */
746                         /* reset */
747                         usbduxfast_cmd_data(dev, 0, 0xff, 0x00,
748                                             (0xff - 0x02) & rngmask, 0x00);
749                 }
750 
751                 /* commit data to the FIFO */
752                 /* data */
753                 usbduxfast_cmd_data(dev, 1, 0x01, 0x02, rngmask, 0x00);
754 
755                 /* we have 2 states with duration 1 */
756                 steps = steps - 2;
757 
758                 /* do the first part of the delay */
759                 usbduxfast_cmd_data(dev, 2, steps / 2,
760                                     0x00, 0xfe & rngmask, 0x00);
761 
762                 /* and the second part */
763                 usbduxfast_cmd_data(dev, 3, steps - steps / 2,
764                                     0x00, rngmask, 0x00);
765 
766                 /* branch back to state 1 */
767                 /* deceision state w/o data */
768                 /* doesn't matter */
769                 usbduxfast_cmd_data(dev, 4, 0x09, 0x01, rngmask, 0xff);
770 
771                 break;
772 
773         default:
774                 dev_err(dev->class_dev, "unsupported combination of channels\n");
775                 up(&devpriv->sem);
776                 return -EFAULT;
777         }
778 
779         /* 0 means that the AD commands are sent */
780         result = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
781         if (result < 0) {
782                 up(&devpriv->sem);
783                 return result;
784         }
785 
786         if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
787                 /* enable this acquisition operation */
788                 devpriv->ai_cmd_running = 1;
789                 ret = usbduxfast_submit_urb(dev);
790                 if (ret < 0) {
791                         devpriv->ai_cmd_running = 0;
792                         /* fixme: unlink here?? */
793                         up(&devpriv->sem);
794                         return ret;
795                 }
796                 s->async->inttrig = NULL;
797         } else {        /* TRIG_INT */
798                 s->async->inttrig = usbduxfast_ai_inttrig;
799         }
800         up(&devpriv->sem);
801 
802         return 0;
803 }
804 
805 /*
806  * Mode 0 is used to get a single conversion on demand.
807  */
808 static int usbduxfast_ai_insn_read(struct comedi_device *dev,
809                                    struct comedi_subdevice *s,
810                                    struct comedi_insn *insn,
811                                    unsigned int *data)
812 {
813         struct usb_device *usb = comedi_to_usb_dev(dev);
814         struct usbduxfast_private *devpriv = dev->private;
815         unsigned int chan = CR_CHAN(insn->chanspec);
816         unsigned int range = CR_RANGE(insn->chanspec);
817         uint8_t rngmask = range ? (0xff - 0x04) : 0xff;
818         int i, j, n, actual_length;
819         int ret;
820 
821         down(&devpriv->sem);
822 
823         if (devpriv->ai_cmd_running) {
824                 dev_err(dev->class_dev,
825                         "ai_insn_read not possible, async cmd is running\n");
826                 up(&devpriv->sem);
827                 return -EBUSY;
828         }
829 
830         /* set command for the first channel */
831 
832         /* commit data to the FIFO */
833         /* data */
834         usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
835 
836         /* do the first part of the delay */
837         usbduxfast_cmd_data(dev, 1, 0x0c, 0x00, 0xfe & rngmask, 0x00);
838         usbduxfast_cmd_data(dev, 2, 0x01, 0x00, 0xfe & rngmask, 0x00);
839         usbduxfast_cmd_data(dev, 3, 0x01, 0x00, 0xfe & rngmask, 0x00);
840         usbduxfast_cmd_data(dev, 4, 0x01, 0x00, 0xfe & rngmask, 0x00);
841 
842         /* second part */
843         usbduxfast_cmd_data(dev, 5, 0x0c, 0x00, rngmask, 0x00);
844         usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
845 
846         ret = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
847         if (ret < 0) {
848                 up(&devpriv->sem);
849                 return ret;
850         }
851 
852         for (i = 0; i < PACKETS_TO_IGNORE; i++) {
853                 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
854                                    devpriv->inbuf, SIZEINBUF,
855                                    &actual_length, 10000);
856                 if (ret < 0) {
857                         dev_err(dev->class_dev, "insn timeout, no data\n");
858                         up(&devpriv->sem);
859                         return ret;
860                 }
861         }
862 
863         for (i = 0; i < insn->n;) {
864                 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
865                                    devpriv->inbuf, SIZEINBUF,
866                                    &actual_length, 10000);
867                 if (ret < 0) {
868                         dev_err(dev->class_dev, "insn data error: %d\n", ret);
869                         up(&devpriv->sem);
870                         return ret;
871                 }
872                 n = actual_length / sizeof(uint16_t);
873                 if ((n % 16) != 0) {
874                         dev_err(dev->class_dev, "insn data packet corrupted\n");
875                         up(&devpriv->sem);
876                         return -EINVAL;
877                 }
878                 for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
879                         data[i] = ((uint16_t *) (devpriv->inbuf))[j];
880                         i++;
881                 }
882         }
883 
884         up(&devpriv->sem);
885 
886         return insn->n;
887 }
888 
889 static int usbduxfast_attach_common(struct comedi_device *dev)
890 {
891         struct usbduxfast_private *devpriv = dev->private;
892         struct comedi_subdevice *s;
893         int ret;
894 
895         down(&devpriv->sem);
896 
897         ret = comedi_alloc_subdevices(dev, 1);
898         if (ret) {
899                 up(&devpriv->sem);
900                 return ret;
901         }
902 
903         /* Analog Input subdevice */
904         s = &dev->subdevices[0];
905         dev->read_subdev = s;
906         s->type         = COMEDI_SUBD_AI;
907         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
908         s->n_chan       = 16;
909         s->len_chanlist = 16;
910         s->insn_read    = usbduxfast_ai_insn_read;
911         s->do_cmdtest   = usbduxfast_ai_cmdtest;
912         s->do_cmd       = usbduxfast_ai_cmd;
913         s->cancel       = usbduxfast_ai_cancel;
914         s->maxdata      = 0x1000;
915         s->range_table  = &range_usbduxfast_ai_range;
916 
917         up(&devpriv->sem);
918 
919         return 0;
920 }
921 
922 static int usbduxfast_upload_firmware(struct comedi_device *dev,
923                                       const u8 *data, size_t size,
924                                       unsigned long context)
925 {
926         struct usb_device *usb = comedi_to_usb_dev(dev);
927         uint8_t *buf;
928         unsigned char *tmp;
929         int ret;
930 
931         if (!data)
932                 return 0;
933 
934         if (size > FIRMWARE_MAX_LEN) {
935                 dev_err(dev->class_dev, "firmware binary too large for FX2\n");
936                 return -ENOMEM;
937         }
938 
939         /* we generate a local buffer for the firmware */
940         buf = kmemdup(data, size, GFP_KERNEL);
941         if (!buf)
942                 return -ENOMEM;
943 
944         /* we need a malloc'ed buffer for usb_control_msg() */
945         tmp = kmalloc(1, GFP_KERNEL);
946         if (!tmp) {
947                 kfree(buf);
948                 return -ENOMEM;
949         }
950 
951         /* stop the current firmware on the device */
952         *tmp = 1;       /* 7f92 to one */
953         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
954                               USBDUXFASTSUB_FIRMWARE,
955                               VENDOR_DIR_OUT,
956                               USBDUXFASTSUB_CPUCS, 0x0000,
957                               tmp, 1,
958                               EZTIMEOUT);
959         if (ret < 0) {
960                 dev_err(dev->class_dev, "can not stop firmware\n");
961                 goto done;
962         }
963 
964         /* upload the new firmware to the device */
965         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
966                               USBDUXFASTSUB_FIRMWARE,
967                               VENDOR_DIR_OUT,
968                               0, 0x0000,
969                               buf, size,
970                               EZTIMEOUT);
971         if (ret < 0) {
972                 dev_err(dev->class_dev, "firmware upload failed\n");
973                 goto done;
974         }
975 
976         /* start the new firmware on the device */
977         *tmp = 0;       /* 7f92 to zero */
978         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
979                               USBDUXFASTSUB_FIRMWARE,
980                               VENDOR_DIR_OUT,
981                               USBDUXFASTSUB_CPUCS, 0x0000,
982                               tmp, 1,
983                               EZTIMEOUT);
984         if (ret < 0)
985                 dev_err(dev->class_dev, "can not start firmware\n");
986 
987 done:
988         kfree(tmp);
989         kfree(buf);
990         return ret;
991 }
992 
993 static int usbduxfast_auto_attach(struct comedi_device *dev,
994                                   unsigned long context_unused)
995 {
996         struct usb_interface *intf = comedi_to_usb_interface(dev);
997         struct usb_device *usb = comedi_to_usb_dev(dev);
998         struct usbduxfast_private *devpriv;
999         int ret;
1000 
1001         if (usb->speed != USB_SPEED_HIGH) {
1002                 dev_err(dev->class_dev,
1003                         "This driver needs USB 2.0 to operate. Aborting...\n");
1004                 return -ENODEV;
1005         }
1006 
1007         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1008         if (!devpriv)
1009                 return -ENOMEM;
1010 
1011         sema_init(&devpriv->sem, 1);
1012         usb_set_intfdata(intf, devpriv);
1013 
1014         devpriv->duxbuf = kmalloc(SIZEOFDUXBUF, GFP_KERNEL);
1015         if (!devpriv->duxbuf)
1016                 return -ENOMEM;
1017 
1018         ret = usb_set_interface(usb,
1019                                 intf->altsetting->desc.bInterfaceNumber, 1);
1020         if (ret < 0) {
1021                 dev_err(dev->class_dev,
1022                         "could not switch to alternate setting 1\n");
1023                 return -ENODEV;
1024         }
1025 
1026         devpriv->urb = usb_alloc_urb(0, GFP_KERNEL);
1027         if (!devpriv->urb) {
1028                 dev_err(dev->class_dev, "Could not alloc. urb\n");
1029                 return -ENOMEM;
1030         }
1031 
1032         devpriv->inbuf = kmalloc(SIZEINBUF, GFP_KERNEL);
1033         if (!devpriv->inbuf)
1034                 return -ENOMEM;
1035 
1036         ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1037                                    usbduxfast_upload_firmware, 0);
1038         if (ret)
1039                 return ret;
1040 
1041         return usbduxfast_attach_common(dev);
1042 }
1043 
1044 static void usbduxfast_detach(struct comedi_device *dev)
1045 {
1046         struct usb_interface *intf = comedi_to_usb_interface(dev);
1047         struct usbduxfast_private *devpriv = dev->private;
1048 
1049         if (!devpriv)
1050                 return;
1051 
1052         down(&devpriv->sem);
1053 
1054         usb_set_intfdata(intf, NULL);
1055 
1056         if (devpriv->urb) {
1057                 /* waits until a running transfer is over */
1058                 usb_kill_urb(devpriv->urb);
1059 
1060                 kfree(devpriv->inbuf);
1061                 devpriv->inbuf = NULL;
1062 
1063                 usb_free_urb(devpriv->urb);
1064                 devpriv->urb = NULL;
1065         }
1066 
1067         kfree(devpriv->duxbuf);
1068         devpriv->duxbuf = NULL;
1069 
1070         devpriv->ai_cmd_running = 0;
1071 
1072         up(&devpriv->sem);
1073 }
1074 
1075 static struct comedi_driver usbduxfast_driver = {
1076         .driver_name    = "usbduxfast",
1077         .module         = THIS_MODULE,
1078         .auto_attach    = usbduxfast_auto_attach,
1079         .detach         = usbduxfast_detach,
1080 };
1081 
1082 static int usbduxfast_usb_probe(struct usb_interface *intf,
1083                                 const struct usb_device_id *id)
1084 {
1085         return comedi_usb_auto_config(intf, &usbduxfast_driver, 0);
1086 }
1087 
1088 static const struct usb_device_id usbduxfast_usb_table[] = {
1089         /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
1090         { USB_DEVICE(0x13d8, 0x0010) }, /* real ID */
1091         { USB_DEVICE(0x13d8, 0x0011) }, /* real ID */
1092         { }
1093 };
1094 MODULE_DEVICE_TABLE(usb, usbduxfast_usb_table);
1095 
1096 static struct usb_driver usbduxfast_usb_driver = {
1097         .name           = "usbduxfast",
1098         .probe          = usbduxfast_usb_probe,
1099         .disconnect     = comedi_usb_auto_unconfig,
1100         .id_table       = usbduxfast_usb_table,
1101 };
1102 module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver);
1103 
1104 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1105 MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com");
1106 MODULE_LICENSE("GPL");
1107 MODULE_FIRMWARE(FIRMWARE);
1108 

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