linux/drivers/staging/comedi/drivers/usbduxsigma.c
<<
>>
Prefs
   1/*
   2 * usbduxsigma.c
   3 * Copyright (C) 2011-2015 Bernd Porr, mail@berndporr.me.uk
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License as published by
   7 * the Free Software Foundation; either version 2 of the License, or
   8 * (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 */
  15
  16/*
  17 * Driver: usbduxsigma
  18 * Description: University of Stirling USB DAQ & INCITE Technology Limited
  19 * Devices: [ITL] USB-DUX-SIGMA (usbduxsigma)
  20 * Author: Bernd Porr <mail@berndporr.me.uk>
  21 * Updated: 20 July 2015
  22 * Status: stable
  23 */
  24
  25/*
  26 * I must give credit here to Chris Baugher who
  27 * wrote the driver for AT-MIO-16d. I used some parts of this
  28 * driver. I also must give credits to David Brownell
  29 * who supported me with the USB development.
  30 *
  31 * Note: the raw data from the A/D converter is 24 bit big endian
  32 * anything else is little endian to/from the dux board
  33 *
  34 *
  35 * Revision history:
  36 *   0.1: initial version
  37 *   0.2: all basic functions implemented, digital I/O only for one port
  38 *   0.3: proper vendor ID and driver name
  39 *   0.4: fixed D/A voltage range
  40 *   0.5: various bug fixes, health check at startup
  41 *   0.6: corrected wrong input range
  42 *   0.7: rewrite code that urb->interval is always 1
  43 */
  44
  45#include <linux/kernel.h>
  46#include <linux/module.h>
  47#include <linux/slab.h>
  48#include <linux/input.h>
  49#include <linux/fcntl.h>
  50#include <linux/compiler.h>
  51#include <asm/unaligned.h>
  52
  53#include "../comedi_usb.h"
  54
  55/* timeout for the USB-transfer in ms*/
  56#define BULK_TIMEOUT 1000
  57
  58/* constants for "firmware" upload and download */
  59#define FIRMWARE                "usbduxsigma_firmware.bin"
  60#define FIRMWARE_MAX_LEN        0x4000
  61#define USBDUXSUB_FIRMWARE      0xa0
  62#define VENDOR_DIR_IN           0xc0
  63#define VENDOR_DIR_OUT          0x40
  64
  65/* internal addresses of the 8051 processor */
  66#define USBDUXSUB_CPUCS 0xE600
  67
  68/* 300Hz max frequ under PWM */
  69#define MIN_PWM_PERIOD  ((long)(1E9 / 300))
  70
  71/* Default PWM frequency */
  72#define PWM_DEFAULT_PERIOD ((long)(1E9 / 100))
  73
  74/* Number of channels (16 AD and offset)*/
  75#define NUMCHANNELS 16
  76
  77/* Size of one A/D value */
  78#define SIZEADIN          ((sizeof(u32)))
  79
  80/*
  81 * Size of the async input-buffer IN BYTES, the DIO state is transmitted
  82 * as the first byte.
  83 */
  84#define SIZEINBUF         (((NUMCHANNELS + 1) * SIZEADIN))
  85
  86/* 16 bytes. */
  87#define SIZEINSNBUF       16
  88
  89/* Number of DA channels */
  90#define NUMOUTCHANNELS    8
  91
  92/* size of one value for the D/A converter: channel and value */
  93#define SIZEDAOUT          ((sizeof(u8) + sizeof(uint16_t)))
  94
  95/*
  96 * Size of the output-buffer in bytes
  97 * Actually only the first 4 triplets are used but for the
  98 * high speed mode we need to pad it to 8 (microframes).
  99 */
 100#define SIZEOUTBUF         ((8 * SIZEDAOUT))
 101
 102/*
 103 * Size of the buffer for the dux commands: just now max size is determined
 104 * by the analogue out + command byte + panic bytes...
 105 */
 106#define SIZEOFDUXBUFFER    ((8 * SIZEDAOUT + 2))
 107
 108/* Number of in-URBs which receive the data: min=2 */
 109#define NUMOFINBUFFERSFULL     5
 110
 111/* Number of out-URBs which send the data: min=2 */
 112#define NUMOFOUTBUFFERSFULL    5
 113
 114/* Number of in-URBs which receive the data: min=5 */
 115/* must have more buffers due to buggy USB ctr */
 116#define NUMOFINBUFFERSHIGH     10
 117
 118/* Number of out-URBs which send the data: min=5 */
 119/* must have more buffers due to buggy USB ctr */
 120#define NUMOFOUTBUFFERSHIGH    10
 121
 122/* number of retries to get the right dux command */
 123#define RETRIES 10
 124
 125/* bulk transfer commands to usbduxsigma */
 126#define USBBUXSIGMA_AD_CMD              9
 127#define USBDUXSIGMA_DA_CMD              1
 128#define USBDUXSIGMA_DIO_CFG_CMD         2
 129#define USBDUXSIGMA_DIO_BITS_CMD        3
 130#define USBDUXSIGMA_SINGLE_AD_CMD       4
 131#define USBDUXSIGMA_PWM_ON_CMD          7
 132#define USBDUXSIGMA_PWM_OFF_CMD         8
 133
 134static const struct comedi_lrange usbduxsigma_ai_range = {
 135        1, {
 136                BIP_RANGE(2.5 * 0x800000 / 0x780000 / 2.0)
 137        }
 138};
 139
 140struct usbduxsigma_private {
 141        /* actual number of in-buffers */
 142        int n_ai_urbs;
 143        /* actual number of out-buffers */
 144        int n_ao_urbs;
 145        /* ISO-transfer handling: buffers */
 146        struct urb **ai_urbs;
 147        struct urb **ao_urbs;
 148        /* pwm-transfer handling */
 149        struct urb *pwm_urb;
 150        /* PWM period */
 151        unsigned int pwm_period;
 152        /* PWM internal delay for the GPIF in the FX2 */
 153        u8 pwm_delay;
 154        /* size of the PWM buffer which holds the bit pattern */
 155        int pwm_buf_sz;
 156        /* input buffer for the ISO-transfer */
 157        __be32 *in_buf;
 158        /* input buffer for single insn */
 159        u8 *insn_buf;
 160
 161        unsigned high_speed:1;
 162        unsigned ai_cmd_running:1;
 163        unsigned ao_cmd_running:1;
 164        unsigned pwm_cmd_running:1;
 165
 166        /* time between samples in units of the timer */
 167        unsigned int ai_timer;
 168        unsigned int ao_timer;
 169        /* counter between acquisitions */
 170        unsigned int ai_counter;
 171        unsigned int ao_counter;
 172        /* interval in frames/uframes */
 173        unsigned int ai_interval;
 174        /* commands */
 175        u8 *dux_commands;
 176        struct mutex mut;
 177};
 178
 179static void usbduxsigma_unlink_urbs(struct urb **urbs, int num_urbs)
 180{
 181        int i;
 182
 183        for (i = 0; i < num_urbs; i++)
 184                usb_kill_urb(urbs[i]);
 185}
 186
 187static void usbduxsigma_ai_stop(struct comedi_device *dev, int do_unlink)
 188{
 189        struct usbduxsigma_private *devpriv = dev->private;
 190
 191        if (do_unlink && devpriv->ai_urbs)
 192                usbduxsigma_unlink_urbs(devpriv->ai_urbs, devpriv->n_ai_urbs);
 193
 194        devpriv->ai_cmd_running = 0;
 195}
 196
 197static int usbduxsigma_ai_cancel(struct comedi_device *dev,
 198                                 struct comedi_subdevice *s)
 199{
 200        struct usbduxsigma_private *devpriv = dev->private;
 201
 202        mutex_lock(&devpriv->mut);
 203        /* unlink only if it is really running */
 204        usbduxsigma_ai_stop(dev, devpriv->ai_cmd_running);
 205        mutex_unlock(&devpriv->mut);
 206
 207        return 0;
 208}
 209
 210static void usbduxsigma_ai_handle_urb(struct comedi_device *dev,
 211                                      struct comedi_subdevice *s,
 212                                      struct urb *urb)
 213{
 214        struct usbduxsigma_private *devpriv = dev->private;
 215        struct comedi_async *async = s->async;
 216        struct comedi_cmd *cmd = &async->cmd;
 217        u32 val;
 218        int ret;
 219        int i;
 220
 221        if ((urb->actual_length > 0) && (urb->status != -EXDEV)) {
 222                devpriv->ai_counter--;
 223                if (devpriv->ai_counter == 0) {
 224                        devpriv->ai_counter = devpriv->ai_timer;
 225
 226                        /*
 227                         * Get the data from the USB bus and hand it over
 228                         * to comedi. Note, first byte is the DIO state.
 229                         */
 230                        for (i = 0; i < cmd->chanlist_len; i++) {
 231                                val = be32_to_cpu(devpriv->in_buf[i + 1]);
 232                                val &= 0x00ffffff; /* strip status byte */
 233                                val = comedi_offset_munge(s, val);
 234                                if (!comedi_buf_write_samples(s, &val, 1))
 235                                        return;
 236                        }
 237
 238                        if (cmd->stop_src == TRIG_COUNT &&
 239                            async->scans_done >= cmd->stop_arg)
 240                                async->events |= COMEDI_CB_EOA;
 241                }
 242        }
 243
 244        /* if command is still running, resubmit urb */
 245        if (!(async->events & COMEDI_CB_CANCEL_MASK)) {
 246                urb->dev = comedi_to_usb_dev(dev);
 247                ret = usb_submit_urb(urb, GFP_ATOMIC);
 248                if (ret < 0) {
 249                        dev_err(dev->class_dev, "urb resubmit failed (%d)\n",
 250                                ret);
 251                        if (ret == -EL2NSYNC)
 252                                dev_err(dev->class_dev,
 253                                        "buggy USB host controller or bug in IRQ handler\n");
 254                        async->events |= COMEDI_CB_ERROR;
 255                }
 256        }
 257}
 258
 259static void usbduxsigma_ai_urb_complete(struct urb *urb)
 260{
 261        struct comedi_device *dev = urb->context;
 262        struct usbduxsigma_private *devpriv = dev->private;
 263        struct comedi_subdevice *s = dev->read_subdev;
 264        struct comedi_async *async = s->async;
 265
 266        /* exit if not running a command, do not resubmit urb */
 267        if (!devpriv->ai_cmd_running)
 268                return;
 269
 270        switch (urb->status) {
 271        case 0:
 272                /* copy the result in the transfer buffer */
 273                memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF);
 274                usbduxsigma_ai_handle_urb(dev, s, urb);
 275                break;
 276
 277        case -EILSEQ:
 278                /*
 279                 * error in the ISOchronous data
 280                 * we don't copy the data into the transfer buffer
 281                 * and recycle the last data byte
 282                 */
 283                dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
 284                usbduxsigma_ai_handle_urb(dev, s, urb);
 285                break;
 286
 287        case -ECONNRESET:
 288        case -ENOENT:
 289        case -ESHUTDOWN:
 290        case -ECONNABORTED:
 291                /* happens after an unlink command */
 292                async->events |= COMEDI_CB_ERROR;
 293                break;
 294
 295        default:
 296                /* a real error */
 297                dev_err(dev->class_dev, "non-zero urb status (%d)\n",
 298                        urb->status);
 299                async->events |= COMEDI_CB_ERROR;
 300                break;
 301        }
 302
 303        /*
 304         * comedi_handle_events() cannot be used in this driver. The (*cancel)
 305         * operation would unlink the urb.
 306         */
 307        if (async->events & COMEDI_CB_CANCEL_MASK)
 308                usbduxsigma_ai_stop(dev, 0);
 309
 310        comedi_event(dev, s);
 311}
 312
 313static void usbduxsigma_ao_stop(struct comedi_device *dev, int do_unlink)
 314{
 315        struct usbduxsigma_private *devpriv = dev->private;
 316
 317        if (do_unlink && devpriv->ao_urbs)
 318                usbduxsigma_unlink_urbs(devpriv->ao_urbs, devpriv->n_ao_urbs);
 319
 320        devpriv->ao_cmd_running = 0;
 321}
 322
 323static int usbduxsigma_ao_cancel(struct comedi_device *dev,
 324                                 struct comedi_subdevice *s)
 325{
 326        struct usbduxsigma_private *devpriv = dev->private;
 327
 328        mutex_lock(&devpriv->mut);
 329        /* unlink only if it is really running */
 330        usbduxsigma_ao_stop(dev, devpriv->ao_cmd_running);
 331        mutex_unlock(&devpriv->mut);
 332
 333        return 0;
 334}
 335
 336static void usbduxsigma_ao_handle_urb(struct comedi_device *dev,
 337                                      struct comedi_subdevice *s,
 338                                      struct urb *urb)
 339{
 340        struct usbduxsigma_private *devpriv = dev->private;
 341        struct comedi_async *async = s->async;
 342        struct comedi_cmd *cmd = &async->cmd;
 343        u8 *datap;
 344        int ret;
 345        int i;
 346
 347        devpriv->ao_counter--;
 348        if (devpriv->ao_counter == 0) {
 349                devpriv->ao_counter = devpriv->ao_timer;
 350
 351                if (cmd->stop_src == TRIG_COUNT &&
 352                    async->scans_done >= cmd->stop_arg) {
 353                        async->events |= COMEDI_CB_EOA;
 354                        return;
 355                }
 356
 357                /* transmit data to the USB bus */
 358                datap = urb->transfer_buffer;
 359                *datap++ = cmd->chanlist_len;
 360                for (i = 0; i < cmd->chanlist_len; i++) {
 361                        unsigned int chan = CR_CHAN(cmd->chanlist[i]);
 362                        unsigned short val;
 363
 364                        if (!comedi_buf_read_samples(s, &val, 1)) {
 365                                dev_err(dev->class_dev, "buffer underflow\n");
 366                                async->events |= COMEDI_CB_OVERFLOW;
 367                                return;
 368                        }
 369
 370                        *datap++ = val;
 371                        *datap++ = chan;
 372                        s->readback[chan] = val;
 373                }
 374        }
 375
 376        /* if command is still running, resubmit urb */
 377        if (!(async->events & COMEDI_CB_CANCEL_MASK)) {
 378                urb->transfer_buffer_length = SIZEOUTBUF;
 379                urb->dev = comedi_to_usb_dev(dev);
 380                urb->status = 0;
 381                urb->interval = 1;      /* (u)frames */
 382                urb->number_of_packets = 1;
 383                urb->iso_frame_desc[0].offset = 0;
 384                urb->iso_frame_desc[0].length = SIZEOUTBUF;
 385                urb->iso_frame_desc[0].status = 0;
 386                ret = usb_submit_urb(urb, GFP_ATOMIC);
 387                if (ret < 0) {
 388                        dev_err(dev->class_dev, "urb resubmit failed (%d)\n",
 389                                ret);
 390                        if (ret == -EL2NSYNC)
 391                                dev_err(dev->class_dev,
 392                                        "buggy USB host controller or bug in IRQ handler\n");
 393                        async->events |= COMEDI_CB_ERROR;
 394                }
 395        }
 396}
 397
 398static void usbduxsigma_ao_urb_complete(struct urb *urb)
 399{
 400        struct comedi_device *dev = urb->context;
 401        struct usbduxsigma_private *devpriv = dev->private;
 402        struct comedi_subdevice *s = dev->write_subdev;
 403        struct comedi_async *async = s->async;
 404
 405        /* exit if not running a command, do not resubmit urb */
 406        if (!devpriv->ao_cmd_running)
 407                return;
 408
 409        switch (urb->status) {
 410        case 0:
 411                usbduxsigma_ao_handle_urb(dev, s, urb);
 412                break;
 413
 414        case -ECONNRESET:
 415        case -ENOENT:
 416        case -ESHUTDOWN:
 417        case -ECONNABORTED:
 418                /* happens after an unlink command */
 419                async->events |= COMEDI_CB_ERROR;
 420                break;
 421
 422        default:
 423                /* a real error */
 424                dev_err(dev->class_dev, "non-zero urb status (%d)\n",
 425                        urb->status);
 426                async->events |= COMEDI_CB_ERROR;
 427                break;
 428        }
 429
 430        /*
 431         * comedi_handle_events() cannot be used in this driver. The (*cancel)
 432         * operation would unlink the urb.
 433         */
 434        if (async->events & COMEDI_CB_CANCEL_MASK)
 435                usbduxsigma_ao_stop(dev, 0);
 436
 437        comedi_event(dev, s);
 438}
 439
 440static int usbduxsigma_submit_urbs(struct comedi_device *dev,
 441                                   struct urb **urbs, int num_urbs,
 442                                   int input_urb)
 443{
 444        struct usb_device *usb = comedi_to_usb_dev(dev);
 445        struct urb *urb;
 446        int ret;
 447        int i;
 448
 449        /* Submit all URBs and start the transfer on the bus */
 450        for (i = 0; i < num_urbs; i++) {
 451                urb = urbs[i];
 452
 453                /* in case of a resubmission after an unlink... */
 454                if (input_urb)
 455                        urb->interval = 1;
 456                urb->context = dev;
 457                urb->dev = usb;
 458                urb->status = 0;
 459                urb->transfer_flags = URB_ISO_ASAP;
 460
 461                ret = usb_submit_urb(urb, GFP_ATOMIC);
 462                if (ret)
 463                        return ret;
 464        }
 465        return 0;
 466}
 467
 468static int usbduxsigma_chans_to_interval(int num_chan)
 469{
 470        if (num_chan <= 2)
 471                return 2;       /* 4kHz */
 472        if (num_chan <= 8)
 473                return 4;       /* 2kHz */
 474        return 8;               /* 1kHz */
 475}
 476
 477static int usbduxsigma_ai_cmdtest(struct comedi_device *dev,
 478                                  struct comedi_subdevice *s,
 479                                  struct comedi_cmd *cmd)
 480{
 481        struct usbduxsigma_private *devpriv = dev->private;
 482        int high_speed = devpriv->high_speed;
 483        int interval = usbduxsigma_chans_to_interval(cmd->chanlist_len);
 484        unsigned int tmp;
 485        int err = 0;
 486
 487        /* Step 1 : check if triggers are trivially valid */
 488
 489        err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
 490        err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
 491        err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
 492        err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 493        err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 494
 495        if (err)
 496                return 1;
 497
 498        /* Step 2a : make sure trigger sources are unique */
 499
 500        err |= comedi_check_trigger_is_unique(cmd->start_src);
 501        err |= comedi_check_trigger_is_unique(cmd->stop_src);
 502
 503        /* Step 2b : and mutually compatible */
 504
 505        if (err)
 506                return 2;
 507
 508        /* Step 3: check if arguments are trivially valid */
 509
 510        err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
 511
 512        if (high_speed) {
 513                /*
 514                 * In high speed mode microframes are possible.
 515                 * However, during one microframe we can roughly
 516                 * sample two channels. Thus, the more channels
 517                 * are in the channel list the more time we need.
 518                 */
 519                err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
 520                                                    (125000 * interval));
 521        } else {
 522                /* full speed */
 523                /* 1kHz scans every USB frame */
 524                err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
 525                                                    1000000);
 526        }
 527
 528        err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
 529                                           cmd->chanlist_len);
 530
 531        if (cmd->stop_src == TRIG_COUNT)
 532                err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
 533        else    /* TRIG_NONE */
 534                err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
 535
 536        if (err)
 537                return 3;
 538
 539        /* Step 4: fix up any arguments */
 540
 541        tmp = rounddown(cmd->scan_begin_arg, high_speed ? 125000 : 1000000);
 542        err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, tmp);
 543
 544        if (err)
 545                return 4;
 546
 547        return 0;
 548}
 549
 550/*
 551 * creates the ADC command for the MAX1271
 552 * range is the range value from comedi
 553 */
 554static void create_adc_command(unsigned int chan,
 555                               u8 *muxsg0, u8 *muxsg1)
 556{
 557        if (chan < 8)
 558                (*muxsg0) = (*muxsg0) | (1 << chan);
 559        else if (chan < 16)
 560                (*muxsg1) = (*muxsg1) | (1 << (chan - 8));
 561}
 562
 563static int usbbuxsigma_send_cmd(struct comedi_device *dev, int cmd_type)
 564{
 565        struct usb_device *usb = comedi_to_usb_dev(dev);
 566        struct usbduxsigma_private *devpriv = dev->private;
 567        int nsent;
 568
 569        devpriv->dux_commands[0] = cmd_type;
 570
 571        return usb_bulk_msg(usb, usb_sndbulkpipe(usb, 1),
 572                            devpriv->dux_commands, SIZEOFDUXBUFFER,
 573                            &nsent, BULK_TIMEOUT);
 574}
 575
 576static int usbduxsigma_receive_cmd(struct comedi_device *dev, int command)
 577{
 578        struct usb_device *usb = comedi_to_usb_dev(dev);
 579        struct usbduxsigma_private *devpriv = dev->private;
 580        int nrec;
 581        int ret;
 582        int i;
 583
 584        for (i = 0; i < RETRIES; i++) {
 585                ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, 8),
 586                                   devpriv->insn_buf, SIZEINSNBUF,
 587                                   &nrec, BULK_TIMEOUT);
 588                if (ret < 0)
 589                        return ret;
 590
 591                if (devpriv->insn_buf[0] == command)
 592                        return 0;
 593        }
 594        /*
 595         * This is only reached if the data has been requested a
 596         * couple of times and the command was not received.
 597         */
 598        return -EFAULT;
 599}
 600
 601static int usbduxsigma_ai_inttrig(struct comedi_device *dev,
 602                                  struct comedi_subdevice *s,
 603                                  unsigned int trig_num)
 604{
 605        struct usbduxsigma_private *devpriv = dev->private;
 606        struct comedi_cmd *cmd = &s->async->cmd;
 607        int ret;
 608
 609        if (trig_num != cmd->start_arg)
 610                return -EINVAL;
 611
 612        mutex_lock(&devpriv->mut);
 613        if (!devpriv->ai_cmd_running) {
 614                devpriv->ai_cmd_running = 1;
 615                ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
 616                                              devpriv->n_ai_urbs, 1);
 617                if (ret < 0) {
 618                        devpriv->ai_cmd_running = 0;
 619                        mutex_unlock(&devpriv->mut);
 620                        return ret;
 621                }
 622                s->async->inttrig = NULL;
 623        }
 624        mutex_unlock(&devpriv->mut);
 625
 626        return 1;
 627}
 628
 629static int usbduxsigma_ai_cmd(struct comedi_device *dev,
 630                              struct comedi_subdevice *s)
 631{
 632        struct usbduxsigma_private *devpriv = dev->private;
 633        struct comedi_cmd *cmd = &s->async->cmd;
 634        unsigned int len = cmd->chanlist_len;
 635        u8 muxsg0 = 0;
 636        u8 muxsg1 = 0;
 637        u8 sysred = 0;
 638        int ret;
 639        int i;
 640
 641        mutex_lock(&devpriv->mut);
 642
 643        if (devpriv->high_speed) {
 644                /*
 645                 * every 2 channels get a time window of 125us. Thus, if we
 646                 * sample all 16 channels we need 1ms. If we sample only one
 647                 * channel we need only 125us
 648                 */
 649                unsigned int interval = usbduxsigma_chans_to_interval(len);
 650
 651                devpriv->ai_interval = interval;
 652                devpriv->ai_timer = cmd->scan_begin_arg / (125000 * interval);
 653        } else {
 654                /* interval always 1ms */
 655                devpriv->ai_interval = 1;
 656                devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
 657        }
 658
 659        for (i = 0; i < len; i++) {
 660                unsigned int chan  = CR_CHAN(cmd->chanlist[i]);
 661
 662                create_adc_command(chan, &muxsg0, &muxsg1);
 663        }
 664
 665        devpriv->dux_commands[1] = devpriv->ai_interval;
 666        devpriv->dux_commands[2] = len;  /* num channels per time step */
 667        devpriv->dux_commands[3] = 0x12; /* CONFIG0 */
 668        devpriv->dux_commands[4] = 0x03; /* CONFIG1: 23kHz sample, delay 0us */
 669        devpriv->dux_commands[5] = 0x00; /* CONFIG3: diff. channels off */
 670        devpriv->dux_commands[6] = muxsg0;
 671        devpriv->dux_commands[7] = muxsg1;
 672        devpriv->dux_commands[8] = sysred;
 673
 674        ret = usbbuxsigma_send_cmd(dev, USBBUXSIGMA_AD_CMD);
 675        if (ret < 0) {
 676                mutex_unlock(&devpriv->mut);
 677                return ret;
 678        }
 679
 680        devpriv->ai_counter = devpriv->ai_timer;
 681
 682        if (cmd->start_src == TRIG_NOW) {
 683                /* enable this acquisition operation */
 684                devpriv->ai_cmd_running = 1;
 685                ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
 686                                              devpriv->n_ai_urbs, 1);
 687                if (ret < 0) {
 688                        devpriv->ai_cmd_running = 0;
 689                        mutex_unlock(&devpriv->mut);
 690                        return ret;
 691                }
 692                s->async->inttrig = NULL;
 693        } else {        /* TRIG_INT */
 694                s->async->inttrig = usbduxsigma_ai_inttrig;
 695        }
 696
 697        mutex_unlock(&devpriv->mut);
 698
 699        return 0;
 700}
 701
 702static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
 703                                    struct comedi_subdevice *s,
 704                                    struct comedi_insn *insn,
 705                                    unsigned int *data)
 706{
 707        struct usbduxsigma_private *devpriv = dev->private;
 708        unsigned int chan = CR_CHAN(insn->chanspec);
 709        u8 muxsg0 = 0;
 710        u8 muxsg1 = 0;
 711        u8 sysred = 0;
 712        int ret;
 713        int i;
 714
 715        mutex_lock(&devpriv->mut);
 716        if (devpriv->ai_cmd_running) {
 717                mutex_unlock(&devpriv->mut);
 718                return -EBUSY;
 719        }
 720
 721        create_adc_command(chan, &muxsg0, &muxsg1);
 722
 723        /* Mode 0 is used to get a single conversion on demand */
 724        devpriv->dux_commands[1] = 0x16; /* CONFIG0: chopper on */
 725        devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
 726        devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
 727        devpriv->dux_commands[4] = muxsg0;
 728        devpriv->dux_commands[5] = muxsg1;
 729        devpriv->dux_commands[6] = sysred;
 730
 731        /* adc commands */
 732        ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
 733        if (ret < 0) {
 734                mutex_unlock(&devpriv->mut);
 735                return ret;
 736        }
 737
 738        for (i = 0; i < insn->n; i++) {
 739                u32 val;
 740
 741                ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
 742                if (ret < 0) {
 743                        mutex_unlock(&devpriv->mut);
 744                        return ret;
 745                }
 746
 747                /* 32 bits big endian from the A/D converter */
 748                val = be32_to_cpu(get_unaligned((__be32
 749                                                 *)(devpriv->insn_buf + 1)));
 750                val &= 0x00ffffff;      /* strip status byte */
 751                data[i] = comedi_offset_munge(s, val);
 752        }
 753        mutex_unlock(&devpriv->mut);
 754
 755        return insn->n;
 756}
 757
 758static int usbduxsigma_ao_insn_read(struct comedi_device *dev,
 759                                    struct comedi_subdevice *s,
 760                                    struct comedi_insn *insn,
 761                                    unsigned int *data)
 762{
 763        struct usbduxsigma_private *devpriv = dev->private;
 764        int ret;
 765
 766        mutex_lock(&devpriv->mut);
 767        ret = comedi_readback_insn_read(dev, s, insn, data);
 768        mutex_unlock(&devpriv->mut);
 769
 770        return ret;
 771}
 772
 773static int usbduxsigma_ao_insn_write(struct comedi_device *dev,
 774                                     struct comedi_subdevice *s,
 775                                     struct comedi_insn *insn,
 776                                     unsigned int *data)
 777{
 778        struct usbduxsigma_private *devpriv = dev->private;
 779        unsigned int chan = CR_CHAN(insn->chanspec);
 780        int ret;
 781        int i;
 782
 783        mutex_lock(&devpriv->mut);
 784        if (devpriv->ao_cmd_running) {
 785                mutex_unlock(&devpriv->mut);
 786                return -EBUSY;
 787        }
 788
 789        for (i = 0; i < insn->n; i++) {
 790                devpriv->dux_commands[1] = 1;           /* num channels */
 791                devpriv->dux_commands[2] = data[i];     /* value */
 792                devpriv->dux_commands[3] = chan;        /* channel number */
 793                ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DA_CMD);
 794                if (ret < 0) {
 795                        mutex_unlock(&devpriv->mut);
 796                        return ret;
 797                }
 798                s->readback[chan] = data[i];
 799        }
 800        mutex_unlock(&devpriv->mut);
 801
 802        return insn->n;
 803}
 804
 805static int usbduxsigma_ao_inttrig(struct comedi_device *dev,
 806                                  struct comedi_subdevice *s,
 807                                  unsigned int trig_num)
 808{
 809        struct usbduxsigma_private *devpriv = dev->private;
 810        struct comedi_cmd *cmd = &s->async->cmd;
 811        int ret;
 812
 813        if (trig_num != cmd->start_arg)
 814                return -EINVAL;
 815
 816        mutex_lock(&devpriv->mut);
 817        if (!devpriv->ao_cmd_running) {
 818                devpriv->ao_cmd_running = 1;
 819                ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
 820                                              devpriv->n_ao_urbs, 0);
 821                if (ret < 0) {
 822                        devpriv->ao_cmd_running = 0;
 823                        mutex_unlock(&devpriv->mut);
 824                        return ret;
 825                }
 826                s->async->inttrig = NULL;
 827        }
 828        mutex_unlock(&devpriv->mut);
 829
 830        return 1;
 831}
 832
 833static int usbduxsigma_ao_cmdtest(struct comedi_device *dev,
 834                                  struct comedi_subdevice *s,
 835                                  struct comedi_cmd *cmd)
 836{
 837        struct usbduxsigma_private *devpriv = dev->private;
 838        unsigned int tmp;
 839        int err = 0;
 840
 841        /* Step 1 : check if triggers are trivially valid */
 842
 843        err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
 844
 845        /*
 846         * For now, always use "scan" timing with all channels updated at once
 847         * (cmd->scan_begin_src == TRIG_TIMER, cmd->convert_src == TRIG_NOW).
 848         *
 849         * In a future version, "convert" timing with channels updated
 850         * indivually may be supported in high speed mode
 851         * (cmd->scan_begin_src == TRIG_FOLLOW, cmd->convert_src == TRIG_TIMER).
 852         */
 853        err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
 854        err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
 855        err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 856        err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 857
 858        if (err) {
 859                mutex_unlock(&devpriv->mut);
 860                return 1;
 861        }
 862
 863        /* Step 2a : make sure trigger sources are unique */
 864
 865        err |= comedi_check_trigger_is_unique(cmd->start_src);
 866        err |= comedi_check_trigger_is_unique(cmd->stop_src);
 867
 868        /* Step 2b : and mutually compatible */
 869
 870        if (err)
 871                return 2;
 872
 873        /* Step 3: check if arguments are trivially valid */
 874
 875        err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
 876
 877        err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, 1000000);
 878
 879        err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
 880                                           cmd->chanlist_len);
 881
 882        if (cmd->stop_src == TRIG_COUNT)
 883                err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
 884        else    /* TRIG_NONE */
 885                err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
 886
 887        if (err)
 888                return 3;
 889
 890        /* Step 4: fix up any arguments */
 891
 892        tmp = rounddown(cmd->scan_begin_arg, 1000000);
 893        err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, tmp);
 894
 895        if (err)
 896                return 4;
 897
 898        return 0;
 899}
 900
 901static int usbduxsigma_ao_cmd(struct comedi_device *dev,
 902                              struct comedi_subdevice *s)
 903{
 904        struct usbduxsigma_private *devpriv = dev->private;
 905        struct comedi_cmd *cmd = &s->async->cmd;
 906        int ret;
 907
 908        mutex_lock(&devpriv->mut);
 909
 910        /*
 911         * For now, only "scan" timing is supported.  A future version may
 912         * support "convert" timing in high speed mode.
 913         *
 914         * Timing of the scan: every 1ms all channels updated at once.
 915         */
 916        devpriv->ao_timer = cmd->scan_begin_arg / 1000000;
 917
 918        devpriv->ao_counter = devpriv->ao_timer;
 919
 920        if (cmd->start_src == TRIG_NOW) {
 921                /* enable this acquisition operation */
 922                devpriv->ao_cmd_running = 1;
 923                ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
 924                                              devpriv->n_ao_urbs, 0);
 925                if (ret < 0) {
 926                        devpriv->ao_cmd_running = 0;
 927                        mutex_unlock(&devpriv->mut);
 928                        return ret;
 929                }
 930                s->async->inttrig = NULL;
 931        } else {        /* TRIG_INT */
 932                s->async->inttrig = usbduxsigma_ao_inttrig;
 933        }
 934
 935        mutex_unlock(&devpriv->mut);
 936
 937        return 0;
 938}
 939
 940static int usbduxsigma_dio_insn_config(struct comedi_device *dev,
 941                                       struct comedi_subdevice *s,
 942                                       struct comedi_insn *insn,
 943                                       unsigned int *data)
 944{
 945        int ret;
 946
 947        ret = comedi_dio_insn_config(dev, s, insn, data, 0);
 948        if (ret)
 949                return ret;
 950
 951        /*
 952         * We don't tell the firmware here as it would take 8 frames
 953         * to submit the information. We do it in the (*insn_bits).
 954         */
 955        return insn->n;
 956}
 957
 958static int usbduxsigma_dio_insn_bits(struct comedi_device *dev,
 959                                     struct comedi_subdevice *s,
 960                                     struct comedi_insn *insn,
 961                                     unsigned int *data)
 962{
 963        struct usbduxsigma_private *devpriv = dev->private;
 964        int ret;
 965
 966        mutex_lock(&devpriv->mut);
 967
 968        comedi_dio_update_state(s, data);
 969
 970        /* Always update the hardware. See the (*insn_config). */
 971        devpriv->dux_commands[1] = s->io_bits & 0xff;
 972        devpriv->dux_commands[4] = s->state & 0xff;
 973        devpriv->dux_commands[2] = (s->io_bits >> 8) & 0xff;
 974        devpriv->dux_commands[5] = (s->state >> 8) & 0xff;
 975        devpriv->dux_commands[3] = (s->io_bits >> 16) & 0xff;
 976        devpriv->dux_commands[6] = (s->state >> 16) & 0xff;
 977
 978        ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
 979        if (ret < 0)
 980                goto done;
 981        ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
 982        if (ret < 0)
 983                goto done;
 984
 985        s->state = devpriv->insn_buf[1] |
 986                   (devpriv->insn_buf[2] << 8) |
 987                   (devpriv->insn_buf[3] << 16);
 988
 989        data[1] = s->state;
 990        ret = insn->n;
 991
 992done:
 993        mutex_unlock(&devpriv->mut);
 994
 995        return ret;
 996}
 997
 998static void usbduxsigma_pwm_stop(struct comedi_device *dev, int do_unlink)
 999{
1000        struct usbduxsigma_private *devpriv = dev->private;
1001
1002        if (do_unlink) {
1003                if (devpriv->pwm_urb)
1004                        usb_kill_urb(devpriv->pwm_urb);
1005        }
1006
1007        devpriv->pwm_cmd_running = 0;
1008}
1009
1010static int usbduxsigma_pwm_cancel(struct comedi_device *dev,
1011                                  struct comedi_subdevice *s)
1012{
1013        struct usbduxsigma_private *devpriv = dev->private;
1014
1015        /* unlink only if it is really running */
1016        usbduxsigma_pwm_stop(dev, devpriv->pwm_cmd_running);
1017
1018        return usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_OFF_CMD);
1019}
1020
1021static void usbduxsigma_pwm_urb_complete(struct urb *urb)
1022{
1023        struct comedi_device *dev = urb->context;
1024        struct usbduxsigma_private *devpriv = dev->private;
1025        int ret;
1026
1027        switch (urb->status) {
1028        case 0:
1029                /* success */
1030                break;
1031
1032        case -ECONNRESET:
1033        case -ENOENT:
1034        case -ESHUTDOWN:
1035        case -ECONNABORTED:
1036                /* happens after an unlink command */
1037                if (devpriv->pwm_cmd_running)
1038                        usbduxsigma_pwm_stop(dev, 0);   /* w/o unlink */
1039                return;
1040
1041        default:
1042                /* a real error */
1043                if (devpriv->pwm_cmd_running) {
1044                        dev_err(dev->class_dev, "non-zero urb status (%d)\n",
1045                                urb->status);
1046                        usbduxsigma_pwm_stop(dev, 0);   /* w/o unlink */
1047                }
1048                return;
1049        }
1050
1051        if (!devpriv->pwm_cmd_running)
1052                return;
1053
1054        urb->transfer_buffer_length = devpriv->pwm_buf_sz;
1055        urb->dev = comedi_to_usb_dev(dev);
1056        urb->status = 0;
1057        ret = usb_submit_urb(urb, GFP_ATOMIC);
1058        if (ret < 0) {
1059                dev_err(dev->class_dev, "urb resubmit failed (%d)\n", ret);
1060                if (ret == -EL2NSYNC)
1061                        dev_err(dev->class_dev,
1062                                "buggy USB host controller or bug in IRQ handler\n");
1063                usbduxsigma_pwm_stop(dev, 0);   /* w/o unlink */
1064        }
1065}
1066
1067static int usbduxsigma_submit_pwm_urb(struct comedi_device *dev)
1068{
1069        struct usb_device *usb = comedi_to_usb_dev(dev);
1070        struct usbduxsigma_private *devpriv = dev->private;
1071        struct urb *urb = devpriv->pwm_urb;
1072
1073        /* in case of a resubmission after an unlink... */
1074        usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, 4),
1075                          urb->transfer_buffer, devpriv->pwm_buf_sz,
1076                          usbduxsigma_pwm_urb_complete, dev);
1077
1078        return usb_submit_urb(urb, GFP_ATOMIC);
1079}
1080
1081static int usbduxsigma_pwm_period(struct comedi_device *dev,
1082                                  struct comedi_subdevice *s,
1083                                  unsigned int period)
1084{
1085        struct usbduxsigma_private *devpriv = dev->private;
1086        int fx2delay = 255;
1087
1088        if (period < MIN_PWM_PERIOD)
1089                return -EAGAIN;
1090
1091        fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
1092        if (fx2delay > 255)
1093                return -EAGAIN;
1094
1095        devpriv->pwm_delay = fx2delay;
1096        devpriv->pwm_period = period;
1097        return 0;
1098}
1099
1100static int usbduxsigma_pwm_start(struct comedi_device *dev,
1101                                 struct comedi_subdevice *s)
1102{
1103        struct usbduxsigma_private *devpriv = dev->private;
1104        int ret;
1105
1106        if (devpriv->pwm_cmd_running)
1107                return 0;
1108
1109        devpriv->dux_commands[1] = devpriv->pwm_delay;
1110        ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_ON_CMD);
1111        if (ret < 0)
1112                return ret;
1113
1114        memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);
1115
1116        devpriv->pwm_cmd_running = 1;
1117        ret = usbduxsigma_submit_pwm_urb(dev);
1118        if (ret < 0) {
1119                devpriv->pwm_cmd_running = 0;
1120                return ret;
1121        }
1122
1123        return 0;
1124}
1125
1126static void usbduxsigma_pwm_pattern(struct comedi_device *dev,
1127                                    struct comedi_subdevice *s,
1128                                    unsigned int chan,
1129                                    unsigned int value,
1130                                    unsigned int sign)
1131{
1132        struct usbduxsigma_private *devpriv = dev->private;
1133        char pwm_mask = (1 << chan);    /* DIO bit for the PWM data */
1134        char sgn_mask = (16 << chan);   /* DIO bit for the sign */
1135        char *buf = (char *)(devpriv->pwm_urb->transfer_buffer);
1136        int szbuf = devpriv->pwm_buf_sz;
1137        int i;
1138
1139        for (i = 0; i < szbuf; i++) {
1140                char c = *buf;
1141
1142                c &= ~pwm_mask;
1143                if (i < value)
1144                        c |= pwm_mask;
1145                if (!sign)
1146                        c &= ~sgn_mask;
1147                else
1148                        c |= sgn_mask;
1149                *buf++ = c;
1150        }
1151}
1152
1153static int usbduxsigma_pwm_write(struct comedi_device *dev,
1154                                 struct comedi_subdevice *s,
1155                                 struct comedi_insn *insn,
1156                                 unsigned int *data)
1157{
1158        unsigned int chan = CR_CHAN(insn->chanspec);
1159
1160        /*
1161         * It doesn't make sense to support more than one value here
1162         * because it would just overwrite the PWM buffer.
1163         */
1164        if (insn->n != 1)
1165                return -EINVAL;
1166
1167        /*
1168         * The sign is set via a special INSN only, this gives us 8 bits
1169         * for normal operation, sign is 0 by default.
1170         */
1171        usbduxsigma_pwm_pattern(dev, s, chan, data[0], 0);
1172
1173        return insn->n;
1174}
1175
1176static int usbduxsigma_pwm_config(struct comedi_device *dev,
1177                                  struct comedi_subdevice *s,
1178                                  struct comedi_insn *insn,
1179                                  unsigned int *data)
1180{
1181        struct usbduxsigma_private *devpriv = dev->private;
1182        unsigned int chan = CR_CHAN(insn->chanspec);
1183
1184        switch (data[0]) {
1185        case INSN_CONFIG_ARM:
1186                /*
1187                 * if not zero the PWM is limited to a certain time which is
1188                 * not supported here
1189                 */
1190                if (data[1] != 0)
1191                        return -EINVAL;
1192                return usbduxsigma_pwm_start(dev, s);
1193        case INSN_CONFIG_DISARM:
1194                return usbduxsigma_pwm_cancel(dev, s);
1195        case INSN_CONFIG_GET_PWM_STATUS:
1196                data[1] = devpriv->pwm_cmd_running;
1197                return 0;
1198        case INSN_CONFIG_PWM_SET_PERIOD:
1199                return usbduxsigma_pwm_period(dev, s, data[1]);
1200        case INSN_CONFIG_PWM_GET_PERIOD:
1201                data[1] = devpriv->pwm_period;
1202                return 0;
1203        case INSN_CONFIG_PWM_SET_H_BRIDGE:
1204                /*
1205                 * data[1] = value
1206                 * data[2] = sign (for a relay)
1207                 */
1208                usbduxsigma_pwm_pattern(dev, s, chan, data[1], (data[2] != 0));
1209                return 0;
1210        case INSN_CONFIG_PWM_GET_H_BRIDGE:
1211                /* values are not kept in this driver, nothing to return */
1212                return -EINVAL;
1213        }
1214        return -EINVAL;
1215}
1216
1217static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan)
1218{
1219        struct comedi_subdevice *s = dev->read_subdev;
1220        struct usbduxsigma_private *devpriv = dev->private;
1221        u8 sysred;
1222        u32 val;
1223        int ret;
1224
1225        switch (chan) {
1226        default:
1227        case 0:
1228                sysred = 0;             /* ADC zero */
1229                break;
1230        case 1:
1231                sysred = 1;             /* ADC offset */
1232                break;
1233        case 2:
1234                sysred = 4;             /* VCC */
1235                break;
1236        case 3:
1237                sysred = 8;             /* temperature */
1238                break;
1239        case 4:
1240                sysred = 16;            /* gain */
1241                break;
1242        case 5:
1243                sysred =  32;           /* ref */
1244                break;
1245        }
1246
1247        devpriv->dux_commands[1] = 0x12; /* CONFIG0 */
1248        devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
1249        devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
1250        devpriv->dux_commands[4] = 0;
1251        devpriv->dux_commands[5] = 0;
1252        devpriv->dux_commands[6] = sysred;
1253        ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
1254        if (ret < 0)
1255                return ret;
1256
1257        ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
1258        if (ret < 0)
1259                return ret;
1260
1261        /* 32 bits big endian from the A/D converter */
1262        val = be32_to_cpu(get_unaligned((__be32 *)(devpriv->insn_buf + 1)));
1263        val &= 0x00ffffff;      /* strip status byte */
1264
1265        return (int)comedi_offset_munge(s, val);
1266}
1267
1268static int usbduxsigma_firmware_upload(struct comedi_device *dev,
1269                                       const u8 *data, size_t size,
1270                                       unsigned long context)
1271{
1272        struct usb_device *usb = comedi_to_usb_dev(dev);
1273        u8 *buf;
1274        u8 *tmp;
1275        int ret;
1276
1277        if (!data)
1278                return 0;
1279
1280        if (size > FIRMWARE_MAX_LEN) {
1281                dev_err(dev->class_dev, "firmware binary too large for FX2\n");
1282                return -ENOMEM;
1283        }
1284
1285        /* we generate a local buffer for the firmware */
1286        buf = kmemdup(data, size, GFP_KERNEL);
1287        if (!buf)
1288                return -ENOMEM;
1289
1290        /* we need a malloc'ed buffer for usb_control_msg() */
1291        tmp = kmalloc(1, GFP_KERNEL);
1292        if (!tmp) {
1293                kfree(buf);
1294                return -ENOMEM;
1295        }
1296
1297        /* stop the current firmware on the device */
1298        *tmp = 1;       /* 7f92 to one */
1299        ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1300                              USBDUXSUB_FIRMWARE,
1301                              VENDOR_DIR_OUT,
1302                              USBDUXSUB_CPUCS, 0x0000,
1303                              tmp, 1,
1304                              BULK_TIMEOUT);
1305        if (ret < 0) {
1306                dev_err(dev->class_dev, "can not stop firmware\n");
1307                goto done;
1308        }
1309
1310        /* upload the new firmware to the device */
1311        ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1312                              USBDUXSUB_FIRMWARE,
1313                              VENDOR_DIR_OUT,
1314                              0, 0x0000,
1315                              buf, size,
1316                              BULK_TIMEOUT);
1317        if (ret < 0) {
1318                dev_err(dev->class_dev, "firmware upload failed\n");
1319                goto done;
1320        }
1321
1322        /* start the new firmware on the device */
1323        *tmp = 0;       /* 7f92 to zero */
1324        ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1325                              USBDUXSUB_FIRMWARE,
1326                              VENDOR_DIR_OUT,
1327                              USBDUXSUB_CPUCS, 0x0000,
1328                              tmp, 1,
1329                              BULK_TIMEOUT);
1330        if (ret < 0)
1331                dev_err(dev->class_dev, "can not start firmware\n");
1332
1333done:
1334        kfree(tmp);
1335        kfree(buf);
1336        return ret;
1337}
1338
1339static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev)
1340{
1341        struct usb_device *usb = comedi_to_usb_dev(dev);
1342        struct usbduxsigma_private *devpriv = dev->private;
1343        struct urb *urb;
1344        int i;
1345
1346        devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1347        devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL);
1348        devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1349        devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(urb), GFP_KERNEL);
1350        devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(urb), GFP_KERNEL);
1351        if (!devpriv->dux_commands || !devpriv->in_buf || !devpriv->insn_buf ||
1352            !devpriv->ai_urbs || !devpriv->ao_urbs)
1353                return -ENOMEM;
1354
1355        for (i = 0; i < devpriv->n_ai_urbs; i++) {
1356                /* one frame: 1ms */
1357                urb = usb_alloc_urb(1, GFP_KERNEL);
1358                if (!urb)
1359                        return -ENOMEM;
1360                devpriv->ai_urbs[i] = urb;
1361                urb->dev = usb;
1362                /* will be filled later with a pointer to the comedi-device */
1363                /* and ONLY then the urb should be submitted */
1364                urb->context = NULL;
1365                urb->pipe = usb_rcvisocpipe(usb, 6);
1366                urb->transfer_flags = URB_ISO_ASAP;
1367                urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1368                if (!urb->transfer_buffer)
1369                        return -ENOMEM;
1370                urb->complete = usbduxsigma_ai_urb_complete;
1371                urb->number_of_packets = 1;
1372                urb->transfer_buffer_length = SIZEINBUF;
1373                urb->iso_frame_desc[0].offset = 0;
1374                urb->iso_frame_desc[0].length = SIZEINBUF;
1375        }
1376
1377        for (i = 0; i < devpriv->n_ao_urbs; i++) {
1378                /* one frame: 1ms */
1379                urb = usb_alloc_urb(1, GFP_KERNEL);
1380                if (!urb)
1381                        return -ENOMEM;
1382                devpriv->ao_urbs[i] = urb;
1383                urb->dev = usb;
1384                /* will be filled later with a pointer to the comedi-device */
1385                /* and ONLY then the urb should be submitted */
1386                urb->context = NULL;
1387                urb->pipe = usb_sndisocpipe(usb, 2);
1388                urb->transfer_flags = URB_ISO_ASAP;
1389                urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1390                if (!urb->transfer_buffer)
1391                        return -ENOMEM;
1392                urb->complete = usbduxsigma_ao_urb_complete;
1393                urb->number_of_packets = 1;
1394                urb->transfer_buffer_length = SIZEOUTBUF;
1395                urb->iso_frame_desc[0].offset = 0;
1396                urb->iso_frame_desc[0].length = SIZEOUTBUF;
1397                urb->interval = 1;      /* (u)frames */
1398        }
1399
1400        if (devpriv->pwm_buf_sz) {
1401                urb = usb_alloc_urb(0, GFP_KERNEL);
1402                if (!urb)
1403                        return -ENOMEM;
1404                devpriv->pwm_urb = urb;
1405
1406                urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz,
1407                                               GFP_KERNEL);
1408                if (!urb->transfer_buffer)
1409                        return -ENOMEM;
1410        }
1411
1412        return 0;
1413}
1414
1415static void usbduxsigma_free_usb_buffers(struct comedi_device *dev)
1416{
1417        struct usbduxsigma_private *devpriv = dev->private;
1418        struct urb *urb;
1419        int i;
1420
1421        urb = devpriv->pwm_urb;
1422        if (urb) {
1423                kfree(urb->transfer_buffer);
1424                usb_free_urb(urb);
1425        }
1426        if (devpriv->ao_urbs) {
1427                for (i = 0; i < devpriv->n_ao_urbs; i++) {
1428                        urb = devpriv->ao_urbs[i];
1429                        if (urb) {
1430                                kfree(urb->transfer_buffer);
1431                                usb_free_urb(urb);
1432                        }
1433                }
1434                kfree(devpriv->ao_urbs);
1435        }
1436        if (devpriv->ai_urbs) {
1437                for (i = 0; i < devpriv->n_ai_urbs; i++) {
1438                        urb = devpriv->ai_urbs[i];
1439                        if (urb) {
1440                                kfree(urb->transfer_buffer);
1441                                usb_free_urb(urb);
1442                        }
1443                }
1444                kfree(devpriv->ai_urbs);
1445        }
1446        kfree(devpriv->insn_buf);
1447        kfree(devpriv->in_buf);
1448        kfree(devpriv->dux_commands);
1449}
1450
1451static int usbduxsigma_auto_attach(struct comedi_device *dev,
1452                                   unsigned long context_unused)
1453{
1454        struct usb_interface *intf = comedi_to_usb_interface(dev);
1455        struct usb_device *usb = comedi_to_usb_dev(dev);
1456        struct usbduxsigma_private *devpriv;
1457        struct comedi_subdevice *s;
1458        int offset;
1459        int ret;
1460
1461        devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1462        if (!devpriv)
1463                return -ENOMEM;
1464
1465        mutex_init(&devpriv->mut);
1466
1467        usb_set_intfdata(intf, devpriv);
1468
1469        devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1470        if (devpriv->high_speed) {
1471                devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH;
1472                devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH;
1473                devpriv->pwm_buf_sz = 512;
1474        } else {
1475                devpriv->n_ai_urbs = NUMOFINBUFFERSFULL;
1476                devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL;
1477        }
1478
1479        ret = usbduxsigma_alloc_usb_buffers(dev);
1480        if (ret)
1481                return ret;
1482
1483        /* setting to alternate setting 3: enabling iso ep and bulk ep. */
1484        ret = usb_set_interface(usb, intf->altsetting->desc.bInterfaceNumber,
1485                                3);
1486        if (ret < 0) {
1487                dev_err(dev->class_dev,
1488                        "could not set alternate setting 3 in high speed\n");
1489                return ret;
1490        }
1491
1492        ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1493                                   usbduxsigma_firmware_upload, 0);
1494        if (ret)
1495                return ret;
1496
1497        ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 4 : 3);
1498        if (ret)
1499                return ret;
1500
1501        /* Analog Input subdevice */
1502        s = &dev->subdevices[0];
1503        dev->read_subdev = s;
1504        s->type         = COMEDI_SUBD_AI;
1505        s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ | SDF_LSAMPL;
1506        s->n_chan       = NUMCHANNELS;
1507        s->len_chanlist = NUMCHANNELS;
1508        s->maxdata      = 0x00ffffff;
1509        s->range_table  = &usbduxsigma_ai_range;
1510        s->insn_read    = usbduxsigma_ai_insn_read;
1511        s->do_cmdtest   = usbduxsigma_ai_cmdtest;
1512        s->do_cmd       = usbduxsigma_ai_cmd;
1513        s->cancel       = usbduxsigma_ai_cancel;
1514
1515        /* Analog Output subdevice */
1516        s = &dev->subdevices[1];
1517        dev->write_subdev = s;
1518        s->type         = COMEDI_SUBD_AO;
1519        s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1520        s->n_chan       = 4;
1521        s->len_chanlist = s->n_chan;
1522        s->maxdata      = 0x00ff;
1523        s->range_table  = &range_unipolar2_5;
1524        s->insn_write   = usbduxsigma_ao_insn_write;
1525        s->insn_read    = usbduxsigma_ao_insn_read;
1526        s->do_cmdtest   = usbduxsigma_ao_cmdtest;
1527        s->do_cmd       = usbduxsigma_ao_cmd;
1528        s->cancel       = usbduxsigma_ao_cancel;
1529
1530        ret = comedi_alloc_subdev_readback(s);
1531        if (ret)
1532                return ret;
1533
1534        /* Digital I/O subdevice */
1535        s = &dev->subdevices[2];
1536        s->type         = COMEDI_SUBD_DIO;
1537        s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1538        s->n_chan       = 24;
1539        s->maxdata      = 1;
1540        s->range_table  = &range_digital;
1541        s->insn_bits    = usbduxsigma_dio_insn_bits;
1542        s->insn_config  = usbduxsigma_dio_insn_config;
1543
1544        if (devpriv->high_speed) {
1545                /* Timer / pwm subdevice */
1546                s = &dev->subdevices[3];
1547                s->type         = COMEDI_SUBD_PWM;
1548                s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1549                s->n_chan       = 8;
1550                s->maxdata      = devpriv->pwm_buf_sz;
1551                s->insn_write   = usbduxsigma_pwm_write;
1552                s->insn_config  = usbduxsigma_pwm_config;
1553
1554                usbduxsigma_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1555        }
1556
1557        offset = usbduxsigma_getstatusinfo(dev, 0);
1558        if (offset < 0) {
1559                dev_err(dev->class_dev,
1560                        "Communication to USBDUXSIGMA failed! Check firmware and cabling.\n");
1561                return offset;
1562        }
1563
1564        dev_info(dev->class_dev, "ADC_zero = %x\n", offset);
1565
1566        return 0;
1567}
1568
1569static void usbduxsigma_detach(struct comedi_device *dev)
1570{
1571        struct usb_interface *intf = comedi_to_usb_interface(dev);
1572        struct usbduxsigma_private *devpriv = dev->private;
1573
1574        usb_set_intfdata(intf, NULL);
1575
1576        if (!devpriv)
1577                return;
1578
1579        mutex_lock(&devpriv->mut);
1580
1581        /* force unlink all urbs */
1582        usbduxsigma_ai_stop(dev, 1);
1583        usbduxsigma_ao_stop(dev, 1);
1584        usbduxsigma_pwm_stop(dev, 1);
1585
1586        usbduxsigma_free_usb_buffers(dev);
1587
1588        mutex_unlock(&devpriv->mut);
1589}
1590
1591static struct comedi_driver usbduxsigma_driver = {
1592        .driver_name    = "usbduxsigma",
1593        .module         = THIS_MODULE,
1594        .auto_attach    = usbduxsigma_auto_attach,
1595        .detach         = usbduxsigma_detach,
1596};
1597
1598static int usbduxsigma_usb_probe(struct usb_interface *intf,
1599                                 const struct usb_device_id *id)
1600{
1601        return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0);
1602}
1603
1604static const struct usb_device_id usbduxsigma_usb_table[] = {
1605        { USB_DEVICE(0x13d8, 0x0020) },
1606        { USB_DEVICE(0x13d8, 0x0021) },
1607        { USB_DEVICE(0x13d8, 0x0022) },
1608        { }
1609};
1610MODULE_DEVICE_TABLE(usb, usbduxsigma_usb_table);
1611
1612static struct usb_driver usbduxsigma_usb_driver = {
1613        .name           = "usbduxsigma",
1614        .probe          = usbduxsigma_usb_probe,
1615        .disconnect     = comedi_usb_auto_unconfig,
1616        .id_table       = usbduxsigma_usb_table,
1617};
1618module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver);
1619
1620MODULE_AUTHOR("Bernd Porr, mail@berndporr.me.uk");
1621MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- mail@berndporr.me.uk");
1622MODULE_LICENSE("GPL");
1623MODULE_FIRMWARE(FIRMWARE);
1624