Version:  2.6.34 2.6.35 2.6.36 2.6.37 2.6.38 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14

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

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

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