root/drivers/staging/comedi/drivers/dt9812.c

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

DEFINITIONS

This source file includes following definitions.
  1. dt9812_read_info
  2. dt9812_read_multiple_registers
  3. dt9812_write_multiple_registers
  4. dt9812_rmw_multiple_registers
  5. dt9812_digital_in
  6. dt9812_digital_out
  7. dt9812_configure_mux
  8. dt9812_configure_gain
  9. dt9812_analog_in
  10. dt9812_analog_out
  11. dt9812_di_insn_bits
  12. dt9812_do_insn_bits
  13. dt9812_ai_insn_read
  14. dt9812_ao_insn_read
  15. dt9812_ao_insn_write
  16. dt9812_find_endpoints
  17. dt9812_reset_device
  18. dt9812_auto_attach
  19. dt9812_detach
  20. dt9812_usb_probe

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

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