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

Linux/drivers/staging/comedi/drivers/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_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         /* stop source */
428         switch (cmd->stop_src) {
429         case TRIG_COUNT:
430                 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
431                 break;
432         case TRIG_NONE:
433                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
434                 break;
435                 /*
436                  * TRIG_EXT doesn't care since it doesn't trigger
437                  * off a numbered channel
438                  */
439         default:
440                 break;
441         }
442 
443         if (err)
444                 return 3;
445 
446         /* step 4: fix up any arguments */
447 
448         return 0;
449 
450 }
451 
452 static int usbduxfast_ai_inttrig(struct comedi_device *dev,
453                                  struct comedi_subdevice *s,
454                                  unsigned int trignum)
455 {
456         struct usbduxfast_private *devpriv = dev->private;
457         int ret;
458 
459         if (!devpriv)
460                 return -EFAULT;
461 
462         down(&devpriv->sem);
463 
464         if (trignum != 0) {
465                 dev_err(dev->class_dev, "invalid trignum\n");
466                 up(&devpriv->sem);
467                 return -EINVAL;
468         }
469         if (!devpriv->ai_cmd_running) {
470                 devpriv->ai_cmd_running = 1;
471                 ret = usbduxfast_submit_urb(dev);
472                 if (ret < 0) {
473                         dev_err(dev->class_dev, "urbSubmit: err=%d\n", ret);
474                         devpriv->ai_cmd_running = 0;
475                         up(&devpriv->sem);
476                         return ret;
477                 }
478                 s->async->inttrig = NULL;
479         } else {
480                 dev_err(dev->class_dev, "ai is already running\n");
481         }
482         up(&devpriv->sem);
483         return 1;
484 }
485 
486 static int usbduxfast_ai_cmd(struct comedi_device *dev,
487                              struct comedi_subdevice *s)
488 {
489         struct usbduxfast_private *devpriv = dev->private;
490         struct comedi_cmd *cmd = &s->async->cmd;
491         unsigned int chan, gain, rngmask = 0xff;
492         int i, j, ret;
493         int result;
494         long steps, steps_tmp;
495 
496         if (!devpriv)
497                 return -EFAULT;
498 
499         down(&devpriv->sem);
500         if (devpriv->ai_cmd_running) {
501                 dev_err(dev->class_dev, "ai_cmd not possible\n");
502                 up(&devpriv->sem);
503                 return -EBUSY;
504         }
505         /* set current channel of the running acquisition to zero */
506         s->async->cur_chan = 0;
507 
508         /*
509          * ignore the first buffers from the device if there
510          * is an error condition
511          */
512         devpriv->ignore = PACKETS_TO_IGNORE;
513 
514         gain = CR_RANGE(cmd->chanlist[0]);
515         for (i = 0; i < cmd->chanlist_len; ++i) {
516                 chan = CR_CHAN(cmd->chanlist[i]);
517                 if (chan != i) {
518                         dev_err(dev->class_dev,
519                                 "channels are not consecutive\n");
520                         up(&devpriv->sem);
521                         return -EINVAL;
522                 }
523                 if ((gain != CR_RANGE(cmd->chanlist[i]))
524                         && (cmd->chanlist_len > 3)) {
525                         dev_err(dev->class_dev,
526                                 "gain must be the same for all channels\n");
527                         up(&devpriv->sem);
528                         return -EINVAL;
529                 }
530                 if (i >= NUMCHANNELS) {
531                         dev_err(dev->class_dev, "chanlist too long\n");
532                         break;
533                 }
534         }
535         steps = 0;
536         if (cmd->convert_src == TRIG_TIMER)
537                 steps = (cmd->convert_arg * 30) / 1000;
538 
539         if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
540                 dev_err(dev->class_dev,
541                         "steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n",
542                         steps, cmd->scan_begin_arg);
543                 up(&devpriv->sem);
544                 return -EINVAL;
545         }
546         if (steps > MAX_SAMPLING_PERIOD) {
547                 dev_err(dev->class_dev, "sampling rate too low\n");
548                 up(&devpriv->sem);
549                 return -EINVAL;
550         }
551         if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
552             && (cmd->chanlist_len != 16)) {
553                 dev_err(dev->class_dev,
554                         "TRIG_EXT only with 1 or 16 channels possible\n");
555                 up(&devpriv->sem);
556                 return -EINVAL;
557         }
558 
559         switch (cmd->chanlist_len) {
560         case 1:
561                 /*
562                  * one channel
563                  */
564 
565                 if (CR_RANGE(cmd->chanlist[0]) > 0)
566                         rngmask = 0xff - 0x04;
567                 else
568                         rngmask = 0xff;
569 
570                 /*
571                  * for external trigger: looping in this state until
572                  * the RDY0 pin becomes zero
573                  */
574 
575                 /* we loop here until ready has been set */
576                 if (cmd->start_src == TRIG_EXT) {
577                         /* branch back to state 0 */
578                         /* deceision state w/o data */
579                         /* RDY0 = 0 */
580                         usbduxfast_cmd_data(dev, 0, 0x01, 0x01, rngmask, 0x00);
581                 } else {        /* we just proceed to state 1 */
582                         usbduxfast_cmd_data(dev, 0, 0x01, 0x00, rngmask, 0x00);
583                 }
584 
585                 if (steps < MIN_SAMPLING_PERIOD) {
586                         /* for fast single channel aqu without mux */
587                         if (steps <= 1) {
588                                 /*
589                                  * we just stay here at state 1 and rexecute
590                                  * the same state this gives us 30MHz sampling
591                                  * rate
592                                  */
593 
594                                 /* branch back to state 1 */
595                                 /* deceision state with data */
596                                 /* doesn't matter */
597                                 usbduxfast_cmd_data(dev, 1,
598                                                     0x89, 0x03, rngmask, 0xff);
599                         } else {
600                                 /*
601                                  * we loop through two states: data and delay
602                                  * max rate is 15MHz
603                                  */
604                                 /* data */
605                                 /* doesn't matter */
606                                 usbduxfast_cmd_data(dev, 1, steps - 1,
607                                                     0x02, rngmask, 0x00);
608 
609                                 /* branch back to state 1 */
610                                 /* deceision state w/o data */
611                                 /* doesn't matter */
612                                 usbduxfast_cmd_data(dev, 2,
613                                                     0x09, 0x01, rngmask, 0xff);
614                         }
615                 } else {
616                         /*
617                          * we loop through 3 states: 2x delay and 1x data
618                          * this gives a min sampling rate of 60kHz
619                          */
620 
621                         /* we have 1 state with duration 1 */
622                         steps = steps - 1;
623 
624                         /* do the first part of the delay */
625                         usbduxfast_cmd_data(dev, 1,
626                                             steps / 2, 0x00, rngmask, 0x00);
627 
628                         /* and the second part */
629                         usbduxfast_cmd_data(dev, 2, steps - steps / 2,
630                                             0x00, rngmask, 0x00);
631 
632                         /* get the data and branch back */
633 
634                         /* branch back to state 1 */
635                         /* deceision state w data */
636                         /* doesn't matter */
637                         usbduxfast_cmd_data(dev, 3,
638                                             0x09, 0x03, rngmask, 0xff);
639                 }
640                 break;
641 
642         case 2:
643                 /*
644                  * two channels
645                  * commit data to the FIFO
646                  */
647 
648                 if (CR_RANGE(cmd->chanlist[0]) > 0)
649                         rngmask = 0xff - 0x04;
650                 else
651                         rngmask = 0xff;
652 
653                 /* data */
654                 usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
655 
656                 /* we have 1 state with duration 1: state 0 */
657                 steps_tmp = steps - 1;
658 
659                 if (CR_RANGE(cmd->chanlist[1]) > 0)
660                         rngmask = 0xff - 0x04;
661                 else
662                         rngmask = 0xff;
663 
664                 /* do the first part of the delay */
665                 /* count */
666                 usbduxfast_cmd_data(dev, 1, steps_tmp / 2,
667                                     0x00, 0xfe & rngmask, 0x00);
668 
669                 /* and the second part */
670                 usbduxfast_cmd_data(dev, 2, steps_tmp  - steps_tmp / 2,
671                                     0x00, rngmask, 0x00);
672 
673                 /* data */
674                 usbduxfast_cmd_data(dev, 3, 0x01, 0x02, rngmask, 0x00);
675 
676                 /*
677                  * we have 2 states with duration 1: step 6 and
678                  * the IDLE state
679                  */
680                 steps_tmp = steps - 2;
681 
682                 if (CR_RANGE(cmd->chanlist[0]) > 0)
683                         rngmask = 0xff - 0x04;
684                 else
685                         rngmask = 0xff;
686 
687                 /* do the first part of the delay */
688                 /* reset */
689                 usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
690                                     0x00, (0xff - 0x02) & rngmask, 0x00);
691 
692                 /* and the second part */
693                 usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
694                                     0x00, rngmask, 0x00);
695 
696                 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
697                 break;
698 
699         case 3:
700                 /*
701                  * three channels
702                  */
703                 for (j = 0; j < 1; j++) {
704                         int index = j * 2;
705 
706                         if (CR_RANGE(cmd->chanlist[j]) > 0)
707                                 rngmask = 0xff - 0x04;
708                         else
709                                 rngmask = 0xff;
710                         /*
711                          * commit data to the FIFO and do the first part
712                          * of the delay
713                          */
714                         /* data */
715                         /* no change */
716                         usbduxfast_cmd_data(dev, index, steps / 2,
717                                             0x02, rngmask, 0x00);
718 
719                         if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
720                                 rngmask = 0xff - 0x04;
721                         else
722                                 rngmask = 0xff;
723 
724                         /* do the second part of the delay */
725                         /* no data */
726                         /* count */
727                         usbduxfast_cmd_data(dev, index + 1, steps - steps / 2,
728                                             0x00, 0xfe & rngmask, 0x00);
729                 }
730 
731                 /* 2 steps with duration 1: the idele step and step 6: */
732                 steps_tmp = steps - 2;
733 
734                 /* commit data to the FIFO and do the first part of the delay */
735                 /* data */
736                 usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
737                                     0x02, rngmask, 0x00);
738 
739                 if (CR_RANGE(cmd->chanlist[0]) > 0)
740                         rngmask = 0xff - 0x04;
741                 else
742                         rngmask = 0xff;
743 
744                 /* do the second part of the delay */
745                 /* no data */
746                 /* reset */
747                 usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
748                                     0x00, (0xff - 0x02) & rngmask, 0x00);
749 
750                 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
751 
752         case 16:
753                 if (CR_RANGE(cmd->chanlist[0]) > 0)
754                         rngmask = 0xff - 0x04;
755                 else
756                         rngmask = 0xff;
757 
758                 if (cmd->start_src == TRIG_EXT) {
759                         /*
760                          * we loop here until ready has been set
761                          */
762 
763                         /* branch back to state 0 */
764                         /* deceision state w/o data */
765                         /* reset */
766                         /* RDY0 = 0 */
767                         usbduxfast_cmd_data(dev, 0, 0x01, 0x01,
768                                             (0xff - 0x02) & rngmask, 0x00);
769                 } else {
770                         /*
771                          * we just proceed to state 1
772                          */
773 
774                         /* 30us reset pulse */
775                         /* reset */
776                         usbduxfast_cmd_data(dev, 0, 0xff, 0x00,
777                                             (0xff - 0x02) & rngmask, 0x00);
778                 }
779 
780                 /* commit data to the FIFO */
781                 /* data */
782                 usbduxfast_cmd_data(dev, 1, 0x01, 0x02, rngmask, 0x00);
783 
784                 /* we have 2 states with duration 1 */
785                 steps = steps - 2;
786 
787                 /* do the first part of the delay */
788                 usbduxfast_cmd_data(dev, 2, steps / 2,
789                                     0x00, 0xfe & rngmask, 0x00);
790 
791                 /* and the second part */
792                 usbduxfast_cmd_data(dev, 3, steps - steps / 2,
793                                     0x00, rngmask, 0x00);
794 
795                 /* branch back to state 1 */
796                 /* deceision state w/o data */
797                 /* doesn't matter */
798                 usbduxfast_cmd_data(dev, 4, 0x09, 0x01, rngmask, 0xff);
799 
800                 break;
801 
802         default:
803                 dev_err(dev->class_dev, "unsupported combination of channels\n");
804                 up(&devpriv->sem);
805                 return -EFAULT;
806         }
807 
808         /* 0 means that the AD commands are sent */
809         result = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
810         if (result < 0) {
811                 up(&devpriv->sem);
812                 return result;
813         }
814         if (cmd->stop_src == TRIG_COUNT) {
815                 devpriv->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg;
816                 if (devpriv->ai_sample_count < 1) {
817                         dev_err(dev->class_dev,
818                                 "(cmd->stop_arg)*(cmd->scan_end_arg)<1, aborting\n");
819                         up(&devpriv->sem);
820                         return -EFAULT;
821                 }
822                 devpriv->ai_continous = 0;
823         } else {
824                 /* continous acquisition */
825                 devpriv->ai_continous = 1;
826                 devpriv->ai_sample_count = 0;
827         }
828 
829         if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
830                 /* enable this acquisition operation */
831                 devpriv->ai_cmd_running = 1;
832                 ret = usbduxfast_submit_urb(dev);
833                 if (ret < 0) {
834                         devpriv->ai_cmd_running = 0;
835                         /* fixme: unlink here?? */
836                         up(&devpriv->sem);
837                         return ret;
838                 }
839                 s->async->inttrig = NULL;
840         } else {
841                 /*
842                  * TRIG_INT
843                  * don't enable the acquision operation
844                  * wait for an internal signal
845                  */
846                 s->async->inttrig = usbduxfast_ai_inttrig;
847         }
848         up(&devpriv->sem);
849 
850         return 0;
851 }
852 
853 /*
854  * Mode 0 is used to get a single conversion on demand.
855  */
856 static int usbduxfast_ai_insn_read(struct comedi_device *dev,
857                                    struct comedi_subdevice *s,
858                                    struct comedi_insn *insn,
859                                    unsigned int *data)
860 {
861         struct usb_device *usb = comedi_to_usb_dev(dev);
862         struct usbduxfast_private *devpriv = dev->private;
863         unsigned int chan = CR_CHAN(insn->chanspec);
864         unsigned int range = CR_RANGE(insn->chanspec);
865         uint8_t rngmask = range ? (0xff - 0x04) : 0xff;
866         int i, j, n, actual_length;
867         int ret;
868 
869         down(&devpriv->sem);
870 
871         if (devpriv->ai_cmd_running) {
872                 dev_err(dev->class_dev,
873                         "ai_insn_read not possible, async cmd is running\n");
874                 up(&devpriv->sem);
875                 return -EBUSY;
876         }
877 
878         /* set command for the first channel */
879 
880         /* commit data to the FIFO */
881         /* data */
882         usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
883 
884         /* do the first part of the delay */
885         usbduxfast_cmd_data(dev, 1, 0x0c, 0x00, 0xfe & rngmask, 0x00);
886         usbduxfast_cmd_data(dev, 2, 0x01, 0x00, 0xfe & rngmask, 0x00);
887         usbduxfast_cmd_data(dev, 3, 0x01, 0x00, 0xfe & rngmask, 0x00);
888         usbduxfast_cmd_data(dev, 4, 0x01, 0x00, 0xfe & rngmask, 0x00);
889 
890         /* second part */
891         usbduxfast_cmd_data(dev, 5, 0x0c, 0x00, rngmask, 0x00);
892         usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
893 
894         ret = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
895         if (ret < 0) {
896                 up(&devpriv->sem);
897                 return ret;
898         }
899 
900         for (i = 0; i < PACKETS_TO_IGNORE; i++) {
901                 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
902                                    devpriv->inbuf, SIZEINBUF,
903                                    &actual_length, 10000);
904                 if (ret < 0) {
905                         dev_err(dev->class_dev, "insn timeout, no data\n");
906                         up(&devpriv->sem);
907                         return ret;
908                 }
909         }
910 
911         for (i = 0; i < insn->n;) {
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 data error: %d\n", ret);
917                         up(&devpriv->sem);
918                         return ret;
919                 }
920                 n = actual_length / sizeof(uint16_t);
921                 if ((n % 16) != 0) {
922                         dev_err(dev->class_dev, "insn data packet corrupted\n");
923                         up(&devpriv->sem);
924                         return -EINVAL;
925                 }
926                 for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
927                         data[i] = ((uint16_t *) (devpriv->inbuf))[j];
928                         i++;
929                 }
930         }
931 
932         up(&devpriv->sem);
933 
934         return insn->n;
935 }
936 
937 static int usbduxfast_attach_common(struct comedi_device *dev)
938 {
939         struct usbduxfast_private *devpriv = dev->private;
940         struct comedi_subdevice *s;
941         int ret;
942 
943         down(&devpriv->sem);
944 
945         ret = comedi_alloc_subdevices(dev, 1);
946         if (ret) {
947                 up(&devpriv->sem);
948                 return ret;
949         }
950 
951         /* Analog Input subdevice */
952         s = &dev->subdevices[0];
953         dev->read_subdev = s;
954         s->type         = COMEDI_SUBD_AI;
955         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
956         s->n_chan       = 16;
957         s->len_chanlist = 16;
958         s->insn_read    = usbduxfast_ai_insn_read;
959         s->do_cmdtest   = usbduxfast_ai_cmdtest;
960         s->do_cmd       = usbduxfast_ai_cmd;
961         s->cancel       = usbduxfast_ai_cancel;
962         s->maxdata      = 0x1000;
963         s->range_table  = &range_usbduxfast_ai_range;
964 
965         up(&devpriv->sem);
966 
967         return 0;
968 }
969 
970 static int usbduxfast_upload_firmware(struct comedi_device *dev,
971                                       const u8 *data, size_t size,
972                                       unsigned long context)
973 {
974         struct usb_device *usb = comedi_to_usb_dev(dev);
975         uint8_t *buf;
976         unsigned char *tmp;
977         int ret;
978 
979         if (!data)
980                 return 0;
981 
982         if (size > FIRMWARE_MAX_LEN) {
983                 dev_err(dev->class_dev, "firmware binary too large for FX2\n");
984                 return -ENOMEM;
985         }
986 
987         /* we generate a local buffer for the firmware */
988         buf = kmemdup(data, size, GFP_KERNEL);
989         if (!buf)
990                 return -ENOMEM;
991 
992         /* we need a malloc'ed buffer for usb_control_msg() */
993         tmp = kmalloc(1, GFP_KERNEL);
994         if (!tmp) {
995                 kfree(buf);
996                 return -ENOMEM;
997         }
998 
999         /* stop the current firmware on the device */
1000         *tmp = 1;       /* 7f92 to one */
1001         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1002                               USBDUXFASTSUB_FIRMWARE,
1003                               VENDOR_DIR_OUT,
1004                               USBDUXFASTSUB_CPUCS, 0x0000,
1005                               tmp, 1,
1006                               EZTIMEOUT);
1007         if (ret < 0) {
1008                 dev_err(dev->class_dev, "can not stop firmware\n");
1009                 goto done;
1010         }
1011 
1012         /* upload the new firmware to the device */
1013         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1014                               USBDUXFASTSUB_FIRMWARE,
1015                               VENDOR_DIR_OUT,
1016                               0, 0x0000,
1017                               buf, size,
1018                               EZTIMEOUT);
1019         if (ret < 0) {
1020                 dev_err(dev->class_dev, "firmware upload failed\n");
1021                 goto done;
1022         }
1023 
1024         /* start the new firmware on the device */
1025         *tmp = 0;       /* 7f92 to zero */
1026         ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1027                               USBDUXFASTSUB_FIRMWARE,
1028                               VENDOR_DIR_OUT,
1029                               USBDUXFASTSUB_CPUCS, 0x0000,
1030                               tmp, 1,
1031                               EZTIMEOUT);
1032         if (ret < 0)
1033                 dev_err(dev->class_dev, "can not start firmware\n");
1034 
1035 done:
1036         kfree(tmp);
1037         kfree(buf);
1038         return ret;
1039 }
1040 
1041 static int usbduxfast_auto_attach(struct comedi_device *dev,
1042                                   unsigned long context_unused)
1043 {
1044         struct usb_interface *intf = comedi_to_usb_interface(dev);
1045         struct usb_device *usb = comedi_to_usb_dev(dev);
1046         struct usbduxfast_private *devpriv;
1047         int ret;
1048 
1049         if (usb->speed != USB_SPEED_HIGH) {
1050                 dev_err(dev->class_dev,
1051                         "This driver needs USB 2.0 to operate. Aborting...\n");
1052                 return -ENODEV;
1053         }
1054 
1055         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1056         if (!devpriv)
1057                 return -ENOMEM;
1058 
1059         sema_init(&devpriv->sem, 1);
1060         usb_set_intfdata(intf, devpriv);
1061 
1062         devpriv->duxbuf = kmalloc(SIZEOFDUXBUF, GFP_KERNEL);
1063         if (!devpriv->duxbuf)
1064                 return -ENOMEM;
1065 
1066         ret = usb_set_interface(usb,
1067                                 intf->altsetting->desc.bInterfaceNumber, 1);
1068         if (ret < 0) {
1069                 dev_err(dev->class_dev,
1070                         "could not switch to alternate setting 1\n");
1071                 return -ENODEV;
1072         }
1073 
1074         devpriv->urb = usb_alloc_urb(0, GFP_KERNEL);
1075         if (!devpriv->urb) {
1076                 dev_err(dev->class_dev, "Could not alloc. urb\n");
1077                 return -ENOMEM;
1078         }
1079 
1080         devpriv->inbuf = kmalloc(SIZEINBUF, GFP_KERNEL);
1081         if (!devpriv->inbuf)
1082                 return -ENOMEM;
1083 
1084         ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1085                                    usbduxfast_upload_firmware, 0);
1086         if (ret)
1087                 return ret;
1088 
1089         return usbduxfast_attach_common(dev);
1090 }
1091 
1092 static void usbduxfast_detach(struct comedi_device *dev)
1093 {
1094         struct usb_interface *intf = comedi_to_usb_interface(dev);
1095         struct usbduxfast_private *devpriv = dev->private;
1096 
1097         if (!devpriv)
1098                 return;
1099 
1100         down(&devpriv->sem);
1101 
1102         usb_set_intfdata(intf, NULL);
1103 
1104         if (devpriv->urb) {
1105                 /* waits until a running transfer is over */
1106                 usb_kill_urb(devpriv->urb);
1107 
1108                 kfree(devpriv->inbuf);
1109                 devpriv->inbuf = NULL;
1110 
1111                 usb_free_urb(devpriv->urb);
1112                 devpriv->urb = NULL;
1113         }
1114 
1115         kfree(devpriv->duxbuf);
1116         devpriv->duxbuf = NULL;
1117 
1118         devpriv->ai_cmd_running = 0;
1119 
1120         up(&devpriv->sem);
1121 }
1122 
1123 static struct comedi_driver usbduxfast_driver = {
1124         .driver_name    = "usbduxfast",
1125         .module         = THIS_MODULE,
1126         .auto_attach    = usbduxfast_auto_attach,
1127         .detach         = usbduxfast_detach,
1128 };
1129 
1130 static int usbduxfast_usb_probe(struct usb_interface *intf,
1131                                 const struct usb_device_id *id)
1132 {
1133         return comedi_usb_auto_config(intf, &usbduxfast_driver, 0);
1134 }
1135 
1136 static const struct usb_device_id usbduxfast_usb_table[] = {
1137         /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
1138         { USB_DEVICE(0x13d8, 0x0010) }, /* real ID */
1139         { USB_DEVICE(0x13d8, 0x0011) }, /* real ID */
1140         { }
1141 };
1142 MODULE_DEVICE_TABLE(usb, usbduxfast_usb_table);
1143 
1144 static struct usb_driver usbduxfast_usb_driver = {
1145         .name           = "usbduxfast",
1146         .probe          = usbduxfast_usb_probe,
1147         .disconnect     = comedi_usb_auto_unconfig,
1148         .id_table       = usbduxfast_usb_table,
1149 };
1150 module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver);
1151 
1152 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1153 MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com");
1154 MODULE_LICENSE("GPL");
1155 MODULE_FIRMWARE(FIRMWARE);
1156 

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