Version:  2.0.40 2.2.26 2.4.37 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6

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

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