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/slab.h> 36 #include <linux/uaccess.h> 37 #include <linux/comedi/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 size_t tbuf_size; 242 int count, ret; 243 void *tbuf; 244 245 tbuf_size = max(sizeof(*cmd), buf_size); 246 247 tbuf = kzalloc(tbuf_size, GFP_KERNEL); 248 if (!tbuf) 249 return -ENOMEM; 250 251 cmd = tbuf; 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, sizeof(*cmd), &count, DT9812_USB_TIMEOUT); 261 if (ret) 262 goto out; 263 264 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr), 265 tbuf, buf_size, &count, DT9812_USB_TIMEOUT); 266 if (!ret) { 267 if (count == buf_size) 268 memcpy(buf, tbuf, buf_size); 269 else 270 ret = -EREMOTEIO; 271 } 272 out: 273 kfree(tbuf); 274 275 return ret; 276 } 277 278 static int dt9812_read_multiple_registers(struct comedi_device *dev, 279 int reg_count, u8 *address, 280 u8 *value) 281 { 282 struct usb_device *usb = comedi_to_usb_dev(dev); 283 struct dt9812_private *devpriv = dev->private; 284 struct dt9812_usb_cmd *cmd; 285 int i, count, ret; 286 size_t buf_size; 287 void *buf; 288 289 buf_size = max_t(size_t, sizeof(*cmd), reg_count); 290 291 buf = kzalloc(buf_size, GFP_KERNEL); 292 if (!buf) 293 return -ENOMEM; 294 295 cmd = buf; 296 297 cmd->cmd = cpu_to_le32(DT9812_R_MULTI_BYTE_REG); 298 cmd->u.read_multi_info.count = reg_count; 299 for (i = 0; i < reg_count; i++) 300 cmd->u.read_multi_info.address[i] = address[i]; 301 302 /* DT9812 only responds to 32 byte writes!! */ 303 ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), 304 cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT); 305 if (ret) 306 goto out; 307 308 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr), 309 buf, reg_count, &count, DT9812_USB_TIMEOUT); 310 if (!ret) { 311 if (count == reg_count) 312 memcpy(value, buf, reg_count); 313 else 314 ret = -EREMOTEIO; 315 } 316 out: 317 kfree(buf); 318 319 return ret; 320 } 321 322 static int dt9812_write_multiple_registers(struct comedi_device *dev, 323 int reg_count, u8 *address, 324 u8 *value) 325 { 326 struct usb_device *usb = comedi_to_usb_dev(dev); 327 struct dt9812_private *devpriv = dev->private; 328 struct dt9812_usb_cmd *cmd; 329 int i, count; 330 int ret; 331 332 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 333 if (!cmd) 334 return -ENOMEM; 335 336 cmd->cmd = cpu_to_le32(DT9812_W_MULTI_BYTE_REG); 337 cmd->u.read_multi_info.count = reg_count; 338 for (i = 0; i < reg_count; i++) { 339 cmd->u.write_multi_info.write[i].address = address[i]; 340 cmd->u.write_multi_info.write[i].value = value[i]; 341 } 342 343 /* DT9812 only responds to 32 byte writes!! */ 344 ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), 345 cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT); 346 kfree(cmd); 347 348 return ret; 349 } 350 351 static int dt9812_rmw_multiple_registers(struct comedi_device *dev, 352 int reg_count, 353 struct dt9812_rmw_byte *rmw) 354 { 355 struct usb_device *usb = comedi_to_usb_dev(dev); 356 struct dt9812_private *devpriv = dev->private; 357 struct dt9812_usb_cmd *cmd; 358 int i, count; 359 int ret; 360 361 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 362 if (!cmd) 363 return -ENOMEM; 364 365 cmd->cmd = cpu_to_le32(DT9812_RMW_MULTI_BYTE_REG); 366 cmd->u.rmw_multi_info.count = reg_count; 367 for (i = 0; i < reg_count; i++) 368 cmd->u.rmw_multi_info.rmw[i] = rmw[i]; 369 370 /* DT9812 only responds to 32 byte writes!! */ 371 ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), 372 cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT); 373 kfree(cmd); 374 375 return ret; 376 } 377 378 static int dt9812_digital_in(struct comedi_device *dev, u8 *bits) 379 { 380 struct dt9812_private *devpriv = dev->private; 381 u8 reg[2] = { F020_SFR_P3, F020_SFR_P1 }; 382 u8 value[2]; 383 int ret; 384 385 mutex_lock(&devpriv->mut); 386 ret = dt9812_read_multiple_registers(dev, 2, reg, value); 387 if (ret == 0) { 388 /* 389 * bits 0-6 in F020_SFR_P3 are bits 0-6 in the digital 390 * input port bit 3 in F020_SFR_P1 is bit 7 in the 391 * digital input port 392 */ 393 *bits = (value[0] & 0x7f) | ((value[1] & 0x08) << 4); 394 } 395 mutex_unlock(&devpriv->mut); 396 397 return ret; 398 } 399 400 static int dt9812_digital_out(struct comedi_device *dev, u8 bits) 401 { 402 struct dt9812_private *devpriv = dev->private; 403 u8 reg[1] = { F020_SFR_P2 }; 404 u8 value[1] = { bits }; 405 int ret; 406 407 mutex_lock(&devpriv->mut); 408 ret = dt9812_write_multiple_registers(dev, 1, reg, value); 409 mutex_unlock(&devpriv->mut); 410 411 return ret; 412 } 413 414 static void dt9812_configure_mux(struct comedi_device *dev, 415 struct dt9812_rmw_byte *rmw, int channel) 416 { 417 struct dt9812_private *devpriv = dev->private; 418 419 if (devpriv->device == DT9812_DEVID_DT9812_10) { 420 /* In the DT9812/10V MUX is selected by P1.5-7 */ 421 rmw->address = F020_SFR_P1; 422 rmw->and_mask = 0xe0; 423 rmw->or_value = channel << 5; 424 } else { 425 /* In the DT9812/2.5V, internal mux is selected by bits 0:2 */ 426 rmw->address = F020_SFR_AMX0SL; 427 rmw->and_mask = 0xff; 428 rmw->or_value = channel & 0x07; 429 } 430 } 431 432 static void dt9812_configure_gain(struct comedi_device *dev, 433 struct dt9812_rmw_byte *rmw, 434 enum dt9812_gain gain) 435 { 436 struct dt9812_private *devpriv = dev->private; 437 438 /* In the DT9812/10V, there is an external gain of 0.5 */ 439 if (devpriv->device == DT9812_DEVID_DT9812_10) 440 gain <<= 1; 441 442 rmw->address = F020_SFR_ADC0CF; 443 rmw->and_mask = F020_MASK_ADC0CF_AMP0GN2 | 444 F020_MASK_ADC0CF_AMP0GN1 | 445 F020_MASK_ADC0CF_AMP0GN0; 446 447 switch (gain) { 448 /* 449 * 000 -> Gain = 1 450 * 001 -> Gain = 2 451 * 010 -> Gain = 4 452 * 011 -> Gain = 8 453 * 10x -> Gain = 16 454 * 11x -> Gain = 0.5 455 */ 456 case DT9812_GAIN_0PT5: 457 rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 | 458 F020_MASK_ADC0CF_AMP0GN1; 459 break; 460 default: 461 /* this should never happen, just use a gain of 1 */ 462 case DT9812_GAIN_1: 463 rmw->or_value = 0x00; 464 break; 465 case DT9812_GAIN_2: 466 rmw->or_value = F020_MASK_ADC0CF_AMP0GN0; 467 break; 468 case DT9812_GAIN_4: 469 rmw->or_value = F020_MASK_ADC0CF_AMP0GN1; 470 break; 471 case DT9812_GAIN_8: 472 rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 | 473 F020_MASK_ADC0CF_AMP0GN0; 474 break; 475 case DT9812_GAIN_16: 476 rmw->or_value = F020_MASK_ADC0CF_AMP0GN2; 477 break; 478 } 479 } 480 481 static int dt9812_analog_in(struct comedi_device *dev, 482 int channel, u16 *value, enum dt9812_gain gain) 483 { 484 struct dt9812_private *devpriv = dev->private; 485 struct dt9812_rmw_byte rmw[3]; 486 u8 reg[3] = { 487 F020_SFR_ADC0CN, 488 F020_SFR_ADC0H, 489 F020_SFR_ADC0L 490 }; 491 u8 val[3]; 492 int ret; 493 494 mutex_lock(&devpriv->mut); 495 496 /* 1 select the gain */ 497 dt9812_configure_gain(dev, &rmw[0], gain); 498 499 /* 2 set the MUX to select the channel */ 500 dt9812_configure_mux(dev, &rmw[1], channel); 501 502 /* 3 start conversion */ 503 rmw[2].address = F020_SFR_ADC0CN; 504 rmw[2].and_mask = 0xff; 505 rmw[2].or_value = F020_MASK_ADC0CN_AD0EN | F020_MASK_ADC0CN_AD0BUSY; 506 507 ret = dt9812_rmw_multiple_registers(dev, 3, rmw); 508 if (ret) 509 goto exit; 510 511 /* read the status and ADC */ 512 ret = dt9812_read_multiple_registers(dev, 3, reg, val); 513 if (ret) 514 goto exit; 515 516 /* 517 * An ADC conversion takes 16 SAR clocks cycles, i.e. about 9us. 518 * Therefore, between the instant that AD0BUSY was set via 519 * dt9812_rmw_multiple_registers and the read of AD0BUSY via 520 * dt9812_read_multiple_registers, the conversion should be complete 521 * since these two operations require two USB transactions each taking 522 * at least a millisecond to complete. However, lets make sure that 523 * conversion is finished. 524 */ 525 if ((val[0] & (F020_MASK_ADC0CN_AD0INT | F020_MASK_ADC0CN_AD0BUSY)) == 526 F020_MASK_ADC0CN_AD0INT) { 527 switch (devpriv->device) { 528 case DT9812_DEVID_DT9812_10: 529 /* 530 * For DT9812-10V the personality module set the 531 * encoding to 2's complement. Hence, convert it before 532 * returning it 533 */ 534 *value = ((val[1] << 8) | val[2]) + 0x800; 535 break; 536 case DT9812_DEVID_DT9812_2PT5: 537 *value = (val[1] << 8) | val[2]; 538 break; 539 } 540 } 541 542 exit: 543 mutex_unlock(&devpriv->mut); 544 545 return ret; 546 } 547 548 static int dt9812_analog_out(struct comedi_device *dev, int channel, u16 value) 549 { 550 struct dt9812_private *devpriv = dev->private; 551 struct dt9812_rmw_byte rmw[3]; 552 int ret; 553 554 mutex_lock(&devpriv->mut); 555 556 switch (channel) { 557 case 0: 558 /* 1. Set DAC mode */ 559 rmw[0].address = F020_SFR_DAC0CN; 560 rmw[0].and_mask = 0xff; 561 rmw[0].or_value = F020_MASK_DACXCN_DACXEN; 562 563 /* 2. load lsb of DAC value first */ 564 rmw[1].address = F020_SFR_DAC0L; 565 rmw[1].and_mask = 0xff; 566 rmw[1].or_value = value & 0xff; 567 568 /* 3. load msb of DAC value next to latch the 12-bit value */ 569 rmw[2].address = F020_SFR_DAC0H; 570 rmw[2].and_mask = 0xff; 571 rmw[2].or_value = (value >> 8) & 0xf; 572 break; 573 574 case 1: 575 /* 1. Set DAC mode */ 576 rmw[0].address = F020_SFR_DAC1CN; 577 rmw[0].and_mask = 0xff; 578 rmw[0].or_value = F020_MASK_DACXCN_DACXEN; 579 580 /* 2. load lsb of DAC value first */ 581 rmw[1].address = F020_SFR_DAC1L; 582 rmw[1].and_mask = 0xff; 583 rmw[1].or_value = value & 0xff; 584 585 /* 3. load msb of DAC value next to latch the 12-bit value */ 586 rmw[2].address = F020_SFR_DAC1H; 587 rmw[2].and_mask = 0xff; 588 rmw[2].or_value = (value >> 8) & 0xf; 589 break; 590 } 591 ret = dt9812_rmw_multiple_registers(dev, 3, rmw); 592 593 mutex_unlock(&devpriv->mut); 594 595 return ret; 596 } 597 598 static int dt9812_di_insn_bits(struct comedi_device *dev, 599 struct comedi_subdevice *s, 600 struct comedi_insn *insn, 601 unsigned int *data) 602 { 603 u8 bits = 0; 604 int ret; 605 606 ret = dt9812_digital_in(dev, &bits); 607 if (ret) 608 return ret; 609 610 data[1] = bits; 611 612 return insn->n; 613 } 614 615 static int dt9812_do_insn_bits(struct comedi_device *dev, 616 struct comedi_subdevice *s, 617 struct comedi_insn *insn, 618 unsigned int *data) 619 { 620 if (comedi_dio_update_state(s, data)) 621 dt9812_digital_out(dev, s->state); 622 623 data[1] = s->state; 624 625 return insn->n; 626 } 627 628 static int dt9812_ai_insn_read(struct comedi_device *dev, 629 struct comedi_subdevice *s, 630 struct comedi_insn *insn, 631 unsigned int *data) 632 { 633 unsigned int chan = CR_CHAN(insn->chanspec); 634 u16 val = 0; 635 int ret; 636 int i; 637 638 for (i = 0; i < insn->n; i++) { 639 ret = dt9812_analog_in(dev, chan, &val, DT9812_GAIN_1); 640 if (ret) 641 return ret; 642 data[i] = val; 643 } 644 645 return insn->n; 646 } 647 648 static int dt9812_ao_insn_read(struct comedi_device *dev, 649 struct comedi_subdevice *s, 650 struct comedi_insn *insn, 651 unsigned int *data) 652 { 653 struct dt9812_private *devpriv = dev->private; 654 int ret; 655 656 mutex_lock(&devpriv->mut); 657 ret = comedi_readback_insn_read(dev, s, insn, data); 658 mutex_unlock(&devpriv->mut); 659 660 return ret; 661 } 662 663 static int dt9812_ao_insn_write(struct comedi_device *dev, 664 struct comedi_subdevice *s, 665 struct comedi_insn *insn, 666 unsigned int *data) 667 { 668 unsigned int chan = CR_CHAN(insn->chanspec); 669 int i; 670 671 for (i = 0; i < insn->n; i++) { 672 unsigned int val = data[i]; 673 int ret; 674 675 ret = dt9812_analog_out(dev, chan, val); 676 if (ret) 677 return ret; 678 679 s->readback[chan] = val; 680 } 681 682 return insn->n; 683 } 684 685 static int dt9812_find_endpoints(struct comedi_device *dev) 686 { 687 struct usb_interface *intf = comedi_to_usb_interface(dev); 688 struct usb_host_interface *host = intf->cur_altsetting; 689 struct dt9812_private *devpriv = dev->private; 690 struct usb_endpoint_descriptor *ep; 691 int i; 692 693 if (host->desc.bNumEndpoints != 5) { 694 dev_err(dev->class_dev, "Wrong number of endpoints\n"); 695 return -ENODEV; 696 } 697 698 for (i = 0; i < host->desc.bNumEndpoints; ++i) { 699 int dir = -1; 700 701 ep = &host->endpoint[i].desc; 702 switch (i) { 703 case 0: 704 /* unused message pipe */ 705 dir = USB_DIR_IN; 706 break; 707 case 1: 708 dir = USB_DIR_OUT; 709 devpriv->cmd_wr.addr = ep->bEndpointAddress; 710 devpriv->cmd_wr.size = usb_endpoint_maxp(ep); 711 break; 712 case 2: 713 dir = USB_DIR_IN; 714 devpriv->cmd_rd.addr = ep->bEndpointAddress; 715 devpriv->cmd_rd.size = usb_endpoint_maxp(ep); 716 break; 717 case 3: 718 /* unused write stream */ 719 dir = USB_DIR_OUT; 720 break; 721 case 4: 722 /* unused read stream */ 723 dir = USB_DIR_IN; 724 break; 725 } 726 if ((ep->bEndpointAddress & USB_DIR_IN) != dir) { 727 dev_err(dev->class_dev, 728 "Endpoint has wrong direction\n"); 729 return -ENODEV; 730 } 731 } 732 return 0; 733 } 734 735 static int dt9812_reset_device(struct comedi_device *dev) 736 { 737 struct usb_device *usb = comedi_to_usb_dev(dev); 738 struct dt9812_private *devpriv = dev->private; 739 u32 serial; 740 u16 vendor; 741 u16 product; 742 u8 tmp8; 743 __le16 tmp16; 744 __le32 tmp32; 745 int ret; 746 int i; 747 748 ret = dt9812_read_info(dev, 0, &tmp8, sizeof(tmp8)); 749 if (ret) { 750 /* 751 * Seems like a configuration reset is necessary if driver is 752 * reloaded while device is attached 753 */ 754 usb_reset_configuration(usb); 755 for (i = 0; i < 10; i++) { 756 ret = dt9812_read_info(dev, 1, &tmp8, sizeof(tmp8)); 757 if (ret == 0) 758 break; 759 } 760 if (ret) { 761 dev_err(dev->class_dev, 762 "unable to reset configuration\n"); 763 return ret; 764 } 765 } 766 767 ret = dt9812_read_info(dev, 1, &tmp16, sizeof(tmp16)); 768 if (ret) { 769 dev_err(dev->class_dev, "failed to read vendor id\n"); 770 return ret; 771 } 772 vendor = le16_to_cpu(tmp16); 773 774 ret = dt9812_read_info(dev, 3, &tmp16, sizeof(tmp16)); 775 if (ret) { 776 dev_err(dev->class_dev, "failed to read product id\n"); 777 return ret; 778 } 779 product = le16_to_cpu(tmp16); 780 781 ret = dt9812_read_info(dev, 5, &tmp16, sizeof(tmp16)); 782 if (ret) { 783 dev_err(dev->class_dev, "failed to read device id\n"); 784 return ret; 785 } 786 devpriv->device = le16_to_cpu(tmp16); 787 788 ret = dt9812_read_info(dev, 7, &tmp32, sizeof(tmp32)); 789 if (ret) { 790 dev_err(dev->class_dev, "failed to read serial number\n"); 791 return ret; 792 } 793 serial = le32_to_cpu(tmp32); 794 795 /* let the user know what node this device is now attached to */ 796 dev_info(dev->class_dev, "USB DT9812 (%4.4x.%4.4x.%4.4x) #0x%8.8x\n", 797 vendor, product, devpriv->device, serial); 798 799 if (devpriv->device != DT9812_DEVID_DT9812_10 && 800 devpriv->device != DT9812_DEVID_DT9812_2PT5) { 801 dev_err(dev->class_dev, "Unsupported device!\n"); 802 return -EINVAL; 803 } 804 805 return 0; 806 } 807 808 static int dt9812_auto_attach(struct comedi_device *dev, 809 unsigned long context) 810 { 811 struct usb_interface *intf = comedi_to_usb_interface(dev); 812 struct dt9812_private *devpriv; 813 struct comedi_subdevice *s; 814 bool is_unipolar; 815 int ret; 816 int i; 817 818 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 819 if (!devpriv) 820 return -ENOMEM; 821 822 mutex_init(&devpriv->mut); 823 usb_set_intfdata(intf, devpriv); 824 825 ret = dt9812_find_endpoints(dev); 826 if (ret) 827 return ret; 828 829 ret = dt9812_reset_device(dev); 830 if (ret) 831 return ret; 832 833 is_unipolar = (devpriv->device == DT9812_DEVID_DT9812_2PT5); 834 835 ret = comedi_alloc_subdevices(dev, 4); 836 if (ret) 837 return ret; 838 839 /* Digital Input subdevice */ 840 s = &dev->subdevices[0]; 841 s->type = COMEDI_SUBD_DI; 842 s->subdev_flags = SDF_READABLE; 843 s->n_chan = 8; 844 s->maxdata = 1; 845 s->range_table = &range_digital; 846 s->insn_bits = dt9812_di_insn_bits; 847 848 /* Digital Output subdevice */ 849 s = &dev->subdevices[1]; 850 s->type = COMEDI_SUBD_DO; 851 s->subdev_flags = SDF_WRITABLE; 852 s->n_chan = 8; 853 s->maxdata = 1; 854 s->range_table = &range_digital; 855 s->insn_bits = dt9812_do_insn_bits; 856 857 /* Analog Input subdevice */ 858 s = &dev->subdevices[2]; 859 s->type = COMEDI_SUBD_AI; 860 s->subdev_flags = SDF_READABLE | SDF_GROUND; 861 s->n_chan = 8; 862 s->maxdata = 0x0fff; 863 s->range_table = is_unipolar ? &range_unipolar2_5 : &range_bipolar10; 864 s->insn_read = dt9812_ai_insn_read; 865 866 /* Analog Output subdevice */ 867 s = &dev->subdevices[3]; 868 s->type = COMEDI_SUBD_AO; 869 s->subdev_flags = SDF_WRITABLE; 870 s->n_chan = 2; 871 s->maxdata = 0x0fff; 872 s->range_table = is_unipolar ? &range_unipolar2_5 : &range_bipolar10; 873 s->insn_write = dt9812_ao_insn_write; 874 s->insn_read = dt9812_ao_insn_read; 875 876 ret = comedi_alloc_subdev_readback(s); 877 if (ret) 878 return ret; 879 880 for (i = 0; i < s->n_chan; i++) 881 s->readback[i] = is_unipolar ? 0x0000 : 0x0800; 882 883 return 0; 884 } 885 886 static void dt9812_detach(struct comedi_device *dev) 887 { 888 struct usb_interface *intf = comedi_to_usb_interface(dev); 889 struct dt9812_private *devpriv = dev->private; 890 891 if (!devpriv) 892 return; 893 894 mutex_destroy(&devpriv->mut); 895 usb_set_intfdata(intf, NULL); 896 } 897 898 static struct comedi_driver dt9812_driver = { 899 .driver_name = "dt9812", 900 .module = THIS_MODULE, 901 .auto_attach = dt9812_auto_attach, 902 .detach = dt9812_detach, 903 }; 904 905 static int dt9812_usb_probe(struct usb_interface *intf, 906 const struct usb_device_id *id) 907 { 908 return comedi_usb_auto_config(intf, &dt9812_driver, id->driver_info); 909 } 910 911 static const struct usb_device_id dt9812_usb_table[] = { 912 { USB_DEVICE(0x0867, 0x9812) }, 913 { } 914 }; 915 MODULE_DEVICE_TABLE(usb, dt9812_usb_table); 916 917 static struct usb_driver dt9812_usb_driver = { 918 .name = "dt9812", 919 .id_table = dt9812_usb_table, 920 .probe = dt9812_usb_probe, 921 .disconnect = comedi_usb_auto_unconfig, 922 }; 923 module_comedi_usb_driver(dt9812_driver, dt9812_usb_driver); 924 925 MODULE_AUTHOR("Anders Blomdell <anders.blomdell@control.lth.se>"); 926 MODULE_DESCRIPTION("Comedi DT9812 driver"); 927 MODULE_LICENSE("GPL"); 928