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

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

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