dt9812.c revision c73190fa2e3ab6b441170ce23bd4bd7a44e213fd
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 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 * 23 */ 24 25/* 26Driver: dt9812 27Description: Data Translation DT9812 USB module 28Author: anders.blomdell@control.lth.se (Anders Blomdell) 29Status: in development 30Devices: [Data Translation] DT9812 (dt9812) 31Updated: Sun Nov 20 20:18:34 EST 2005 32 33This driver works, but bulk transfers not implemented. Might be a starting point 34for someone else. I found out too late that USB has too high latencies (>1 ms) 35for my needs. 36*/ 37 38/* 39 * Nota Bene: 40 * 1. All writes to command pipe has to be 32 bytes (ISP1181B SHRTP=0 ?) 41 * 2. The DDK source (as of sep 2005) is in error regarding the 42 * input MUX bits (example code says P4, but firmware schematics 43 * says P1). 44 */ 45 46#include <linux/kernel.h> 47#include <linux/errno.h> 48#include <linux/init.h> 49#include <linux/slab.h> 50#include <linux/module.h> 51#include <linux/kref.h> 52#include <linux/uaccess.h> 53#include <linux/usb.h> 54 55#include "../comedidev.h" 56 57#define DT9812_DIAGS_BOARD_INFO_ADDR 0xFBFF 58#define DT9812_MAX_WRITE_CMD_PIPE_SIZE 32 59#define DT9812_MAX_READ_CMD_PIPE_SIZE 32 60 61/* 62 * See Silican Laboratories C8051F020/1/2/3 manual 63 */ 64#define F020_SFR_P4 0x84 65#define F020_SFR_P1 0x90 66#define F020_SFR_P2 0xa0 67#define F020_SFR_P3 0xb0 68#define F020_SFR_AMX0CF 0xba 69#define F020_SFR_AMX0SL 0xbb 70#define F020_SFR_ADC0CF 0xbc 71#define F020_SFR_ADC0L 0xbe 72#define F020_SFR_ADC0H 0xbf 73#define F020_SFR_DAC0L 0xd2 74#define F020_SFR_DAC0H 0xd3 75#define F020_SFR_DAC0CN 0xd4 76#define F020_SFR_DAC1L 0xd5 77#define F020_SFR_DAC1H 0xd6 78#define F020_SFR_DAC1CN 0xd7 79#define F020_SFR_ADC0CN 0xe8 80 81#define F020_MASK_ADC0CF_AMP0GN0 0x01 82#define F020_MASK_ADC0CF_AMP0GN1 0x02 83#define F020_MASK_ADC0CF_AMP0GN2 0x04 84 85#define F020_MASK_ADC0CN_AD0EN 0x80 86#define F020_MASK_ADC0CN_AD0INT 0x20 87#define F020_MASK_ADC0CN_AD0BUSY 0x10 88 89#define F020_MASK_DACxCN_DACxEN 0x80 90 91typedef enum { 92 /* A/D D/A DI DO CT */ 93 DT9812_DEVID_DT9812_10, /* 8 2 8 8 1 +/- 10V */ 94 DT9812_DEVID_DT9812_2PT5,/* 8 2 8 8 1 0-2.44V */ 95#if 0 96 DT9812_DEVID_DT9813, /* 16 2 4 4 1 +/- 10V */ 97 DT9812_DEVID_DT9814 /* 24 2 0 0 1 +/- 10V */ 98#endif 99} dt9812_devid_t; 100 101typedef enum { 102 DT9812_GAIN_0PT25 = 1, 103 DT9812_GAIN_0PT5 = 2, 104 DT9812_GAIN_1 = 4, 105 DT9812_GAIN_2 = 8, 106 DT9812_GAIN_4 = 16, 107 DT9812_GAIN_8 = 32, 108 DT9812_GAIN_16 = 64, 109} dt9812_gain_t; 110 111typedef enum { 112 DT9812_LEAST_USB_FIRMWARE_CMD_CODE = 0, 113 /* Write Flash memory */ 114 DT9812_W_FLASH_DATA = 0, 115 /* Read Flash memory misc config info */ 116 DT9812_R_FLASH_DATA = 1, 117 118 /* 119 * Register read/write commands for processor 120 */ 121 122 /* Read a single byte of USB memory */ 123 DT9812_R_SINGLE_BYTE_REG = 2, 124 /* Write a single byte of USB memory */ 125 DT9812_W_SINGLE_BYTE_REG = 3, 126 /* Multiple Reads of USB memory */ 127 DT9812_R_MULTI_BYTE_REG = 4, 128 /* Multiple Writes of USB memory */ 129 DT9812_W_MULTI_BYTE_REG = 5, 130 /* Read, (AND) with mask, OR value, then write (single) */ 131 DT9812_RMW_SINGLE_BYTE_REG = 6, 132 /* Read, (AND) with mask, OR value, then write (multiple) */ 133 DT9812_RMW_MULTI_BYTE_REG = 7, 134 135 /* 136 * Register read/write commands for SMBus 137 */ 138 139 /* Read a single byte of SMBus */ 140 DT9812_R_SINGLE_BYTE_SMBUS = 8, 141 /* Write a single byte of SMBus */ 142 DT9812_W_SINGLE_BYTE_SMBUS = 9, 143 /* Multiple Reads of SMBus */ 144 DT9812_R_MULTI_BYTE_SMBUS = 10, 145 /* Multiple Writes of SMBus */ 146 DT9812_W_MULTI_BYTE_SMBUS = 11, 147 148 /* 149 * Register read/write commands for a device 150 */ 151 152 /* Read a single byte of a device */ 153 DT9812_R_SINGLE_BYTE_DEV = 12, 154 /* Write a single byte of a device */ 155 DT9812_W_SINGLE_BYTE_DEV = 13, 156 /* Multiple Reads of a device */ 157 DT9812_R_MULTI_BYTE_DEV = 14, 158 /* Multiple Writes of a device */ 159 DT9812_W_MULTI_BYTE_DEV = 15, 160 161 /* Not sure if we'll need this */ 162 DT9812_W_DAC_THRESHOLD = 16, 163 164 /* Set interrupt on change mask */ 165 DT9812_W_INT_ON_CHANGE_MASK = 17, 166 167 /* Write (or Clear) the CGL for the ADC */ 168 DT9812_W_CGL = 18, 169 /* Multiple Reads of USB memory */ 170 DT9812_R_MULTI_BYTE_USBMEM = 19, 171 /* Multiple Writes to USB memory */ 172 DT9812_W_MULTI_BYTE_USBMEM = 20, 173 174 /* Issue a start command to a given subsystem */ 175 DT9812_START_SUBSYSTEM = 21, 176 /* Issue a stop command to a given subsystem */ 177 DT9812_STOP_SUBSYSTEM = 22, 178 179 /* calibrate the board using CAL_POT_CMD */ 180 DT9812_CALIBRATE_POT = 23, 181 /* set the DAC FIFO size */ 182 DT9812_W_DAC_FIFO_SIZE = 24, 183 /* Write or Clear the CGL for the DAC */ 184 DT9812_W_CGL_DAC = 25, 185 /* Read a single value from a subsystem */ 186 DT9812_R_SINGLE_VALUE_CMD = 26, 187 /* Write a single value to a subsystem */ 188 DT9812_W_SINGLE_VALUE_CMD = 27, 189 /* Valid DT9812_USB_FIRMWARE_CMD_CODE's will be less than this number */ 190 DT9812_MAX_USB_FIRMWARE_CMD_CODE, 191} dt9812_usb_firmware_cmd_t; 192 193typedef struct { 194 u16 numbytes; 195 u16 address; 196} dt9812_flash_data_t; 197 198#define DT9812_MAX_NUM_MULTI_BYTE_RDS \ 199 ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / sizeof(u8)) 200 201typedef struct { 202 u8 count; 203 u8 address[DT9812_MAX_NUM_MULTI_BYTE_RDS]; 204} dt9812_read_multi_t; 205 206typedef struct { 207 u8 address; 208 u8 value; 209} dt9812_write_byte_t; 210 211#define DT9812_MAX_NUM_MULTI_BYTE_WRTS \ 212 ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / sizeof(dt9812_write_byte_t)) 213 214typedef struct { 215 u8 count; 216 dt9812_write_byte_t write[DT9812_MAX_NUM_MULTI_BYTE_WRTS]; 217} dt9812_write_multi_t; 218 219typedef struct { 220 u8 address; 221 u8 and_mask; 222 u8 or_value; 223} dt9812_rmw_byte_t; 224 225#define DT9812_MAX_NUM_MULTI_BYTE_RMWS \ 226 ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / sizeof(dt9812_rmw_byte_t)) 227 228typedef struct { 229 u8 count; 230 dt9812_rmw_byte_t rmw[DT9812_MAX_NUM_MULTI_BYTE_RMWS]; 231} dt9812_rmw_multi_t; 232 233typedef struct dt9812_usb_cmd { 234 235 u32 cmd; 236 union { 237 dt9812_flash_data_t flash_data_info; 238 dt9812_read_multi_t read_multi_info; 239 dt9812_write_multi_t write_multi_info; 240 dt9812_rmw_multi_t rmw_multi_info; 241 } u; 242#if 0 243 WRITE_BYTE_INFO WriteByteInfo; 244 READ_BYTE_INFO ReadByteInfo; 245 WRITE_MULTI_INFO WriteMultiInfo; 246 READ_MULTI_INFO ReadMultiInfo; 247 RMW_BYTE_INFO RMWByteInfo; 248 RMW_MULTI_INFO RMWMultiInfo; 249 DAC_THRESHOLD_INFO DacThresholdInfo; 250 INT_ON_CHANGE_MASK_INFO IntOnChangeMaskInfo; 251 CGL_INFO CglInfo; 252 SUBSYSTEM_INFO SubsystemInfo; 253 CAL_POT_CMD CalPotCmd; 254 WRITE_DEV_BYTE_INFO WriteDevByteInfo; 255 READ_DEV_BYTE_INFO ReadDevByteInfo; 256 WRITE_DEV_MULTI_INFO WriteDevMultiInfo; 257 READ_DEV_MULTI_INFO ReadDevMultiInfo; 258 READ_SINGLE_VALUE_INFO ReadSingleValueInfo; 259 WRITE_SINGLE_VALUE_INFO WriteSingleValueInfo; 260#endif 261} dt9812_usb_cmd_t; 262 263#define DT9812_NUM_SLOTS 16 264 265static DECLARE_MUTEX(dt9812_mutex); 266 267static struct usb_device_id dt9812_table[] = { 268 {USB_DEVICE(0x0867, 0x9812)}, 269 { } /* Terminating entry */ 270}; 271 272MODULE_DEVICE_TABLE(usb, dt9812_table); 273 274typedef struct usb_dt9812 { 275 struct slot_dt9812 *slot; 276 struct usb_device *udev; 277 struct usb_interface *interface; 278 u16 vendor; 279 u16 product; 280 u16 device; 281 u32 serial; 282 struct { 283 __u8 addr; 284 size_t size; 285 } message_pipe, command_write, command_read, write_stream, read_stream; 286 struct kref kref; 287 u16 analog_out_shadow[2]; 288 u8 digital_out_shadow; 289} usb_dt9812_t; 290 291typedef struct comedi_dt9812 { 292 struct slot_dt9812 *slot; 293 u32 serial; 294} comedi_dt9812_t; 295 296typedef struct slot_dt9812 { 297 struct semaphore mutex; 298 u32 serial; 299 usb_dt9812_t *usb; 300 comedi_dt9812_t *comedi; 301} slot_dt9812_t; 302 303static const comedi_lrange dt9812_10_ain_range = { 1, { 304 BIP_RANGE(10), 305 } 306}; 307 308static const comedi_lrange dt9812_2pt5_ain_range = { 1, { 309 UNI_RANGE(2.5), 310 } 311}; 312 313static const comedi_lrange dt9812_10_aout_range = { 1, { 314 BIP_RANGE(10), 315 } 316}; 317 318static const comedi_lrange dt9812_2pt5_aout_range = { 1, { 319 UNI_RANGE(2.5), 320 } 321}; 322 323static slot_dt9812_t dt9812[DT9812_NUM_SLOTS]; 324 325/* Useful shorthand access to private data */ 326#define devpriv ((comedi_dt9812_t *)dev->private) 327 328static inline usb_dt9812_t *to_dt9812_dev(struct kref *d) 329{ 330 return container_of(d, usb_dt9812_t, kref); 331} 332 333static void dt9812_delete(struct kref *kref) 334{ 335 usb_dt9812_t *dev = to_dt9812_dev(kref); 336 337 usb_put_dev(dev->udev); 338 kfree(dev); 339} 340 341static int dt9812_read_info(usb_dt9812_t *dev, int offset, void *buf, 342 size_t buf_size) 343{ 344 dt9812_usb_cmd_t cmd; 345 int count, retval; 346 347 cmd.cmd = cpu_to_le32(DT9812_R_FLASH_DATA); 348 cmd.u.flash_data_info.address = 349 cpu_to_le16(DT9812_DIAGS_BOARD_INFO_ADDR + offset); 350 cmd.u.flash_data_info.numbytes = cpu_to_le16(buf_size); 351 352 /* DT9812 only responds to 32 byte writes!! */ 353 count = 32; 354 retval = usb_bulk_msg(dev->udev, 355 usb_sndbulkpipe(dev->udev, 356 dev->command_write.addr), 357 &cmd, 32, &count, HZ * 1); 358 if (retval) 359 return retval; 360 retval = usb_bulk_msg(dev->udev, 361 usb_rcvbulkpipe(dev->udev, 362 dev->command_read.addr), 363 buf, buf_size, &count, HZ * 1); 364 return retval; 365} 366 367static int dt9812_read_multiple_registers(usb_dt9812_t *dev, int reg_count, 368 u8 *address, u8 *value) 369{ 370 dt9812_usb_cmd_t cmd; 371 int i, count, retval; 372 373 cmd.cmd = cpu_to_le32(DT9812_R_MULTI_BYTE_REG); 374 cmd.u.read_multi_info.count = reg_count; 375 for (i = 0; i < reg_count; i++) 376 cmd.u.read_multi_info.address[i] = address[i]; 377 378 /* DT9812 only responds to 32 byte writes!! */ 379 count = 32; 380 retval = usb_bulk_msg(dev->udev, 381 usb_sndbulkpipe(dev->udev, 382 dev->command_write.addr), 383 &cmd, 32, &count, HZ * 1); 384 if (retval) 385 return retval; 386 retval = usb_bulk_msg(dev->udev, 387 usb_rcvbulkpipe(dev->udev, 388 dev->command_read.addr), 389 value, reg_count, &count, HZ * 1); 390 return retval; 391} 392 393static int dt9812_write_multiple_registers(usb_dt9812_t *dev, int reg_count, 394 u8 *address, u8 *value) 395{ 396 dt9812_usb_cmd_t cmd; 397 int i, count, retval; 398 399 cmd.cmd = cpu_to_le32(DT9812_W_MULTI_BYTE_REG); 400 cmd.u.read_multi_info.count = reg_count; 401 for (i = 0; i < reg_count; i++) { 402 cmd.u.write_multi_info.write[i].address = address[i]; 403 cmd.u.write_multi_info.write[i].value = value[i]; 404 } 405 /* DT9812 only responds to 32 byte writes!! */ 406 retval = usb_bulk_msg(dev->udev, 407 usb_sndbulkpipe(dev->udev, 408 dev->command_write.addr), 409 &cmd, 32, &count, HZ * 1); 410 return retval; 411} 412 413static int dt9812_rmw_multiple_registers(usb_dt9812_t *dev, int reg_count, 414 dt9812_rmw_byte_t rmw[]) 415{ 416 dt9812_usb_cmd_t cmd; 417 int i, count, retval; 418 419 cmd.cmd = cpu_to_le32(DT9812_RMW_MULTI_BYTE_REG); 420 cmd.u.rmw_multi_info.count = reg_count; 421 for (i = 0; i < reg_count; i++) 422 cmd.u.rmw_multi_info.rmw[i] = rmw[i]; 423 424 /* DT9812 only responds to 32 byte writes!! */ 425 retval = usb_bulk_msg(dev->udev, 426 usb_sndbulkpipe(dev->udev, 427 dev->command_write.addr), 428 &cmd, 32, &count, HZ * 1); 429 return retval; 430} 431 432static int dt9812_digital_in(slot_dt9812_t *slot, u8 *bits) 433{ 434 int result = -ENODEV; 435 436 down(&slot->mutex); 437 if (slot->usb) { 438 u8 reg[2] = { F020_SFR_P3, F020_SFR_P1 }; 439 u8 value[2]; 440 441 result = dt9812_read_multiple_registers(slot->usb, 2, reg, 442 value); 443 if (result == 0) { 444 /* 445 * bits 0-6 in F020_SFR_P3 are bits 0-6 in the digital 446 * input port bit 3 in F020_SFR_P1 is bit 7 in the 447 * digital input port 448 */ 449 *bits = (value[0] & 0x7f) | ((value[1] & 0x08) << 4); 450 /* printk("%2.2x, %2.2x -> %2.2x\n", 451 value[0], value[1], *bits); */ 452 } 453 } 454 up(&slot->mutex); 455 456 return result; 457} 458 459static int dt9812_digital_out(slot_dt9812_t *slot, u8 bits) 460{ 461 int result = -ENODEV; 462 463 down(&slot->mutex); 464 if (slot->usb) { 465 u8 reg[1]; 466 u8 value[1]; 467 468 reg[0] = F020_SFR_P2; 469 value[0] = bits; 470 result = dt9812_write_multiple_registers(slot->usb, 1, reg, 471 value); 472 slot->usb->digital_out_shadow = bits; 473 } 474 up(&slot->mutex); 475 return result; 476} 477 478static int dt9812_digital_out_shadow(slot_dt9812_t *slot, u8 *bits) 479{ 480 int result = -ENODEV; 481 482 down(&slot->mutex); 483 if (slot->usb) { 484 *bits = slot->usb->digital_out_shadow; 485 result = 0; 486 } 487 up(&slot->mutex); 488 return result; 489} 490 491static void dt9812_configure_mux(usb_dt9812_t *dev, dt9812_rmw_byte_t *rmw, 492 int channel) 493{ 494 if (dev->device == DT9812_DEVID_DT9812_10) { 495 /* In the DT9812/10V MUX is selected by P1.5-7 */ 496 rmw->address = F020_SFR_P1; 497 rmw->and_mask = 0xe0; 498 rmw->or_value = channel << 5; 499 } else { 500 /* In the DT9812/2.5V, internal mux is selected by bits 0:2 */ 501 rmw->address = F020_SFR_AMX0SL; 502 rmw->and_mask = 0xff; 503 rmw->or_value = channel & 0x07; 504 } 505} 506 507static void dt9812_configure_gain(usb_dt9812_t *dev, dt9812_rmw_byte_t *rmw, 508 dt9812_gain_t gain) 509{ 510 if (dev->device == DT9812_DEVID_DT9812_10) { 511 /* In the DT9812/10V, there is an external gain of 0.5 */ 512 gain <<= 1; 513 } 514 515 rmw->address = F020_SFR_ADC0CF; 516 rmw->and_mask = F020_MASK_ADC0CF_AMP0GN2 | 517 F020_MASK_ADC0CF_AMP0GN1 | 518 F020_MASK_ADC0CF_AMP0GN0; 519 switch (gain) { 520 /* 521 * 000 -> Gain = 1 522 * 001 -> Gain = 2 523 * 010 -> Gain = 4 524 * 011 -> Gain = 8 525 * 10x -> Gain = 16 526 * 11x -> Gain = 0.5 527 */ 528 case DT9812_GAIN_0PT5: 529 rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 || 530 F020_MASK_ADC0CF_AMP0GN1; 531 break; 532 case DT9812_GAIN_1: 533 rmw->or_value = 0x00; 534 break; 535 case DT9812_GAIN_2: 536 rmw->or_value = F020_MASK_ADC0CF_AMP0GN0; 537 break; 538 case DT9812_GAIN_4: 539 rmw->or_value = F020_MASK_ADC0CF_AMP0GN1; 540 break; 541 case DT9812_GAIN_8: 542 rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 || 543 F020_MASK_ADC0CF_AMP0GN0; 544 break; 545 case DT9812_GAIN_16: 546 rmw->or_value = F020_MASK_ADC0CF_AMP0GN2; 547 break; 548 default: 549 err("Illegal gain %d\n", gain); 550 551 } 552} 553 554static int dt9812_analog_in(slot_dt9812_t *slot, int channel, u16 *value, 555 dt9812_gain_t gain) 556{ 557 dt9812_rmw_byte_t rmw[3]; 558 u8 reg[3] = { 559 F020_SFR_ADC0CN, 560 F020_SFR_ADC0H, 561 F020_SFR_ADC0L 562 }; 563 u8 val[3]; 564 int result = -ENODEV; 565 566 down(&slot->mutex); 567 if (!slot->usb) 568 goto exit; 569 570 /* 1 select the gain */ 571 dt9812_configure_gain(slot->usb, &rmw[0], gain); 572 573 /* 2 set the MUX to select the channel */ 574 dt9812_configure_mux(slot->usb, &rmw[1], channel); 575 576 /* 3 start conversion */ 577 rmw[2].address = F020_SFR_ADC0CN; 578 rmw[2].and_mask = 0xff; 579 rmw[2].or_value = F020_MASK_ADC0CN_AD0EN | F020_MASK_ADC0CN_AD0BUSY; 580 581 result = dt9812_rmw_multiple_registers(slot->usb, 3, rmw); 582 if (result) 583 goto exit; 584 585 /* read the status and ADC */ 586 result = dt9812_read_multiple_registers(slot->usb, 3, reg, val); 587 if (result) 588 goto exit; 589 /* 590 * An ADC conversion takes 16 SAR clocks cycles, i.e. about 9us. 591 * Therefore, between the instant that AD0BUSY was set via 592 * dt9812_rmw_multiple_registers and the read of AD0BUSY via 593 * dt9812_read_multiple_registers, the conversion should be complete 594 * since these two operations require two USB transactions each taking 595 * at least a millisecond to complete. However, lets make sure that 596 * conversion is finished. 597 */ 598 if ((val[0] & (F020_MASK_ADC0CN_AD0INT | F020_MASK_ADC0CN_AD0BUSY)) == 599 F020_MASK_ADC0CN_AD0INT) { 600 switch (slot->usb->device) { 601 case DT9812_DEVID_DT9812_10: 602 /* 603 * For DT9812-10V the personality module set the 604 * encoding to 2's complement. Hence, convert it before 605 * returning it 606 */ 607 *value = ((val[1] << 8) | val[2]) + 0x800; 608 break; 609 case DT9812_DEVID_DT9812_2PT5: 610 *value = (val[1] << 8) | val[2]; 611 break; 612 } 613 } 614 615exit: 616 up(&slot->mutex); 617 return result; 618} 619 620static int dt9812_analog_out_shadow(slot_dt9812_t *slot, int channel, 621 u16 *value) 622{ 623 int result = -ENODEV; 624 625 down(&slot->mutex); 626 if (slot->usb) { 627 *value = slot->usb->analog_out_shadow[channel]; 628 result = 0; 629 } 630 up(&slot->mutex); 631 632 return result; 633} 634 635static int dt9812_analog_out(slot_dt9812_t *slot, int channel, u16 value) 636{ 637 int result = -ENODEV; 638 639 down(&slot->mutex); 640 if (slot->usb) { 641 dt9812_rmw_byte_t rmw[3]; 642 643 switch (channel) { 644 case 0: 645 /* 1. Set DAC mode */ 646 rmw[0].address = F020_SFR_DAC0CN; 647 rmw[0].and_mask = 0xff; 648 rmw[0].or_value = F020_MASK_DACxCN_DACxEN; 649 650 /* 2 load low byte of DAC value first */ 651 rmw[1].address = F020_SFR_DAC0L; 652 rmw[1].and_mask = 0xff; 653 rmw[1].or_value = value & 0xff; 654 655 /* 3 load high byte of DAC value next to latch the 656 12-bit value */ 657 rmw[2].address = F020_SFR_DAC0H; 658 rmw[2].and_mask = 0xff; 659 rmw[2].or_value = (value >> 8) & 0xf; 660 break; 661 662 case 1: 663 /* 1. Set DAC mode */ 664 rmw[0].address = F020_SFR_DAC1CN; 665 rmw[0].and_mask = 0xff; 666 rmw[0].or_value = F020_MASK_DACxCN_DACxEN; 667 668 /* 2 load low byte of DAC value first */ 669 rmw[1].address = F020_SFR_DAC1L; 670 rmw[1].and_mask = 0xff; 671 rmw[1].or_value = value & 0xff; 672 673 /* 3 load high byte of DAC value next to latch the 674 12-bit value */ 675 rmw[2].address = F020_SFR_DAC1H; 676 rmw[2].and_mask = 0xff; 677 rmw[2].or_value = (value >> 8) & 0xf; 678 break; 679 } 680 result = dt9812_rmw_multiple_registers(slot->usb, 3, rmw); 681 slot->usb->analog_out_shadow[channel] = value; 682 } 683 up(&slot->mutex); 684 685 return result; 686} 687 688/* 689 * USB framework functions 690 */ 691 692static int dt9812_probe(struct usb_interface *interface, 693 const struct usb_device_id *id) 694{ 695 int retval = -ENOMEM; 696 usb_dt9812_t *dev = NULL; 697 struct usb_host_interface *iface_desc; 698 struct usb_endpoint_descriptor *endpoint; 699 int i; 700 u8 fw; 701 702 /* allocate memory for our device state and initialize it */ 703 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 704 if (dev == NULL) { 705 dev_err(&interface->dev, "Out of memory\n"); 706 goto error; 707 } 708 kref_init(&dev->kref); 709 710 dev->udev = usb_get_dev(interface_to_usbdev(interface)); 711 dev->interface = interface; 712 713 /* Check endpoints */ 714 iface_desc = interface->cur_altsetting; 715 716 if (iface_desc->desc.bNumEndpoints != 5) { 717 err("Wrong number of endpints."); 718 retval = -ENODEV; 719 goto error; 720 } 721 722 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { 723 int direction = -1; 724 endpoint = &iface_desc->endpoint[i].desc; 725 switch (i) { 726 case 0: 727 direction = USB_DIR_IN; 728 dev->message_pipe.addr = endpoint->bEndpointAddress; 729 dev->message_pipe.size = 730 le16_to_cpu(endpoint->wMaxPacketSize); 731 732 break; 733 case 1: 734 direction = USB_DIR_OUT; 735 dev->command_write.addr = endpoint->bEndpointAddress; 736 dev->command_write.size = 737 le16_to_cpu(endpoint->wMaxPacketSize); 738 break; 739 case 2: 740 direction = USB_DIR_IN; 741 dev->command_read.addr = endpoint->bEndpointAddress; 742 dev->command_read.size = 743 le16_to_cpu(endpoint->wMaxPacketSize); 744 break; 745 case 3: 746 direction = USB_DIR_OUT; 747 dev->write_stream.addr = endpoint->bEndpointAddress; 748 dev->write_stream.size = 749 le16_to_cpu(endpoint->wMaxPacketSize); 750 break; 751 case 4: 752 direction = USB_DIR_IN; 753 dev->read_stream.addr = endpoint->bEndpointAddress; 754 dev->read_stream.size = 755 le16_to_cpu(endpoint->wMaxPacketSize); 756 break; 757 } 758 if ((endpoint->bEndpointAddress & USB_DIR_IN) != direction) { 759 dev_err(&interface->dev, 760 "Endpoint has wrong direction.\n"); 761 retval = -ENODEV; 762 goto error; 763 } 764 } 765 if (dt9812_read_info(dev, 0, &fw, sizeof(fw)) != 0) { 766 /* 767 * Seems like a configuration reset is necessary if driver is 768 * reloaded while device is attached 769 */ 770 int i; 771 772 usb_reset_configuration(dev->udev); 773 for (i = 0; i < 10; i++) { 774 retval = dt9812_read_info(dev, 1, &fw, sizeof(fw)); 775 if (retval == 0) { 776 dev_info(&interface->dev, 777 "usb_reset_configuration succeded " 778 "after %d iterations\n", i); 779 break; 780 } 781 } 782 } 783 784 if (dt9812_read_info(dev, 1, &dev->vendor, sizeof(dev->vendor)) != 0) { 785 err("Failed to read vendor."); 786 retval = -ENODEV; 787 goto error; 788 } 789 if (dt9812_read_info(dev, 3, &dev->product, 790 sizeof(dev->product)) != 0) { 791 err("Failed to read product."); 792 retval = -ENODEV; 793 goto error; 794 } 795 if (dt9812_read_info(dev, 5, &dev->device, sizeof(dev->device)) != 0) { 796 err("Failed to read device."); 797 retval = -ENODEV; 798 goto error; 799 } 800 if (dt9812_read_info(dev, 7, &dev->serial, sizeof(dev->serial)) != 0) { 801 err("Failed to read serial."); 802 retval = -ENODEV; 803 goto error; 804 } 805 806 dev->vendor = le16_to_cpu(dev->vendor); 807 dev->product = le16_to_cpu(dev->product); 808 dev->device = le16_to_cpu(dev->device); 809 dev->serial = le32_to_cpu(dev->serial); 810 switch (dev->device) { 811 case DT9812_DEVID_DT9812_10: 812 dev->analog_out_shadow[0] = 0x0800; 813 dev->analog_out_shadow[1] = 0x800; 814 break; 815 case DT9812_DEVID_DT9812_2PT5: 816 dev->analog_out_shadow[0] = 0x0000; 817 dev->analog_out_shadow[1] = 0x0000; 818 break; 819 } 820 dev->digital_out_shadow = 0; 821 822 /* save our data pointer in this interface device */ 823 usb_set_intfdata(interface, dev); 824 825 /* let the user know what node this device is now attached to */ 826 dev_info(&interface->dev, "USB DT9812 (%4.4x.%4.4x.%4.4x) #0x%8.8x\n", 827 dev->vendor, dev->product, dev->device, dev->serial); 828 829 down(&dt9812_mutex); 830 { 831 /* Find a slot for the USB device */ 832 slot_dt9812_t *first = NULL; 833 slot_dt9812_t *best = NULL; 834 835 for (i = 0; i < DT9812_NUM_SLOTS; i++) { 836 if (!first && !dt9812[i].usb && dt9812[i].serial == 0) 837 first = &dt9812[i]; 838 if (!best && dt9812[i].serial == dev->serial) 839 best = &dt9812[i]; 840 } 841 842 if (!best) 843 best = first; 844 845 if (best) { 846 down(&best->mutex); 847 best->usb = dev; 848 dev->slot = best; 849 up(&best->mutex); 850 } 851 } 852 up(&dt9812_mutex); 853 854 return 0; 855 856error: 857 if (dev) 858 kref_put(&dev->kref, dt9812_delete); 859 return retval; 860} 861 862static void dt9812_disconnect(struct usb_interface *interface) 863{ 864 usb_dt9812_t *dev; 865 int minor = interface->minor; 866 867 down(&dt9812_mutex); 868 dev = usb_get_intfdata(interface); 869 if (dev->slot) { 870 down(&dev->slot->mutex); 871 dev->slot->usb = NULL; 872 up(&dev->slot->mutex); 873 dev->slot = NULL; 874 } 875 usb_set_intfdata(interface, NULL); 876 up(&dt9812_mutex); 877 878 /* queue final destruction */ 879 kref_put(&dev->kref, dt9812_delete); 880 881 dev_info(&interface->dev, "USB Dt9812 #%d now disconnected\n", minor); 882} 883 884static struct usb_driver dt9812_usb_driver = { 885#ifdef COMEDI_HAVE_USB_DRIVER_OWNER 886 .owner = THIS_MODULE, 887#endif 888 .name = "dt9812", 889 .probe = dt9812_probe, 890 .disconnect = dt9812_disconnect, 891 .id_table = dt9812_table, 892}; 893 894/* 895 * Comedi functions 896 */ 897 898static void dt9812_comedi_open(comedi_device *dev) 899{ 900 down(&devpriv->slot->mutex); 901 if (devpriv->slot->usb) { 902 /* We have an attached device, fill in current range info */ 903 comedi_subdevice *s; 904 905 s = &dev->subdevices[0]; 906 s->n_chan = 8; 907 s->maxdata = 1; 908 909 s = &dev->subdevices[1]; 910 s->n_chan = 8; 911 s->maxdata = 1; 912 913 s = &dev->subdevices[2]; 914 s->n_chan = 8; 915 switch (devpriv->slot->usb->device) { 916 case 0:{ 917 s->maxdata = 4095; 918 s->range_table = &dt9812_10_ain_range; 919 } 920 break; 921 case 1:{ 922 s->maxdata = 4095; 923 s->range_table = &dt9812_2pt5_ain_range; 924 } 925 break; 926 } 927 928 s = &dev->subdevices[3]; 929 s->n_chan = 2; 930 switch (devpriv->slot->usb->device) { 931 case 0:{ 932 s->maxdata = 4095; 933 s->range_table = &dt9812_10_aout_range; 934 } 935 break; 936 case 1:{ 937 s->maxdata = 4095; 938 s->range_table = &dt9812_2pt5_aout_range; 939 } 940 break; 941 } 942 } 943 up(&devpriv->slot->mutex); 944} 945 946static int dt9812_di_rinsn(comedi_device *dev, comedi_subdevice *s, 947 comedi_insn *insn, lsampl_t *data) 948{ 949 int n; 950 u8 bits = 0; 951 952 dt9812_digital_in(devpriv->slot, &bits); 953 for (n = 0; n < insn->n; n++) 954 data[n] = ((1 << insn->chanspec) & bits) != 0; 955 return n; 956} 957 958static int dt9812_do_winsn(comedi_device *dev, comedi_subdevice *s, 959 comedi_insn *insn, lsampl_t *data) 960{ 961 int n; 962 u8 bits = 0; 963 964 dt9812_digital_out_shadow(devpriv->slot, &bits); 965 for (n = 0; n < insn->n; n++) { 966 u8 mask = 1 << insn->chanspec; 967 968 bits &= ~mask; 969 if (data[n]) 970 bits |= mask; 971 } 972 dt9812_digital_out(devpriv->slot, bits); 973 return n; 974} 975 976static int dt9812_ai_rinsn(comedi_device *dev, comedi_subdevice *s, 977 comedi_insn *insn, lsampl_t *data) 978{ 979 int n; 980 981 for (n = 0; n < insn->n; n++) { 982 u16 value = 0; 983 984 dt9812_analog_in(devpriv->slot, insn->chanspec, &value, 985 DT9812_GAIN_1); 986 data[n] = value; 987 } 988 return n; 989} 990 991static int dt9812_ao_rinsn(comedi_device *dev, comedi_subdevice *s, 992 comedi_insn *insn, lsampl_t *data) 993{ 994 int n; 995 u16 value; 996 997 for (n = 0; n < insn->n; n++) { 998 value = 0; 999 dt9812_analog_out_shadow(devpriv->slot, insn->chanspec, &value); 1000 data[n] = value; 1001 } 1002 return n; 1003} 1004 1005static int dt9812_ao_winsn(comedi_device *dev, comedi_subdevice *s, 1006 comedi_insn *insn, lsampl_t *data) 1007{ 1008 int n; 1009 1010 for (n = 0; n < insn->n; n++) 1011 dt9812_analog_out(devpriv->slot, insn->chanspec, data[n]); 1012 return n; 1013} 1014 1015static int dt9812_attach(comedi_device *dev, comedi_devconfig *it) 1016{ 1017 int i; 1018 comedi_subdevice *s; 1019 1020 dev->board_name = "dt9812"; 1021 1022 if (alloc_private(dev, sizeof(comedi_dt9812_t)) < 0) 1023 return -ENOMEM; 1024 1025 /* 1026 * Special open routine, since USB unit may be unattached at 1027 * comedi_config time, hence range can not be determined 1028 */ 1029 dev->open = dt9812_comedi_open; 1030 1031 devpriv->serial = it->options[0]; 1032 1033 /* Allocate subdevices */ 1034 if (alloc_subdevices(dev, 4) < 0) 1035 return -ENOMEM; 1036 1037 /* digital input subdevice */ 1038 s = dev->subdevices + 0; 1039 s->type = COMEDI_SUBD_DI; 1040 s->subdev_flags = SDF_READABLE; 1041 s->n_chan = 0; 1042 s->maxdata = 1; 1043 s->range_table = &range_digital; 1044 s->insn_read = &dt9812_di_rinsn; 1045 1046 /* digital output subdevice */ 1047 s = dev->subdevices + 1; 1048 s->type = COMEDI_SUBD_DO; 1049 s->subdev_flags = SDF_WRITEABLE; 1050 s->n_chan = 0; 1051 s->maxdata = 1; 1052 s->range_table = &range_digital; 1053 s->insn_write = &dt9812_do_winsn; 1054 1055 /* analog input subdevice */ 1056 s = dev->subdevices + 2; 1057 s->type = COMEDI_SUBD_AI; 1058 s->subdev_flags = SDF_READABLE | SDF_GROUND; 1059 s->n_chan = 0; 1060 s->maxdata = 1; 1061 s->range_table = 0; 1062 s->insn_read = &dt9812_ai_rinsn; 1063 1064 /* analog output subdevice */ 1065 s = dev->subdevices + 3; 1066 s->type = COMEDI_SUBD_AO; 1067 s->subdev_flags = SDF_WRITEABLE; 1068 s->n_chan = 0; 1069 s->maxdata = 1; 1070 s->range_table = 0; 1071 s->insn_write = &dt9812_ao_winsn; 1072 s->insn_read = &dt9812_ao_rinsn; 1073 1074 printk(KERN_INFO "comedi%d: successfully attached to dt9812.\n", 1075 dev->minor); 1076 1077 down(&dt9812_mutex); 1078 /* Find a slot for the comedi device */ 1079 { 1080 slot_dt9812_t *first = NULL; 1081 slot_dt9812_t *best = NULL; 1082 for (i = 0; i < DT9812_NUM_SLOTS; i++) { 1083 if (!first && !dt9812[i].comedi) { 1084 /* First free slot from comedi side */ 1085 first = &dt9812[i]; 1086 } 1087 if (!best && 1088 dt9812[i].usb && 1089 dt9812[i].usb->serial == devpriv->serial) { 1090 /* We have an attaced device with matching ID */ 1091 best = &dt9812[i]; 1092 } 1093 } 1094 if (!best) 1095 best = first; 1096 if (best) { 1097 down(&best->mutex); 1098 best->comedi = devpriv; 1099 best->serial = devpriv->serial; 1100 devpriv->slot = best; 1101 up(&best->mutex); 1102 } 1103 } 1104 up(&dt9812_mutex); 1105 1106 return 0; 1107} 1108 1109static int dt9812_detach(comedi_device *dev) 1110{ 1111 return 0; 1112} 1113 1114static comedi_driver dt9812_comedi_driver = { 1115 .module = THIS_MODULE, 1116 .driver_name = "dt9812", 1117 .attach = dt9812_attach, 1118 .detach = dt9812_detach, 1119}; 1120 1121static int __init usb_dt9812_init(void) 1122{ 1123 int result, i; 1124 1125 /* Initialize all driver slots */ 1126 for (i = 0; i < DT9812_NUM_SLOTS; i++) { 1127 init_MUTEX(&dt9812[i].mutex); 1128 dt9812[i].serial = 0; 1129 dt9812[i].usb = NULL; 1130 dt9812[i].comedi = NULL; 1131 } 1132 dt9812[12].serial = 0x0; 1133 1134 /* register with the USB subsystem */ 1135 result = usb_register(&dt9812_usb_driver); 1136 if (result) { 1137 printk(KERN_ERR KBUILD_MODNAME 1138 ": usb_register failed. Error number %d\n", result); 1139 return result; 1140 } 1141 /* register with comedi */ 1142 result = comedi_driver_register(&dt9812_comedi_driver); 1143 if (result) { 1144 usb_deregister(&dt9812_usb_driver); 1145 err("comedi_driver_register failed. Error number %d", result); 1146 } 1147 1148 return result; 1149} 1150 1151static void __exit usb_dt9812_exit(void) 1152{ 1153 /* unregister with comedi */ 1154 comedi_driver_unregister(&dt9812_comedi_driver); 1155 1156 /* deregister this driver with the USB subsystem */ 1157 usb_deregister(&dt9812_usb_driver); 1158} 1159 1160module_init(usb_dt9812_init); 1161module_exit(usb_dt9812_exit); 1162 1163MODULE_AUTHOR("Anders Blomdell <anders.blomdell@control.lth.se>"); 1164MODULE_DESCRIPTION("Comedi DT9812 driver"); 1165MODULE_LICENSE("GPL"); 1166