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