Version:  2.0.40 2.2.26 2.4.37 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19

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

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