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