linux/drivers/staging/comedi/drivers/dt9812.c
<<
>>
Prefs
   1/*
   2 * comedi/drivers/dt9812.c
   3 *   COMEDI driver for DataTranslation DT9812 USB module
   4 *
   5 * Copyright (C) 2005 Anders Blomdell <anders.blomdell@control.lth.se>
   6 *
   7 * COMEDI - Linux Control and Measurement Device Interface
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * (at your option) any later version.
  13
  14 *  This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 */
  19
  20/*
  21Driver: dt9812
  22Description: Data Translation DT9812 USB module
  23Author: anders.blomdell@control.lth.se (Anders Blomdell)
  24Status: in development
  25Devices: [Data Translation] DT9812 (dt9812)
  26Updated: Sun Nov 20 20:18:34 EST 2005
  27
  28This driver works, but bulk transfers not implemented. Might be a starting point
  29for someone else. I found out too late that USB has too high latencies (>1 ms)
  30for my needs.
  31*/
  32
  33/*
  34 * Nota Bene:
  35 *   1. All writes to command pipe has to be 32 bytes (ISP1181B SHRTP=0 ?)
  36 *   2. The DDK source (as of sep 2005) is in error regarding the
  37 *      input MUX bits (example code says P4, but firmware schematics
  38 *      says P1).
  39 */
  40
  41#include <linux/kernel.h>
  42#include <linux/module.h>
  43#include <linux/errno.h>
  44#include <linux/init.h>
  45#include <linux/uaccess.h>
  46#include <linux/usb.h>
  47
  48#include "../comedidev.h"
  49
  50#define DT9812_DIAGS_BOARD_INFO_ADDR    0xFBFF
  51#define DT9812_MAX_WRITE_CMD_PIPE_SIZE  32
  52#define DT9812_MAX_READ_CMD_PIPE_SIZE   32
  53
  54/* usb_bulk_msg() timout in milliseconds */
  55#define DT9812_USB_TIMEOUT              1000
  56
  57/*
  58 * See Silican Laboratories C8051F020/1/2/3 manual
  59 */
  60#define F020_SFR_P4                     0x84
  61#define F020_SFR_P1                     0x90
  62#define F020_SFR_P2                     0xa0
  63#define F020_SFR_P3                     0xb0
  64#define F020_SFR_AMX0CF                 0xba
  65#define F020_SFR_AMX0SL                 0xbb
  66#define F020_SFR_ADC0CF                 0xbc
  67#define F020_SFR_ADC0L                  0xbe
  68#define F020_SFR_ADC0H                  0xbf
  69#define F020_SFR_DAC0L                  0xd2
  70#define F020_SFR_DAC0H                  0xd3
  71#define F020_SFR_DAC0CN                 0xd4
  72#define F020_SFR_DAC1L                  0xd5
  73#define F020_SFR_DAC1H                  0xd6
  74#define F020_SFR_DAC1CN                 0xd7
  75#define F020_SFR_ADC0CN                 0xe8
  76
  77#define F020_MASK_ADC0CF_AMP0GN0        0x01
  78#define F020_MASK_ADC0CF_AMP0GN1        0x02
  79#define F020_MASK_ADC0CF_AMP0GN2        0x04
  80
  81#define F020_MASK_ADC0CN_AD0EN          0x80
  82#define F020_MASK_ADC0CN_AD0INT         0x20
  83#define F020_MASK_ADC0CN_AD0BUSY        0x10
  84
  85#define F020_MASK_DACxCN_DACxEN         0x80
  86
  87enum {
  88                                        /* A/D  D/A  DI  DO  CT */
  89        DT9812_DEVID_DT9812_10,         /*  8    2   8   8   1  +/- 10V */
  90        DT9812_DEVID_DT9812_2PT5,       /*  8    2   8   8   1  0-2.44V */
  91};
  92
  93enum dt9812_gain {
  94        DT9812_GAIN_0PT25 = 1,
  95        DT9812_GAIN_0PT5 = 2,
  96        DT9812_GAIN_1 = 4,
  97        DT9812_GAIN_2 = 8,
  98        DT9812_GAIN_4 = 16,
  99        DT9812_GAIN_8 = 32,
 100        DT9812_GAIN_16 = 64,
 101};
 102
 103enum {
 104        DT9812_LEAST_USB_FIRMWARE_CMD_CODE = 0,
 105        /* Write Flash memory */
 106        DT9812_W_FLASH_DATA = 0,
 107        /* Read Flash memory misc config info */
 108        DT9812_R_FLASH_DATA = 1,
 109
 110        /*
 111         * Register read/write commands for processor
 112         */
 113
 114        /* Read a single byte of USB memory */
 115        DT9812_R_SINGLE_BYTE_REG = 2,
 116        /* Write a single byte of USB memory */
 117        DT9812_W_SINGLE_BYTE_REG = 3,
 118        /* Multiple Reads of USB memory */
 119        DT9812_R_MULTI_BYTE_REG = 4,
 120        /* Multiple Writes of USB memory */
 121        DT9812_W_MULTI_BYTE_REG = 5,
 122        /* Read, (AND) with mask, OR value, then write (single) */
 123        DT9812_RMW_SINGLE_BYTE_REG = 6,
 124        /* Read, (AND) with mask, OR value, then write (multiple) */
 125        DT9812_RMW_MULTI_BYTE_REG = 7,
 126
 127        /*
 128         * Register read/write commands for SMBus
 129         */
 130
 131        /* Read a single byte of SMBus */
 132        DT9812_R_SINGLE_BYTE_SMBUS = 8,
 133        /* Write a single byte of SMBus */
 134        DT9812_W_SINGLE_BYTE_SMBUS = 9,
 135        /* Multiple Reads of SMBus */
 136        DT9812_R_MULTI_BYTE_SMBUS = 10,
 137        /* Multiple Writes of SMBus */
 138        DT9812_W_MULTI_BYTE_SMBUS = 11,
 139
 140        /*
 141         * Register read/write commands for a device
 142         */
 143
 144        /* Read a single byte of a device */
 145        DT9812_R_SINGLE_BYTE_DEV = 12,
 146        /* Write a single byte of a device */
 147        DT9812_W_SINGLE_BYTE_DEV = 13,
 148        /* Multiple Reads of a device */
 149        DT9812_R_MULTI_BYTE_DEV = 14,
 150        /* Multiple Writes of a device */
 151        DT9812_W_MULTI_BYTE_DEV = 15,
 152
 153        /* Not sure if we'll need this */
 154        DT9812_W_DAC_THRESHOLD = 16,
 155
 156        /* Set interrupt on change mask */
 157        DT9812_W_INT_ON_CHANGE_MASK = 17,
 158
 159        /* Write (or Clear) the CGL for the ADC */
 160        DT9812_W_CGL = 18,
 161        /* Multiple Reads of USB memory */
 162        DT9812_R_MULTI_BYTE_USBMEM = 19,
 163        /* Multiple Writes to USB memory */
 164        DT9812_W_MULTI_BYTE_USBMEM = 20,
 165
 166        /* Issue a start command to a given subsystem */
 167        DT9812_START_SUBSYSTEM = 21,
 168        /* Issue a stop command to a given subsystem */
 169        DT9812_STOP_SUBSYSTEM = 22,
 170
 171        /* calibrate the board using CAL_POT_CMD */
 172        DT9812_CALIBRATE_POT = 23,
 173        /* set the DAC FIFO size */
 174        DT9812_W_DAC_FIFO_SIZE = 24,
 175        /* Write or Clear the CGL for the DAC */
 176        DT9812_W_CGL_DAC = 25,
 177        /* Read a single value from a subsystem */
 178        DT9812_R_SINGLE_VALUE_CMD = 26,
 179        /* Write a single value to a subsystem */
 180        DT9812_W_SINGLE_VALUE_CMD = 27,
 181        /* Valid DT9812_USB_FIRMWARE_CMD_CODE's will be less than this number */
 182        DT9812_MAX_USB_FIRMWARE_CMD_CODE,
 183};
 184
 185struct dt9812_flash_data {
 186        __le16 numbytes;
 187        __le16 address;
 188};
 189
 190#define DT9812_MAX_NUM_MULTI_BYTE_RDS  \
 191        ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / sizeof(u8))
 192
 193struct dt9812_read_multi {
 194        u8 count;
 195        u8 address[DT9812_MAX_NUM_MULTI_BYTE_RDS];
 196};
 197
 198struct dt9812_write_byte {
 199        u8 address;
 200        u8 value;
 201};
 202
 203#define DT9812_MAX_NUM_MULTI_BYTE_WRTS  \
 204        ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \
 205         sizeof(struct dt9812_write_byte))
 206
 207struct dt9812_write_multi {
 208        u8 count;
 209        struct dt9812_write_byte write[DT9812_MAX_NUM_MULTI_BYTE_WRTS];
 210};
 211
 212struct dt9812_rmw_byte {
 213        u8 address;
 214        u8 and_mask;
 215        u8 or_value;
 216};
 217
 218#define DT9812_MAX_NUM_MULTI_BYTE_RMWS  \
 219        ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \
 220         sizeof(struct dt9812_rmw_byte))
 221
 222struct dt9812_rmw_multi {
 223        u8 count;
 224        struct dt9812_rmw_byte rmw[DT9812_MAX_NUM_MULTI_BYTE_RMWS];
 225};
 226
 227struct dt9812_usb_cmd {
 228        __le32 cmd;
 229        union {
 230                struct dt9812_flash_data flash_data_info;
 231                struct dt9812_read_multi read_multi_info;
 232                struct dt9812_write_multi write_multi_info;
 233                struct dt9812_rmw_multi rmw_multi_info;
 234        } u;
 235};
 236
 237struct dt9812_private {
 238        struct semaphore sem;
 239        struct {
 240                __u8 addr;
 241                size_t size;
 242        } cmd_wr, cmd_rd;
 243        u16 device;
 244        u16 ao_shadow[2];
 245};
 246
 247static int dt9812_read_info(struct comedi_device *dev,
 248                            int offset, void *buf, size_t buf_size)
 249{
 250        struct usb_device *usb = comedi_to_usb_dev(dev);
 251        struct dt9812_private *devpriv = dev->private;
 252        struct dt9812_usb_cmd cmd;
 253        int count, ret;
 254
 255        cmd.cmd = cpu_to_le32(DT9812_R_FLASH_DATA);
 256        cmd.u.flash_data_info.address =
 257            cpu_to_le16(DT9812_DIAGS_BOARD_INFO_ADDR + offset);
 258        cmd.u.flash_data_info.numbytes = cpu_to_le16(buf_size);
 259
 260        /* DT9812 only responds to 32 byte writes!! */
 261        ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
 262                           &cmd, 32, &count, DT9812_USB_TIMEOUT);
 263        if (ret)
 264                return ret;
 265
 266        return usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr),
 267                            buf, buf_size, &count, DT9812_USB_TIMEOUT);
 268}
 269
 270static int dt9812_read_multiple_registers(struct comedi_device *dev,
 271                                          int reg_count, u8 *address,
 272                                          u8 *value)
 273{
 274        struct usb_device *usb = comedi_to_usb_dev(dev);
 275        struct dt9812_private *devpriv = dev->private;
 276        struct dt9812_usb_cmd cmd;
 277        int i, count, ret;
 278
 279        cmd.cmd = cpu_to_le32(DT9812_R_MULTI_BYTE_REG);
 280        cmd.u.read_multi_info.count = reg_count;
 281        for (i = 0; i < reg_count; i++)
 282                cmd.u.read_multi_info.address[i] = address[i];
 283
 284        /* DT9812 only responds to 32 byte writes!! */
 285        ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
 286                           &cmd, 32, &count, DT9812_USB_TIMEOUT);
 287        if (ret)
 288                return ret;
 289
 290        return usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr),
 291                            value, reg_count, &count, DT9812_USB_TIMEOUT);
 292}
 293
 294static int dt9812_write_multiple_registers(struct comedi_device *dev,
 295                                           int reg_count, u8 *address,
 296                                           u8 *value)
 297{
 298        struct usb_device *usb = comedi_to_usb_dev(dev);
 299        struct dt9812_private *devpriv = dev->private;
 300        struct dt9812_usb_cmd cmd;
 301        int i, count;
 302
 303        cmd.cmd = cpu_to_le32(DT9812_W_MULTI_BYTE_REG);
 304        cmd.u.read_multi_info.count = reg_count;
 305        for (i = 0; i < reg_count; i++) {
 306                cmd.u.write_multi_info.write[i].address = address[i];
 307                cmd.u.write_multi_info.write[i].value = value[i];
 308        }
 309
 310        /* DT9812 only responds to 32 byte writes!! */
 311        return usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
 312                            &cmd, 32, &count, DT9812_USB_TIMEOUT);
 313}
 314
 315static int dt9812_rmw_multiple_registers(struct comedi_device *dev,
 316                                         int reg_count,
 317                                         struct dt9812_rmw_byte *rmw)
 318{
 319        struct usb_device *usb = comedi_to_usb_dev(dev);
 320        struct dt9812_private *devpriv = dev->private;
 321        struct dt9812_usb_cmd cmd;
 322        int i, count;
 323
 324        cmd.cmd = cpu_to_le32(DT9812_RMW_MULTI_BYTE_REG);
 325        cmd.u.rmw_multi_info.count = reg_count;
 326        for (i = 0; i < reg_count; i++)
 327                cmd.u.rmw_multi_info.rmw[i] = rmw[i];
 328
 329        /* DT9812 only responds to 32 byte writes!! */
 330        return usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
 331                            &cmd, 32, &count, DT9812_USB_TIMEOUT);
 332}
 333
 334static int dt9812_digital_in(struct comedi_device *dev, u8 *bits)
 335{
 336        struct dt9812_private *devpriv = dev->private;
 337        u8 reg[2] = { F020_SFR_P3, F020_SFR_P1 };
 338        u8 value[2];
 339        int ret;
 340
 341        down(&devpriv->sem);
 342        ret = dt9812_read_multiple_registers(dev, 2, reg, value);
 343        if (ret == 0) {
 344                /*
 345                 * bits 0-6 in F020_SFR_P3 are bits 0-6 in the digital
 346                 * input port bit 3 in F020_SFR_P1 is bit 7 in the
 347                 * digital input port
 348                 */
 349                *bits = (value[0] & 0x7f) | ((value[1] & 0x08) << 4);
 350        }
 351        up(&devpriv->sem);
 352
 353        return ret;
 354}
 355
 356static int dt9812_digital_out(struct comedi_device *dev, u8 bits)
 357{
 358        struct dt9812_private *devpriv = dev->private;
 359        u8 reg[1] = { F020_SFR_P2 };
 360        u8 value[1] = { bits };
 361        int ret;
 362
 363        down(&devpriv->sem);
 364        ret = dt9812_write_multiple_registers(dev, 1, reg, value);
 365        up(&devpriv->sem);
 366
 367        return ret;
 368}
 369
 370static void dt9812_configure_mux(struct comedi_device *dev,
 371                                 struct dt9812_rmw_byte *rmw, int channel)
 372{
 373        struct dt9812_private *devpriv = dev->private;
 374
 375        if (devpriv->device == DT9812_DEVID_DT9812_10) {
 376                /* In the DT9812/10V MUX is selected by P1.5-7 */
 377                rmw->address = F020_SFR_P1;
 378                rmw->and_mask = 0xe0;
 379                rmw->or_value = channel << 5;
 380        } else {
 381                /* In the DT9812/2.5V, internal mux is selected by bits 0:2 */
 382                rmw->address = F020_SFR_AMX0SL;
 383                rmw->and_mask = 0xff;
 384                rmw->or_value = channel & 0x07;
 385        }
 386}
 387
 388static void dt9812_configure_gain(struct comedi_device *dev,
 389                                  struct dt9812_rmw_byte *rmw,
 390                                  enum dt9812_gain gain)
 391{
 392        struct dt9812_private *devpriv = dev->private;
 393
 394        /* In the DT9812/10V, there is an external gain of 0.5 */
 395        if (devpriv->device == DT9812_DEVID_DT9812_10)
 396                gain <<= 1;
 397
 398        rmw->address = F020_SFR_ADC0CF;
 399        rmw->and_mask = F020_MASK_ADC0CF_AMP0GN2 |
 400                        F020_MASK_ADC0CF_AMP0GN1 |
 401                        F020_MASK_ADC0CF_AMP0GN0;
 402
 403        switch (gain) {
 404                /*
 405                 * 000 -> Gain =  1
 406                 * 001 -> Gain =  2
 407                 * 010 -> Gain =  4
 408                 * 011 -> Gain =  8
 409                 * 10x -> Gain = 16
 410                 * 11x -> Gain =  0.5
 411                 */
 412        case DT9812_GAIN_0PT5:
 413                rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 |
 414                                F020_MASK_ADC0CF_AMP0GN1;
 415                break;
 416        default:
 417                /* this should never happen, just use a gain of 1 */
 418        case DT9812_GAIN_1:
 419                rmw->or_value = 0x00;
 420                break;
 421        case DT9812_GAIN_2:
 422                rmw->or_value = F020_MASK_ADC0CF_AMP0GN0;
 423                break;
 424        case DT9812_GAIN_4:
 425                rmw->or_value = F020_MASK_ADC0CF_AMP0GN1;
 426                break;
 427        case DT9812_GAIN_8:
 428                rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 |
 429                                F020_MASK_ADC0CF_AMP0GN0;
 430                break;
 431        case DT9812_GAIN_16:
 432                rmw->or_value = F020_MASK_ADC0CF_AMP0GN2;
 433                break;
 434        }
 435}
 436
 437static int dt9812_analog_in(struct comedi_device *dev,
 438                            int channel, u16 *value, enum dt9812_gain gain)
 439{
 440        struct dt9812_private *devpriv = dev->private;
 441        struct dt9812_rmw_byte rmw[3];
 442        u8 reg[3] = {
 443                F020_SFR_ADC0CN,
 444                F020_SFR_ADC0H,
 445                F020_SFR_ADC0L
 446        };
 447        u8 val[3];
 448        int ret;
 449
 450        down(&devpriv->sem);
 451
 452        /* 1 select the gain */
 453        dt9812_configure_gain(dev, &rmw[0], gain);
 454
 455        /* 2 set the MUX to select the channel */
 456        dt9812_configure_mux(dev, &rmw[1], channel);
 457
 458        /* 3 start conversion */
 459        rmw[2].address = F020_SFR_ADC0CN;
 460        rmw[2].and_mask = 0xff;
 461        rmw[2].or_value = F020_MASK_ADC0CN_AD0EN | F020_MASK_ADC0CN_AD0BUSY;
 462
 463        ret = dt9812_rmw_multiple_registers(dev, 3, rmw);
 464        if (ret)
 465                goto exit;
 466
 467        /* read the status and ADC */
 468        ret = dt9812_read_multiple_registers(dev, 3, reg, val);
 469        if (ret)
 470                goto exit;
 471
 472        /*
 473         * An ADC conversion takes 16 SAR clocks cycles, i.e. about 9us.
 474         * Therefore, between the instant that AD0BUSY was set via
 475         * dt9812_rmw_multiple_registers and the read of AD0BUSY via
 476         * dt9812_read_multiple_registers, the conversion should be complete
 477         * since these two operations require two USB transactions each taking
 478         * at least a millisecond to complete.  However, lets make sure that
 479         * conversion is finished.
 480         */
 481        if ((val[0] & (F020_MASK_ADC0CN_AD0INT | F020_MASK_ADC0CN_AD0BUSY)) ==
 482            F020_MASK_ADC0CN_AD0INT) {
 483                switch (devpriv->device) {
 484                case DT9812_DEVID_DT9812_10:
 485                        /*
 486                         * For DT9812-10V the personality module set the
 487                         * encoding to 2's complement. Hence, convert it before
 488                         * returning it
 489                         */
 490                        *value = ((val[1] << 8) | val[2]) + 0x800;
 491                        break;
 492                case DT9812_DEVID_DT9812_2PT5:
 493                        *value = (val[1] << 8) | val[2];
 494                        break;
 495                }
 496        }
 497
 498exit:
 499        up(&devpriv->sem);
 500
 501        return ret;
 502}
 503
 504static int dt9812_analog_out(struct comedi_device *dev, int channel, u16 value)
 505{
 506        struct dt9812_private *devpriv = dev->private;
 507        struct dt9812_rmw_byte rmw[3];
 508        int ret;
 509
 510        down(&devpriv->sem);
 511
 512        switch (channel) {
 513        case 0:
 514                /* 1. Set DAC mode */
 515                rmw[0].address = F020_SFR_DAC0CN;
 516                rmw[0].and_mask = 0xff;
 517                rmw[0].or_value = F020_MASK_DACxCN_DACxEN;
 518
 519                /* 2 load low byte of DAC value first */
 520                rmw[1].address = F020_SFR_DAC0L;
 521                rmw[1].and_mask = 0xff;
 522                rmw[1].or_value = value & 0xff;
 523
 524                /* 3 load high byte of DAC value next to latch the
 525                        12-bit value */
 526                rmw[2].address = F020_SFR_DAC0H;
 527                rmw[2].and_mask = 0xff;
 528                rmw[2].or_value = (value >> 8) & 0xf;
 529                break;
 530
 531        case 1:
 532                /* 1. Set DAC mode */
 533                rmw[0].address = F020_SFR_DAC1CN;
 534                rmw[0].and_mask = 0xff;
 535                rmw[0].or_value = F020_MASK_DACxCN_DACxEN;
 536
 537                /* 2 load low byte of DAC value first */
 538                rmw[1].address = F020_SFR_DAC1L;
 539                rmw[1].and_mask = 0xff;
 540                rmw[1].or_value = value & 0xff;
 541
 542                /* 3 load high byte of DAC value next to latch the
 543                        12-bit value */
 544                rmw[2].address = F020_SFR_DAC1H;
 545                rmw[2].and_mask = 0xff;
 546                rmw[2].or_value = (value >> 8) & 0xf;
 547                break;
 548        }
 549        ret = dt9812_rmw_multiple_registers(dev, 3, rmw);
 550        devpriv->ao_shadow[channel] = value;
 551
 552        up(&devpriv->sem);
 553
 554        return ret;
 555}
 556
 557static int dt9812_di_insn_bits(struct comedi_device *dev,
 558                               struct comedi_subdevice *s,
 559                               struct comedi_insn *insn,
 560                               unsigned int *data)
 561{
 562        u8 bits = 0;
 563        int ret;
 564
 565        ret = dt9812_digital_in(dev, &bits);
 566        if (ret)
 567                return ret;
 568
 569        data[1] = bits;
 570
 571        return insn->n;
 572}
 573
 574static int dt9812_do_insn_bits(struct comedi_device *dev,
 575                               struct comedi_subdevice *s,
 576                               struct comedi_insn *insn,
 577                               unsigned int *data)
 578{
 579        if (comedi_dio_update_state(s, data))
 580                dt9812_digital_out(dev, s->state);
 581
 582        data[1] = s->state;
 583
 584        return insn->n;
 585}
 586
 587static int dt9812_ai_insn_read(struct comedi_device *dev,
 588                               struct comedi_subdevice *s,
 589                               struct comedi_insn *insn,
 590                               unsigned int *data)
 591{
 592        unsigned int chan = CR_CHAN(insn->chanspec);
 593        u16 val = 0;
 594        int ret;
 595        int i;
 596
 597        for (i = 0; i < insn->n; i++) {
 598                ret = dt9812_analog_in(dev, chan, &val, DT9812_GAIN_1);
 599                if (ret)
 600                        return ret;
 601                data[i] = val;
 602        }
 603
 604        return insn->n;
 605}
 606
 607static int dt9812_ao_insn_read(struct comedi_device *dev,
 608                               struct comedi_subdevice *s,
 609                               struct comedi_insn *insn,
 610                               unsigned int *data)
 611{
 612        struct dt9812_private *devpriv = dev->private;
 613        unsigned int chan = CR_CHAN(insn->chanspec);
 614        int i;
 615
 616        down(&devpriv->sem);
 617        for (i = 0; i < insn->n; i++)
 618                data[i] = devpriv->ao_shadow[chan];
 619        up(&devpriv->sem);
 620
 621        return insn->n;
 622}
 623
 624static int dt9812_ao_insn_write(struct comedi_device *dev,
 625                                struct comedi_subdevice *s,
 626                                struct comedi_insn *insn,
 627                                unsigned int *data)
 628{
 629        unsigned int chan = CR_CHAN(insn->chanspec);
 630        int ret;
 631        int i;
 632
 633        for (i = 0; i < insn->n; i++) {
 634                ret = dt9812_analog_out(dev, chan, data[i]);
 635                if (ret)
 636                        return ret;
 637        }
 638
 639        return insn->n;
 640}
 641
 642static int dt9812_find_endpoints(struct comedi_device *dev)
 643{
 644        struct usb_interface *intf = comedi_to_usb_interface(dev);
 645        struct usb_host_interface *host = intf->cur_altsetting;
 646        struct dt9812_private *devpriv = dev->private;
 647        struct usb_endpoint_descriptor *ep;
 648        int i;
 649
 650        if (host->desc.bNumEndpoints != 5) {
 651                dev_err(dev->class_dev, "Wrong number of endpoints\n");
 652                return -ENODEV;
 653        }
 654
 655        for (i = 0; i < host->desc.bNumEndpoints; ++i) {
 656                int dir = -1;
 657                ep = &host->endpoint[i].desc;
 658                switch (i) {
 659                case 0:
 660                        /* unused message pipe */
 661                        dir = USB_DIR_IN;
 662                        break;
 663                case 1:
 664                        dir = USB_DIR_OUT;
 665                        devpriv->cmd_wr.addr = ep->bEndpointAddress;
 666                        devpriv->cmd_wr.size = le16_to_cpu(ep->wMaxPacketSize);
 667                        break;
 668                case 2:
 669                        dir = USB_DIR_IN;
 670                        devpriv->cmd_rd.addr = ep->bEndpointAddress;
 671                        devpriv->cmd_rd.size = le16_to_cpu(ep->wMaxPacketSize);
 672                        break;
 673                case 3:
 674                        /* unused write stream */
 675                        dir = USB_DIR_OUT;
 676                        break;
 677                case 4:
 678                        /* unused read stream */
 679                        dir = USB_DIR_IN;
 680                        break;
 681                }
 682                if ((ep->bEndpointAddress & USB_DIR_IN) != dir) {
 683                        dev_err(dev->class_dev,
 684                                "Endpoint has wrong direction\n");
 685                        return -ENODEV;
 686                }
 687        }
 688        return 0;
 689}
 690
 691static int dt9812_reset_device(struct comedi_device *dev)
 692{
 693        struct usb_device *usb = comedi_to_usb_dev(dev);
 694        struct dt9812_private *devpriv = dev->private;
 695        u32 serial;
 696        u16 vendor;
 697        u16 product;
 698        u8 tmp8;
 699        __le16 tmp16;
 700        __le32 tmp32;
 701        int ret;
 702        int i;
 703
 704        ret = dt9812_read_info(dev, 0, &tmp8, sizeof(tmp8));
 705        if (ret) {
 706                /*
 707                 * Seems like a configuration reset is necessary if driver is
 708                 * reloaded while device is attached
 709                 */
 710                usb_reset_configuration(usb);
 711                for (i = 0; i < 10; i++) {
 712                        ret = dt9812_read_info(dev, 1, &tmp8, sizeof(tmp8));
 713                        if (ret == 0)
 714                                break;
 715                }
 716                if (ret) {
 717                        dev_err(dev->class_dev,
 718                                "unable to reset configuration\n");
 719                        return ret;
 720                }
 721        }
 722
 723        ret = dt9812_read_info(dev, 1, &tmp16, sizeof(tmp16));
 724        if (ret) {
 725                dev_err(dev->class_dev, "failed to read vendor id\n");
 726                return ret;
 727        }
 728        vendor = le16_to_cpu(tmp16);
 729
 730        ret = dt9812_read_info(dev, 3, &tmp16, sizeof(tmp16));
 731        if (ret) {
 732                dev_err(dev->class_dev, "failed to read product id\n");
 733                return ret;
 734        }
 735        product = le16_to_cpu(tmp16);
 736
 737        ret = dt9812_read_info(dev, 5, &tmp16, sizeof(tmp16));
 738        if (ret) {
 739                dev_err(dev->class_dev, "failed to read device id\n");
 740                return ret;
 741        }
 742        devpriv->device = le16_to_cpu(tmp16);
 743
 744        ret = dt9812_read_info(dev, 7, &tmp32, sizeof(tmp32));
 745        if (ret) {
 746                dev_err(dev->class_dev, "failed to read serial number\n");
 747                return ret;
 748        }
 749        serial = le32_to_cpu(tmp32);
 750
 751        /* let the user know what node this device is now attached to */
 752        dev_info(dev->class_dev, "USB DT9812 (%4.4x.%4.4x.%4.4x) #0x%8.8x\n",
 753                 vendor, product, devpriv->device, serial);
 754
 755        if (devpriv->device != DT9812_DEVID_DT9812_10 &&
 756            devpriv->device != DT9812_DEVID_DT9812_2PT5) {
 757                dev_err(dev->class_dev, "Unsupported device!\n");
 758                return -EINVAL;
 759        }
 760
 761        return 0;
 762}
 763
 764static int dt9812_auto_attach(struct comedi_device *dev,
 765                              unsigned long context)
 766{
 767        struct usb_interface *intf = comedi_to_usb_interface(dev);
 768        struct dt9812_private *devpriv;
 769        struct comedi_subdevice *s;
 770        bool is_unipolar;
 771        int ret;
 772
 773        devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
 774        if (!devpriv)
 775                return -ENOMEM;
 776
 777        sema_init(&devpriv->sem, 1);
 778        usb_set_intfdata(intf, devpriv);
 779
 780        ret = dt9812_find_endpoints(dev);
 781        if (ret)
 782                return ret;
 783
 784        ret = dt9812_reset_device(dev);
 785        if (ret)
 786                return ret;
 787
 788        is_unipolar = (devpriv->device == DT9812_DEVID_DT9812_2PT5);
 789
 790        ret = comedi_alloc_subdevices(dev, 4);
 791        if (ret)
 792                return ret;
 793
 794        /* Digital Input subdevice */
 795        s = &dev->subdevices[0];
 796        s->type         = COMEDI_SUBD_DI;
 797        s->subdev_flags = SDF_READABLE;
 798        s->n_chan       = 8;
 799        s->maxdata      = 1;
 800        s->range_table  = &range_digital;
 801        s->insn_bits    = dt9812_di_insn_bits;
 802
 803        /* Digital Output subdevice */
 804        s = &dev->subdevices[1];
 805        s->type         = COMEDI_SUBD_DO;
 806        s->subdev_flags = SDF_WRITEABLE;
 807        s->n_chan       = 8;
 808        s->maxdata      = 1;
 809        s->range_table  = &range_digital;
 810        s->insn_bits    = dt9812_do_insn_bits;
 811
 812        /* Analog Input subdevice */
 813        s = &dev->subdevices[2];
 814        s->type         = COMEDI_SUBD_AI;
 815        s->subdev_flags = SDF_READABLE | SDF_GROUND;
 816        s->n_chan       = 8;
 817        s->maxdata      = 0x0fff;
 818        s->range_table  = is_unipolar ? &range_unipolar2_5 : &range_bipolar10;
 819        s->insn_read    = dt9812_ai_insn_read;
 820
 821        /* Analog Output subdevice */
 822        s = &dev->subdevices[3];
 823        s->type         = COMEDI_SUBD_AO;
 824        s->subdev_flags = SDF_WRITEABLE;
 825        s->n_chan       = 2;
 826        s->maxdata      = 0x0fff;
 827        s->range_table  = is_unipolar ? &range_unipolar2_5 : &range_bipolar10;
 828        s->insn_write   = dt9812_ao_insn_write;
 829        s->insn_read    = dt9812_ao_insn_read;
 830
 831        devpriv->ao_shadow[0] = is_unipolar ? 0x0000 : 0x0800;
 832        devpriv->ao_shadow[1] = is_unipolar ? 0x0000 : 0x0800;
 833
 834        return 0;
 835}
 836
 837static void dt9812_detach(struct comedi_device *dev)
 838{
 839        struct usb_interface *intf = comedi_to_usb_interface(dev);
 840        struct dt9812_private *devpriv = dev->private;
 841
 842        if (!devpriv)
 843                return;
 844
 845        down(&devpriv->sem);
 846
 847        usb_set_intfdata(intf, NULL);
 848
 849        up(&devpriv->sem);
 850}
 851
 852static struct comedi_driver dt9812_driver = {
 853        .driver_name    = "dt9812",
 854        .module         = THIS_MODULE,
 855        .auto_attach    = dt9812_auto_attach,
 856        .detach         = dt9812_detach,
 857};
 858
 859static int dt9812_usb_probe(struct usb_interface *intf,
 860                            const struct usb_device_id *id)
 861{
 862        return comedi_usb_auto_config(intf, &dt9812_driver, id->driver_info);
 863}
 864
 865static const struct usb_device_id dt9812_usb_table[] = {
 866        { USB_DEVICE(0x0867, 0x9812) },
 867        { }
 868};
 869MODULE_DEVICE_TABLE(usb, dt9812_usb_table);
 870
 871static struct usb_driver dt9812_usb_driver = {
 872        .name           = "dt9812",
 873        .id_table       = dt9812_usb_table,
 874        .probe          = dt9812_usb_probe,
 875        .disconnect     = comedi_usb_auto_unconfig,
 876};
 877module_comedi_usb_driver(dt9812_driver, dt9812_usb_driver);
 878
 879MODULE_AUTHOR("Anders Blomdell <anders.blomdell@control.lth.se>");
 880MODULE_DESCRIPTION("Comedi DT9812 driver");
 881MODULE_LICENSE("GPL");
 882