root/drivers/staging/comedi/drivers/usbduxfast.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usbduxfast_send_cmd
  2. usbduxfast_cmd_data
  3. usbduxfast_ai_stop
  4. usbduxfast_ai_cancel
  5. usbduxfast_ai_handle_urb
  6. usbduxfast_ai_interrupt
  7. usbduxfast_submit_urb
  8. usbduxfast_ai_check_chanlist
  9. usbduxfast_ai_cmdtest
  10. usbduxfast_ai_inttrig
  11. usbduxfast_ai_cmd
  12. usbduxfast_ai_insn_read
  13. usbduxfast_upload_firmware
  14. usbduxfast_auto_attach
  15. usbduxfast_detach
  16. usbduxfast_usb_probe

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

/* [<][>][^][v][top][bottom][index][help] */