1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * comedi/drivers/rtd520.c 4 * Comedi driver for Real Time Devices (RTD) PCI4520/DM7520 5 * 6 * COMEDI - Linux Control and Measurement Device Interface 7 * Copyright (C) 2001 David A. Schleef <ds@schleef.org> 8 */ 9 10 /* 11 * Driver: rtd520 12 * Description: Real Time Devices PCI4520/DM7520 13 * Devices: [Real Time Devices] DM7520HR-1 (DM7520), DM7520HR-8, 14 * PCI4520 (PCI4520), PCI4520-8 15 * Author: Dan Christian 16 * Status: Works. Only tested on DM7520-8. Not SMP safe. 17 * 18 * Configuration options: not applicable, uses PCI auto config 19 */ 20 21 /* 22 * Created by Dan Christian, NASA Ames Research Center. 23 * 24 * The PCI4520 is a PCI card. The DM7520 is a PC/104-plus card. 25 * Both have: 26 * 8/16 12 bit ADC with FIFO and channel gain table 27 * 8 bits high speed digital out (for external MUX) (or 8 in or 8 out) 28 * 8 bits high speed digital in with FIFO and interrupt on change (or 8 IO) 29 * 2 12 bit DACs with FIFOs 30 * 2 bits output 31 * 2 bits input 32 * bus mastering DMA 33 * timers: ADC sample, pacer, burst, about, delay, DA1, DA2 34 * sample counter 35 * 3 user timer/counters (8254) 36 * external interrupt 37 * 38 * The DM7520 has slightly fewer features (fewer gain steps). 39 * 40 * These boards can support external multiplexors and multi-board 41 * synchronization, but this driver doesn't support that. 42 * 43 * Board docs: http://www.rtdusa.com/PC104/DM/analog%20IO/dm7520.htm 44 * Data sheet: http://www.rtdusa.com/pdf/dm7520.pdf 45 * Example source: http://www.rtdusa.com/examples/dm/dm7520.zip 46 * Call them and ask for the register level manual. 47 * PCI chip: http://www.plxtech.com/products/io/pci9080 48 * 49 * Notes: 50 * This board is memory mapped. There is some IO stuff, but it isn't needed. 51 * 52 * I use a pretty loose naming style within the driver (rtd_blah). 53 * All externally visible names should be rtd520_blah. 54 * I use camelCase for structures (and inside them). 55 * I may also use upper CamelCase for function names (old habit). 56 * 57 * This board is somewhat related to the RTD PCI4400 board. 58 * 59 * I borrowed heavily from the ni_mio_common, ni_atmio16d, mite, and 60 * das1800, since they have the best documented code. Driver cb_pcidas64.c 61 * uses the same DMA controller. 62 * 63 * As far as I can tell, the About interrupt doesn't work if Sample is 64 * also enabled. It turns out that About really isn't needed, since 65 * we always count down samples read. 66 */ 67 68 /* 69 * driver status: 70 * 71 * Analog-In supports instruction and command mode. 72 * 73 * With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2 74 * (single channel, 64K read buffer). I get random system lockups when 75 * using DMA with ALI-15xx based systems. I haven't been able to test 76 * any other chipsets. The lockups happen soon after the start of an 77 * acquistion, not in the middle of a long run. 78 * 79 * Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2 80 * (with a 256K read buffer). 81 * 82 * Digital-IO and Analog-Out only support instruction mode. 83 */ 84 85 #include <linux/module.h> 86 #include <linux/delay.h> 87 #include <linux/interrupt.h> 88 89 #include "../comedi_pci.h" 90 91 #include "comedi_8254.h" 92 #include "plx9080.h" 93 94 /* 95 * Local Address Space 0 Offsets 96 */ 97 #define LAS0_USER_IO 0x0008 /* User I/O */ 98 #define LAS0_ADC 0x0010 /* FIFO Status/Software A/D Start */ 99 #define FS_DAC1_NOT_EMPTY BIT(0) /* DAC1 FIFO not empty */ 100 #define FS_DAC1_HEMPTY BIT(1) /* DAC1 FIFO half empty */ 101 #define FS_DAC1_NOT_FULL BIT(2) /* DAC1 FIFO not full */ 102 #define FS_DAC2_NOT_EMPTY BIT(4) /* DAC2 FIFO not empty */ 103 #define FS_DAC2_HEMPTY BIT(5) /* DAC2 FIFO half empty */ 104 #define FS_DAC2_NOT_FULL BIT(6) /* DAC2 FIFO not full */ 105 #define FS_ADC_NOT_EMPTY BIT(8) /* ADC FIFO not empty */ 106 #define FS_ADC_HEMPTY BIT(9) /* ADC FIFO half empty */ 107 #define FS_ADC_NOT_FULL BIT(10) /* ADC FIFO not full */ 108 #define FS_DIN_NOT_EMPTY BIT(12) /* DIN FIFO not empty */ 109 #define FS_DIN_HEMPTY BIT(13) /* DIN FIFO half empty */ 110 #define FS_DIN_NOT_FULL BIT(14) /* DIN FIFO not full */ 111 #define LAS0_UPDATE_DAC(x) (0x0014 + ((x) * 0x4)) /* D/Ax Update (w) */ 112 #define LAS0_DAC 0x0024 /* Software Simultaneous Update (w) */ 113 #define LAS0_PACER 0x0028 /* Software Pacer Start/Stop */ 114 #define LAS0_TIMER 0x002c /* Timer Status/HDIN Software Trig. */ 115 #define LAS0_IT 0x0030 /* Interrupt Status/Enable */ 116 #define IRQM_ADC_FIFO_WRITE BIT(0) /* ADC FIFO Write */ 117 #define IRQM_CGT_RESET BIT(1) /* Reset CGT */ 118 #define IRQM_CGT_PAUSE BIT(3) /* Pause CGT */ 119 #define IRQM_ADC_ABOUT_CNT BIT(4) /* About Counter out */ 120 #define IRQM_ADC_DELAY_CNT BIT(5) /* Delay Counter out */ 121 #define IRQM_ADC_SAMPLE_CNT BIT(6) /* ADC Sample Counter */ 122 #define IRQM_DAC1_UCNT BIT(7) /* DAC1 Update Counter */ 123 #define IRQM_DAC2_UCNT BIT(8) /* DAC2 Update Counter */ 124 #define IRQM_UTC1 BIT(9) /* User TC1 out */ 125 #define IRQM_UTC1_INV BIT(10) /* User TC1 out, inverted */ 126 #define IRQM_UTC2 BIT(11) /* User TC2 out */ 127 #define IRQM_DIGITAL_IT BIT(12) /* Digital Interrupt */ 128 #define IRQM_EXTERNAL_IT BIT(13) /* External Interrupt */ 129 #define IRQM_ETRIG_RISING BIT(14) /* Ext Trigger rising-edge */ 130 #define IRQM_ETRIG_FALLING BIT(15) /* Ext Trigger falling-edge */ 131 #define LAS0_CLEAR 0x0034 /* Clear/Set Interrupt Clear Mask */ 132 #define LAS0_OVERRUN 0x0038 /* Pending interrupts/Clear Overrun */ 133 #define LAS0_PCLK 0x0040 /* Pacer Clock (24bit) */ 134 #define LAS0_BCLK 0x0044 /* Burst Clock (10bit) */ 135 #define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter (10bit) */ 136 #define LAS0_DAC1_UCNT 0x004c /* D/A1 Update counter (10 bit) */ 137 #define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter (10 bit) */ 138 #define LAS0_DCNT 0x0054 /* Delay counter (16 bit) */ 139 #define LAS0_ACNT 0x0058 /* About counter (16 bit) */ 140 #define LAS0_DAC_CLK 0x005c /* DAC clock (16bit) */ 141 #define LAS0_8254_TIMER_BASE 0x0060 /* 8254 timer/counter base */ 142 #define LAS0_DIO0 0x0070 /* Digital I/O Port 0 */ 143 #define LAS0_DIO1 0x0074 /* Digital I/O Port 1 */ 144 #define LAS0_DIO0_CTRL 0x0078 /* Digital I/O Control */ 145 #define LAS0_DIO_STATUS 0x007c /* Digital I/O Status */ 146 #define LAS0_BOARD_RESET 0x0100 /* Board reset */ 147 #define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */ 148 #define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */ 149 #define LAS0_ADC_CONVERSION 0x010c /* A/D Conversion Signal select */ 150 #define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */ 151 #define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */ 152 #define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */ 153 #define LAS0_ACNT_STOP_ENABLE 0x011c /* About Counter Stop Enable */ 154 #define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */ 155 #define LAS0_DIN_START 0x0124 /* HiSpd DI Sampling Signal select */ 156 #define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */ 157 #define LAS0_ADC_FIFO_CLEAR 0x012c /* A/D FIFO Clear */ 158 #define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */ 159 #define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */ 160 #define LAS0_CG_DATA 0x0138 /* Digital Table Write */ 161 #define LAS0_CGT_ENABLE 0x013c /* Channel Gain Table Enable */ 162 #define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */ 163 #define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */ 164 #define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */ 165 #define LAS0_CGT_CLEAR 0x014c /* Clear Channel Gain Table */ 166 #define LAS0_DAC_CTRL(x) (0x0150 + ((x) * 0x14)) /* D/Ax type/range */ 167 #define LAS0_DAC_SRC(x) (0x0154 + ((x) * 0x14)) /* D/Ax update source */ 168 #define LAS0_DAC_CYCLE(x) (0x0158 + ((x) * 0x14)) /* D/Ax cycle mode */ 169 #define LAS0_DAC_RESET(x) (0x015c + ((x) * 0x14)) /* D/Ax FIFO reset */ 170 #define LAS0_DAC_FIFO_CLEAR(x) (0x0160 + ((x) * 0x14)) /* D/Ax FIFO clear */ 171 #define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */ 172 #define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */ 173 #define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */ 174 #define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */ 175 #define LAS0_SBUS1_SRC 0x018c /* SyncBus 1 Source select */ 176 #define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */ 177 #define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */ 178 #define LAS0_SBUS2_ENABLE 0x019c /* SyncBus 2 enable */ 179 #define LAS0_ETRG_POLARITY 0x01a4 /* Ext. Trigger polarity select */ 180 #define LAS0_EINT_POLARITY 0x01a8 /* Ext. Interrupt polarity select */ 181 #define LAS0_8254_CLK_SEL(x) (0x01ac + ((x) * 0x8)) /* 8254 clock select */ 182 #define LAS0_8254_GATE_SEL(x) (0x01b0 + ((x) * 0x8)) /* 8254 gate select */ 183 #define LAS0_UOUT0_SELECT 0x01c4 /* User Output 0 source select */ 184 #define LAS0_UOUT1_SELECT 0x01c8 /* User Output 1 source select */ 185 #define LAS0_DMA0_RESET 0x01cc /* DMA0 Request state machine reset */ 186 #define LAS0_DMA1_RESET 0x01d0 /* DMA1 Request state machine reset */ 187 188 /* 189 * Local Address Space 1 Offsets 190 */ 191 #define LAS1_ADC_FIFO 0x0000 /* A/D FIFO (16bit) */ 192 #define LAS1_HDIO_FIFO 0x0004 /* HiSpd DI FIFO (16bit) */ 193 #define LAS1_DAC_FIFO(x) (0x0008 + ((x) * 0x4)) /* D/Ax FIFO (16bit) */ 194 195 /* 196 * Driver specific stuff (tunable) 197 */ 198 199 /* 200 * We really only need 2 buffers. More than that means being much 201 * smarter about knowing which ones are full. 202 */ 203 #define DMA_CHAIN_COUNT 2 /* max DMA segments/buffers in a ring (min 2) */ 204 205 /* Target period for periodic transfers. This sets the user read latency. */ 206 /* Note: There are certain rates where we give this up and transfer 1/2 FIFO */ 207 /* If this is too low, efficiency is poor */ 208 #define TRANS_TARGET_PERIOD 10000000 /* 10 ms (in nanoseconds) */ 209 210 /* Set a practical limit on how long a list to support (affects memory use) */ 211 /* The board support a channel list up to the FIFO length (1K or 8K) */ 212 #define RTD_MAX_CHANLIST 128 /* max channel list that we allow */ 213 214 /* 215 * Board specific stuff 216 */ 217 218 #define RTD_CLOCK_RATE 8000000 /* 8Mhz onboard clock */ 219 #define RTD_CLOCK_BASE 125 /* clock period in ns */ 220 221 /* Note: these speed are slower than the spec, but fit the counter resolution*/ 222 #define RTD_MAX_SPEED 1625 /* when sampling, in nanoseconds */ 223 /* max speed if we don't have to wait for settling */ 224 #define RTD_MAX_SPEED_1 875 /* if single channel, in nanoseconds */ 225 226 #define RTD_MIN_SPEED 2097151875 /* (24bit counter) in nanoseconds */ 227 /* min speed when only 1 channel (no burst counter) */ 228 #define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */ 229 230 /* Setup continuous ring of 1/2 FIFO transfers. See RTD manual p91 */ 231 #define DMA_MODE_BITS (\ 232 PLX_LOCAL_BUS_16_WIDE_BITS \ 233 | PLX_DMA_EN_READYIN_BIT \ 234 | PLX_DMA_LOCAL_BURST_EN_BIT \ 235 | PLX_EN_CHAIN_BIT \ 236 | PLX_DMA_INTR_PCI_BIT \ 237 | PLX_LOCAL_ADDR_CONST_BIT \ 238 | PLX_DEMAND_MODE_BIT) 239 240 #define DMA_TRANSFER_BITS (\ 241 /* descriptors in PCI memory*/ PLX_DESC_IN_PCI_BIT \ 242 /* interrupt at end of block */ | PLX_INTR_TERM_COUNT \ 243 /* from board to PCI */ | PLX_XFER_LOCAL_TO_PCI) 244 245 /* 246 * Comedi specific stuff 247 */ 248 249 /* 250 * The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128) 251 */ 252 static const struct comedi_lrange rtd_ai_7520_range = { 253 18, { 254 /* +-5V input range gain steps */ 255 BIP_RANGE(5.0), 256 BIP_RANGE(5.0 / 2), 257 BIP_RANGE(5.0 / 4), 258 BIP_RANGE(5.0 / 8), 259 BIP_RANGE(5.0 / 16), 260 BIP_RANGE(5.0 / 32), 261 /* +-10V input range gain steps */ 262 BIP_RANGE(10.0), 263 BIP_RANGE(10.0 / 2), 264 BIP_RANGE(10.0 / 4), 265 BIP_RANGE(10.0 / 8), 266 BIP_RANGE(10.0 / 16), 267 BIP_RANGE(10.0 / 32), 268 /* +10V input range gain steps */ 269 UNI_RANGE(10.0), 270 UNI_RANGE(10.0 / 2), 271 UNI_RANGE(10.0 / 4), 272 UNI_RANGE(10.0 / 8), 273 UNI_RANGE(10.0 / 16), 274 UNI_RANGE(10.0 / 32), 275 } 276 }; 277 278 /* PCI4520 has two more gains (6 more entries) */ 279 static const struct comedi_lrange rtd_ai_4520_range = { 280 24, { 281 /* +-5V input range gain steps */ 282 BIP_RANGE(5.0), 283 BIP_RANGE(5.0 / 2), 284 BIP_RANGE(5.0 / 4), 285 BIP_RANGE(5.0 / 8), 286 BIP_RANGE(5.0 / 16), 287 BIP_RANGE(5.0 / 32), 288 BIP_RANGE(5.0 / 64), 289 BIP_RANGE(5.0 / 128), 290 /* +-10V input range gain steps */ 291 BIP_RANGE(10.0), 292 BIP_RANGE(10.0 / 2), 293 BIP_RANGE(10.0 / 4), 294 BIP_RANGE(10.0 / 8), 295 BIP_RANGE(10.0 / 16), 296 BIP_RANGE(10.0 / 32), 297 BIP_RANGE(10.0 / 64), 298 BIP_RANGE(10.0 / 128), 299 /* +10V input range gain steps */ 300 UNI_RANGE(10.0), 301 UNI_RANGE(10.0 / 2), 302 UNI_RANGE(10.0 / 4), 303 UNI_RANGE(10.0 / 8), 304 UNI_RANGE(10.0 / 16), 305 UNI_RANGE(10.0 / 32), 306 UNI_RANGE(10.0 / 64), 307 UNI_RANGE(10.0 / 128), 308 } 309 }; 310 311 /* Table order matches range values */ 312 static const struct comedi_lrange rtd_ao_range = { 313 4, { 314 UNI_RANGE(5), 315 UNI_RANGE(10), 316 BIP_RANGE(5), 317 BIP_RANGE(10), 318 } 319 }; 320 321 enum rtd_boardid { 322 BOARD_DM7520, 323 BOARD_PCI4520, 324 }; 325 326 struct rtd_boardinfo { 327 const char *name; 328 int range_bip10; /* start of +-10V range */ 329 int range_uni10; /* start of +10V range */ 330 const struct comedi_lrange *ai_range; 331 }; 332 333 static const struct rtd_boardinfo rtd520_boards[] = { 334 [BOARD_DM7520] = { 335 .name = "DM7520", 336 .range_bip10 = 6, 337 .range_uni10 = 12, 338 .ai_range = &rtd_ai_7520_range, 339 }, 340 [BOARD_PCI4520] = { 341 .name = "PCI4520", 342 .range_bip10 = 8, 343 .range_uni10 = 16, 344 .ai_range = &rtd_ai_4520_range, 345 }, 346 }; 347 348 struct rtd_private { 349 /* memory mapped board structures */ 350 void __iomem *las1; 351 void __iomem *lcfg; 352 353 long ai_count; /* total transfer size (samples) */ 354 int xfer_count; /* # to transfer data. 0->1/2FIFO */ 355 int flags; /* flag event modes */ 356 unsigned int fifosz; 357 358 /* 8254 Timer/Counter gate and clock sources */ 359 unsigned char timer_gate_src[3]; 360 unsigned char timer_clk_src[3]; 361 }; 362 363 /* bit defines for "flags" */ 364 #define SEND_EOS 0x01 /* send End Of Scan events */ 365 #define DMA0_ACTIVE 0x02 /* DMA0 is active */ 366 #define DMA1_ACTIVE 0x04 /* DMA1 is active */ 367 368 /* 369 * Given a desired period and the clock period (both in ns), return the 370 * proper counter value (divider-1). Sets the original period to be the 371 * true value. 372 * Note: you have to check if the value is larger than the counter range! 373 */ 374 static int rtd_ns_to_timer_base(unsigned int *nanosec, 375 unsigned int flags, int base) 376 { 377 int divider; 378 379 switch (flags & CMDF_ROUND_MASK) { 380 case CMDF_ROUND_NEAREST: 381 default: 382 divider = DIV_ROUND_CLOSEST(*nanosec, base); 383 break; 384 case CMDF_ROUND_DOWN: 385 divider = (*nanosec) / base; 386 break; 387 case CMDF_ROUND_UP: 388 divider = DIV_ROUND_UP(*nanosec, base); 389 break; 390 } 391 if (divider < 2) 392 divider = 2; /* min is divide by 2 */ 393 394 /* 395 * Note: we don't check for max, because different timers 396 * have different ranges 397 */ 398 399 *nanosec = base * divider; 400 return divider - 1; /* countdown is divisor+1 */ 401 } 402 403 /* 404 * Given a desired period (in ns), return the proper counter value 405 * (divider-1) for the internal clock. Sets the original period to 406 * be the true value. 407 */ 408 static int rtd_ns_to_timer(unsigned int *ns, unsigned int flags) 409 { 410 return rtd_ns_to_timer_base(ns, flags, RTD_CLOCK_BASE); 411 } 412 413 /* Convert a single comedi channel-gain entry to a RTD520 table entry */ 414 static unsigned short rtd_convert_chan_gain(struct comedi_device *dev, 415 unsigned int chanspec, int index) 416 { 417 const struct rtd_boardinfo *board = dev->board_ptr; 418 unsigned int chan = CR_CHAN(chanspec); 419 unsigned int range = CR_RANGE(chanspec); 420 unsigned int aref = CR_AREF(chanspec); 421 unsigned short r = 0; 422 423 r |= chan & 0xf; 424 425 /* Note: we also setup the channel list bipolar flag array */ 426 if (range < board->range_bip10) { 427 /* +-5 range */ 428 r |= 0x000; 429 r |= (range & 0x7) << 4; 430 } else if (range < board->range_uni10) { 431 /* +-10 range */ 432 r |= 0x100; 433 r |= ((range - board->range_bip10) & 0x7) << 4; 434 } else { 435 /* +10 range */ 436 r |= 0x200; 437 r |= ((range - board->range_uni10) & 0x7) << 4; 438 } 439 440 switch (aref) { 441 case AREF_GROUND: /* on-board ground */ 442 break; 443 444 case AREF_COMMON: 445 r |= 0x80; /* ref external analog common */ 446 break; 447 448 case AREF_DIFF: 449 r |= 0x400; /* differential inputs */ 450 break; 451 452 case AREF_OTHER: /* ??? */ 453 break; 454 } 455 return r; 456 } 457 458 /* Setup the channel-gain table from a comedi list */ 459 static void rtd_load_channelgain_list(struct comedi_device *dev, 460 unsigned int n_chan, unsigned int *list) 461 { 462 if (n_chan > 1) { /* setup channel gain table */ 463 int ii; 464 465 writel(0, dev->mmio + LAS0_CGT_CLEAR); 466 writel(1, dev->mmio + LAS0_CGT_ENABLE); 467 for (ii = 0; ii < n_chan; ii++) { 468 writel(rtd_convert_chan_gain(dev, list[ii], ii), 469 dev->mmio + LAS0_CGT_WRITE); 470 } 471 } else { /* just use the channel gain latch */ 472 writel(0, dev->mmio + LAS0_CGT_ENABLE); 473 writel(rtd_convert_chan_gain(dev, list[0], 0), 474 dev->mmio + LAS0_CGL_WRITE); 475 } 476 } 477 478 /* 479 * Determine fifo size by doing adc conversions until the fifo half 480 * empty status flag clears. 481 */ 482 static int rtd520_probe_fifo_depth(struct comedi_device *dev) 483 { 484 unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND); 485 unsigned int i; 486 static const unsigned int limit = 0x2000; 487 unsigned int fifo_size = 0; 488 489 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); 490 rtd_load_channelgain_list(dev, 1, &chanspec); 491 /* ADC conversion trigger source: SOFTWARE */ 492 writel(0, dev->mmio + LAS0_ADC_CONVERSION); 493 /* convert samples */ 494 for (i = 0; i < limit; ++i) { 495 unsigned int fifo_status; 496 /* trigger conversion */ 497 writew(0, dev->mmio + LAS0_ADC); 498 usleep_range(1, 1000); 499 fifo_status = readl(dev->mmio + LAS0_ADC); 500 if ((fifo_status & FS_ADC_HEMPTY) == 0) { 501 fifo_size = 2 * i; 502 break; 503 } 504 } 505 if (i == limit) { 506 dev_info(dev->class_dev, "failed to probe fifo size.\n"); 507 return -EIO; 508 } 509 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); 510 if (fifo_size != 0x400 && fifo_size != 0x2000) { 511 dev_info(dev->class_dev, 512 "unexpected fifo size of %i, expected 1024 or 8192.\n", 513 fifo_size); 514 return -EIO; 515 } 516 return fifo_size; 517 } 518 519 static int rtd_ai_eoc(struct comedi_device *dev, 520 struct comedi_subdevice *s, 521 struct comedi_insn *insn, 522 unsigned long context) 523 { 524 unsigned int status; 525 526 status = readl(dev->mmio + LAS0_ADC); 527 if (status & FS_ADC_NOT_EMPTY) 528 return 0; 529 return -EBUSY; 530 } 531 532 static int rtd_ai_rinsn(struct comedi_device *dev, 533 struct comedi_subdevice *s, struct comedi_insn *insn, 534 unsigned int *data) 535 { 536 struct rtd_private *devpriv = dev->private; 537 unsigned int range = CR_RANGE(insn->chanspec); 538 int ret; 539 int n; 540 541 /* clear any old fifo data */ 542 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); 543 544 /* write channel to multiplexer and clear channel gain table */ 545 rtd_load_channelgain_list(dev, 1, &insn->chanspec); 546 547 /* ADC conversion trigger source: SOFTWARE */ 548 writel(0, dev->mmio + LAS0_ADC_CONVERSION); 549 550 /* convert n samples */ 551 for (n = 0; n < insn->n; n++) { 552 unsigned short d; 553 /* trigger conversion */ 554 writew(0, dev->mmio + LAS0_ADC); 555 556 ret = comedi_timeout(dev, s, insn, rtd_ai_eoc, 0); 557 if (ret) 558 return ret; 559 560 /* read data */ 561 d = readw(devpriv->las1 + LAS1_ADC_FIFO); 562 d >>= 3; /* low 3 bits are marker lines */ 563 564 /* convert bipolar data to comedi unsigned data */ 565 if (comedi_range_is_bipolar(s, range)) 566 d = comedi_offset_munge(s, d); 567 568 data[n] = d & s->maxdata; 569 } 570 571 /* return the number of samples read/written */ 572 return n; 573 } 574 575 static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, 576 int count) 577 { 578 struct rtd_private *devpriv = dev->private; 579 struct comedi_async *async = s->async; 580 struct comedi_cmd *cmd = &async->cmd; 581 int ii; 582 583 for (ii = 0; ii < count; ii++) { 584 unsigned int range = CR_RANGE(cmd->chanlist[async->cur_chan]); 585 unsigned short d; 586 587 if (devpriv->ai_count == 0) { /* done */ 588 d = readw(devpriv->las1 + LAS1_ADC_FIFO); 589 continue; 590 } 591 592 d = readw(devpriv->las1 + LAS1_ADC_FIFO); 593 d >>= 3; /* low 3 bits are marker lines */ 594 595 /* convert bipolar data to comedi unsigned data */ 596 if (comedi_range_is_bipolar(s, range)) 597 d = comedi_offset_munge(s, d); 598 d &= s->maxdata; 599 600 if (!comedi_buf_write_samples(s, &d, 1)) 601 return -1; 602 603 if (devpriv->ai_count > 0) /* < 0, means read forever */ 604 devpriv->ai_count--; 605 } 606 return 0; 607 } 608 609 static irqreturn_t rtd_interrupt(int irq, void *d) 610 { 611 struct comedi_device *dev = d; 612 struct comedi_subdevice *s = dev->read_subdev; 613 struct rtd_private *devpriv = dev->private; 614 u32 overrun; 615 u16 status; 616 u16 fifo_status; 617 618 if (!dev->attached) 619 return IRQ_NONE; 620 621 fifo_status = readl(dev->mmio + LAS0_ADC); 622 /* check for FIFO full, this automatically halts the ADC! */ 623 if (!(fifo_status & FS_ADC_NOT_FULL)) /* 0 -> full */ 624 goto xfer_abort; 625 626 status = readw(dev->mmio + LAS0_IT); 627 /* if interrupt was not caused by our board, or handled above */ 628 if (status == 0) 629 return IRQ_HANDLED; 630 631 if (status & IRQM_ADC_ABOUT_CNT) { /* sample count -> read FIFO */ 632 /* 633 * since the priority interrupt controller may have queued 634 * a sample counter interrupt, even though we have already 635 * finished, we must handle the possibility that there is 636 * no data here 637 */ 638 if (!(fifo_status & FS_ADC_HEMPTY)) { 639 /* FIFO half full */ 640 if (ai_read_n(dev, s, devpriv->fifosz / 2) < 0) 641 goto xfer_abort; 642 643 if (devpriv->ai_count == 0) 644 goto xfer_done; 645 } else if (devpriv->xfer_count > 0) { 646 if (fifo_status & FS_ADC_NOT_EMPTY) { 647 /* FIFO not empty */ 648 if (ai_read_n(dev, s, devpriv->xfer_count) < 0) 649 goto xfer_abort; 650 651 if (devpriv->ai_count == 0) 652 goto xfer_done; 653 } 654 } 655 } 656 657 overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff; 658 if (overrun) 659 goto xfer_abort; 660 661 /* clear the interrupt */ 662 writew(status, dev->mmio + LAS0_CLEAR); 663 readw(dev->mmio + LAS0_CLEAR); 664 665 comedi_handle_events(dev, s); 666 667 return IRQ_HANDLED; 668 669 xfer_abort: 670 s->async->events |= COMEDI_CB_ERROR; 671 672 xfer_done: 673 s->async->events |= COMEDI_CB_EOA; 674 675 /* clear the interrupt */ 676 status = readw(dev->mmio + LAS0_IT); 677 writew(status, dev->mmio + LAS0_CLEAR); 678 readw(dev->mmio + LAS0_CLEAR); 679 680 fifo_status = readl(dev->mmio + LAS0_ADC); 681 overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff; 682 683 comedi_handle_events(dev, s); 684 685 return IRQ_HANDLED; 686 } 687 688 static int rtd_ai_cmdtest(struct comedi_device *dev, 689 struct comedi_subdevice *s, struct comedi_cmd *cmd) 690 { 691 int err = 0; 692 unsigned int arg; 693 694 /* Step 1 : check if triggers are trivially valid */ 695 696 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW); 697 err |= comedi_check_trigger_src(&cmd->scan_begin_src, 698 TRIG_TIMER | TRIG_EXT); 699 err |= comedi_check_trigger_src(&cmd->convert_src, 700 TRIG_TIMER | TRIG_EXT); 701 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 702 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 703 704 if (err) 705 return 1; 706 707 /* Step 2a : make sure trigger sources are unique */ 708 709 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); 710 err |= comedi_check_trigger_is_unique(cmd->convert_src); 711 err |= comedi_check_trigger_is_unique(cmd->stop_src); 712 713 /* Step 2b : and mutually compatible */ 714 715 if (err) 716 return 2; 717 718 /* Step 3: check if arguments are trivially valid */ 719 720 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); 721 722 if (cmd->scan_begin_src == TRIG_TIMER) { 723 /* Note: these are time periods, not actual rates */ 724 if (cmd->chanlist_len == 1) { /* no scanning */ 725 if (comedi_check_trigger_arg_min(&cmd->scan_begin_arg, 726 RTD_MAX_SPEED_1)) { 727 rtd_ns_to_timer(&cmd->scan_begin_arg, 728 CMDF_ROUND_UP); 729 err |= -EINVAL; 730 } 731 if (comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 732 RTD_MIN_SPEED_1)) { 733 rtd_ns_to_timer(&cmd->scan_begin_arg, 734 CMDF_ROUND_DOWN); 735 err |= -EINVAL; 736 } 737 } else { 738 if (comedi_check_trigger_arg_min(&cmd->scan_begin_arg, 739 RTD_MAX_SPEED)) { 740 rtd_ns_to_timer(&cmd->scan_begin_arg, 741 CMDF_ROUND_UP); 742 err |= -EINVAL; 743 } 744 if (comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 745 RTD_MIN_SPEED)) { 746 rtd_ns_to_timer(&cmd->scan_begin_arg, 747 CMDF_ROUND_DOWN); 748 err |= -EINVAL; 749 } 750 } 751 } else { 752 /* external trigger */ 753 /* should be level/edge, hi/lo specification here */ 754 /* should specify multiple external triggers */ 755 err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 9); 756 } 757 758 if (cmd->convert_src == TRIG_TIMER) { 759 if (cmd->chanlist_len == 1) { /* no scanning */ 760 if (comedi_check_trigger_arg_min(&cmd->convert_arg, 761 RTD_MAX_SPEED_1)) { 762 rtd_ns_to_timer(&cmd->convert_arg, 763 CMDF_ROUND_UP); 764 err |= -EINVAL; 765 } 766 if (comedi_check_trigger_arg_max(&cmd->convert_arg, 767 RTD_MIN_SPEED_1)) { 768 rtd_ns_to_timer(&cmd->convert_arg, 769 CMDF_ROUND_DOWN); 770 err |= -EINVAL; 771 } 772 } else { 773 if (comedi_check_trigger_arg_min(&cmd->convert_arg, 774 RTD_MAX_SPEED)) { 775 rtd_ns_to_timer(&cmd->convert_arg, 776 CMDF_ROUND_UP); 777 err |= -EINVAL; 778 } 779 if (comedi_check_trigger_arg_max(&cmd->convert_arg, 780 RTD_MIN_SPEED)) { 781 rtd_ns_to_timer(&cmd->convert_arg, 782 CMDF_ROUND_DOWN); 783 err |= -EINVAL; 784 } 785 } 786 } else { 787 /* external trigger */ 788 /* see above */ 789 err |= comedi_check_trigger_arg_max(&cmd->convert_arg, 9); 790 } 791 792 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, 793 cmd->chanlist_len); 794 795 if (cmd->stop_src == TRIG_COUNT) 796 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); 797 else /* TRIG_NONE */ 798 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); 799 800 if (err) 801 return 3; 802 803 /* step 4: fix up any arguments */ 804 805 if (cmd->scan_begin_src == TRIG_TIMER) { 806 arg = cmd->scan_begin_arg; 807 rtd_ns_to_timer(&arg, cmd->flags); 808 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg); 809 } 810 811 if (cmd->convert_src == TRIG_TIMER) { 812 arg = cmd->convert_arg; 813 rtd_ns_to_timer(&arg, cmd->flags); 814 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg); 815 816 if (cmd->scan_begin_src == TRIG_TIMER) { 817 arg = cmd->convert_arg * cmd->scan_end_arg; 818 err |= comedi_check_trigger_arg_min( 819 &cmd->scan_begin_arg, arg); 820 } 821 } 822 823 if (err) 824 return 4; 825 826 return 0; 827 } 828 829 static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 830 { 831 struct rtd_private *devpriv = dev->private; 832 struct comedi_cmd *cmd = &s->async->cmd; 833 int timer; 834 835 /* stop anything currently running */ 836 /* pacer stop source: SOFTWARE */ 837 writel(0, dev->mmio + LAS0_PACER_STOP); 838 writel(0, dev->mmio + LAS0_PACER); /* stop pacer */ 839 writel(0, dev->mmio + LAS0_ADC_CONVERSION); 840 writew(0, dev->mmio + LAS0_IT); 841 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); 842 writel(0, dev->mmio + LAS0_OVERRUN); 843 844 /* start configuration */ 845 /* load channel list and reset CGT */ 846 rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist); 847 848 /* setup the common case and override if needed */ 849 if (cmd->chanlist_len > 1) { 850 /* pacer start source: SOFTWARE */ 851 writel(0, dev->mmio + LAS0_PACER_START); 852 /* burst trigger source: PACER */ 853 writel(1, dev->mmio + LAS0_BURST_START); 854 /* ADC conversion trigger source: BURST */ 855 writel(2, dev->mmio + LAS0_ADC_CONVERSION); 856 } else { /* single channel */ 857 /* pacer start source: SOFTWARE */ 858 writel(0, dev->mmio + LAS0_PACER_START); 859 /* ADC conversion trigger source: PACER */ 860 writel(1, dev->mmio + LAS0_ADC_CONVERSION); 861 } 862 writel((devpriv->fifosz / 2 - 1) & 0xffff, dev->mmio + LAS0_ACNT); 863 864 if (cmd->scan_begin_src == TRIG_TIMER) { 865 /* scan_begin_arg is in nanoseconds */ 866 /* find out how many samples to wait before transferring */ 867 if (cmd->flags & CMDF_WAKE_EOS) { 868 /* 869 * this may generate un-sustainable interrupt rates 870 * the application is responsible for doing the 871 * right thing 872 */ 873 devpriv->xfer_count = cmd->chanlist_len; 874 devpriv->flags |= SEND_EOS; 875 } else { 876 /* arrange to transfer data periodically */ 877 devpriv->xfer_count = 878 (TRANS_TARGET_PERIOD * cmd->chanlist_len) / 879 cmd->scan_begin_arg; 880 if (devpriv->xfer_count < cmd->chanlist_len) { 881 /* transfer after each scan (and avoid 0) */ 882 devpriv->xfer_count = cmd->chanlist_len; 883 } else { /* make a multiple of scan length */ 884 devpriv->xfer_count = 885 DIV_ROUND_UP(devpriv->xfer_count, 886 cmd->chanlist_len); 887 devpriv->xfer_count *= cmd->chanlist_len; 888 } 889 devpriv->flags |= SEND_EOS; 890 } 891 if (devpriv->xfer_count >= (devpriv->fifosz / 2)) { 892 /* out of counter range, use 1/2 fifo instead */ 893 devpriv->xfer_count = 0; 894 devpriv->flags &= ~SEND_EOS; 895 } else { 896 /* interrupt for each transfer */ 897 writel((devpriv->xfer_count - 1) & 0xffff, 898 dev->mmio + LAS0_ACNT); 899 } 900 } else { /* unknown timing, just use 1/2 FIFO */ 901 devpriv->xfer_count = 0; 902 devpriv->flags &= ~SEND_EOS; 903 } 904 /* pacer clock source: INTERNAL 8MHz */ 905 writel(1, dev->mmio + LAS0_PACER_SELECT); 906 /* just interrupt, don't stop */ 907 writel(1, dev->mmio + LAS0_ACNT_STOP_ENABLE); 908 909 /* BUG??? these look like enumerated values, but they are bit fields */ 910 911 /* First, setup when to stop */ 912 switch (cmd->stop_src) { 913 case TRIG_COUNT: /* stop after N scans */ 914 devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len; 915 if ((devpriv->xfer_count > 0) && 916 (devpriv->xfer_count > devpriv->ai_count)) { 917 devpriv->xfer_count = devpriv->ai_count; 918 } 919 break; 920 921 case TRIG_NONE: /* stop when cancel is called */ 922 devpriv->ai_count = -1; /* read forever */ 923 break; 924 } 925 926 /* Scan timing */ 927 switch (cmd->scan_begin_src) { 928 case TRIG_TIMER: /* periodic scanning */ 929 timer = rtd_ns_to_timer(&cmd->scan_begin_arg, 930 CMDF_ROUND_NEAREST); 931 /* set PACER clock */ 932 writel(timer & 0xffffff, dev->mmio + LAS0_PCLK); 933 934 break; 935 936 case TRIG_EXT: 937 /* pacer start source: EXTERNAL */ 938 writel(1, dev->mmio + LAS0_PACER_START); 939 break; 940 } 941 942 /* Sample timing within a scan */ 943 switch (cmd->convert_src) { 944 case TRIG_TIMER: /* periodic */ 945 if (cmd->chanlist_len > 1) { 946 /* only needed for multi-channel */ 947 timer = rtd_ns_to_timer(&cmd->convert_arg, 948 CMDF_ROUND_NEAREST); 949 /* setup BURST clock */ 950 writel(timer & 0x3ff, dev->mmio + LAS0_BCLK); 951 } 952 953 break; 954 955 case TRIG_EXT: /* external */ 956 /* burst trigger source: EXTERNAL */ 957 writel(2, dev->mmio + LAS0_BURST_START); 958 break; 959 } 960 /* end configuration */ 961 962 /* 963 * This doesn't seem to work. There is no way to clear an interrupt 964 * that the priority controller has queued! 965 */ 966 writew(~0, dev->mmio + LAS0_CLEAR); 967 readw(dev->mmio + LAS0_CLEAR); 968 969 /* TODO: allow multiple interrupt sources */ 970 /* transfer every N samples */ 971 writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT); 972 973 /* BUG: start_src is ASSUMED to be TRIG_NOW */ 974 /* BUG? it seems like things are running before the "start" */ 975 readl(dev->mmio + LAS0_PACER); /* start pacer */ 976 return 0; 977 } 978 979 static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 980 { 981 struct rtd_private *devpriv = dev->private; 982 983 /* pacer stop source: SOFTWARE */ 984 writel(0, dev->mmio + LAS0_PACER_STOP); 985 writel(0, dev->mmio + LAS0_PACER); /* stop pacer */ 986 writel(0, dev->mmio + LAS0_ADC_CONVERSION); 987 writew(0, dev->mmio + LAS0_IT); 988 devpriv->ai_count = 0; /* stop and don't transfer any more */ 989 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); 990 return 0; 991 } 992 993 static int rtd_ao_eoc(struct comedi_device *dev, 994 struct comedi_subdevice *s, 995 struct comedi_insn *insn, 996 unsigned long context) 997 { 998 unsigned int chan = CR_CHAN(insn->chanspec); 999 unsigned int bit = (chan == 0) ? FS_DAC1_NOT_EMPTY : FS_DAC2_NOT_EMPTY; 1000 unsigned int status; 1001 1002 status = readl(dev->mmio + LAS0_ADC); 1003 if (status & bit) 1004 return 0; 1005 return -EBUSY; 1006 } 1007 1008 static int rtd_ao_insn_write(struct comedi_device *dev, 1009 struct comedi_subdevice *s, 1010 struct comedi_insn *insn, 1011 unsigned int *data) 1012 { 1013 struct rtd_private *devpriv = dev->private; 1014 unsigned int chan = CR_CHAN(insn->chanspec); 1015 unsigned int range = CR_RANGE(insn->chanspec); 1016 int ret; 1017 int i; 1018 1019 /* Configure the output range (table index matches the range values) */ 1020 writew(range & 7, dev->mmio + LAS0_DAC_CTRL(chan)); 1021 1022 for (i = 0; i < insn->n; ++i) { 1023 unsigned int val = data[i]; 1024 1025 /* bipolar uses 2's complement values with an extended sign */ 1026 if (comedi_range_is_bipolar(s, range)) { 1027 val = comedi_offset_munge(s, val); 1028 val |= (val & ((s->maxdata + 1) >> 1)) << 1; 1029 } 1030 1031 /* shift the 12-bit data (+ sign) to match the register */ 1032 val <<= 3; 1033 1034 writew(val, devpriv->las1 + LAS1_DAC_FIFO(chan)); 1035 writew(0, dev->mmio + LAS0_UPDATE_DAC(chan)); 1036 1037 ret = comedi_timeout(dev, s, insn, rtd_ao_eoc, 0); 1038 if (ret) 1039 return ret; 1040 1041 s->readback[chan] = data[i]; 1042 } 1043 1044 return insn->n; 1045 } 1046 1047 static int rtd_dio_insn_bits(struct comedi_device *dev, 1048 struct comedi_subdevice *s, 1049 struct comedi_insn *insn, 1050 unsigned int *data) 1051 { 1052 if (comedi_dio_update_state(s, data)) 1053 writew(s->state & 0xff, dev->mmio + LAS0_DIO0); 1054 1055 data[1] = readw(dev->mmio + LAS0_DIO0) & 0xff; 1056 1057 return insn->n; 1058 } 1059 1060 static int rtd_dio_insn_config(struct comedi_device *dev, 1061 struct comedi_subdevice *s, 1062 struct comedi_insn *insn, 1063 unsigned int *data) 1064 { 1065 int ret; 1066 1067 ret = comedi_dio_insn_config(dev, s, insn, data, 0); 1068 if (ret) 1069 return ret; 1070 1071 /* TODO support digital match interrupts and strobes */ 1072 1073 /* set direction */ 1074 writew(0x01, dev->mmio + LAS0_DIO_STATUS); 1075 writew(s->io_bits & 0xff, dev->mmio + LAS0_DIO0_CTRL); 1076 1077 /* clear interrupts */ 1078 writew(0x00, dev->mmio + LAS0_DIO_STATUS); 1079 1080 /* port1 can only be all input or all output */ 1081 1082 /* there are also 2 user input lines and 2 user output lines */ 1083 1084 return insn->n; 1085 } 1086 1087 static int rtd_counter_insn_config(struct comedi_device *dev, 1088 struct comedi_subdevice *s, 1089 struct comedi_insn *insn, 1090 unsigned int *data) 1091 { 1092 struct rtd_private *devpriv = dev->private; 1093 unsigned int chan = CR_CHAN(insn->chanspec); 1094 unsigned int max_src; 1095 unsigned int src; 1096 1097 switch (data[0]) { 1098 case INSN_CONFIG_SET_GATE_SRC: 1099 /* 1100 * 8254 Timer/Counter gate sources: 1101 * 1102 * 0 = Not gated, free running (reset state) 1103 * 1 = Gated, off 1104 * 2 = Ext. TC Gate 1 1105 * 3 = Ext. TC Gate 2 1106 * 4 = Previous TC out (chan 1 and 2 only) 1107 */ 1108 src = data[2]; 1109 max_src = (chan == 0) ? 3 : 4; 1110 if (src > max_src) 1111 return -EINVAL; 1112 1113 devpriv->timer_gate_src[chan] = src; 1114 writeb(src, dev->mmio + LAS0_8254_GATE_SEL(chan)); 1115 break; 1116 case INSN_CONFIG_GET_GATE_SRC: 1117 data[2] = devpriv->timer_gate_src[chan]; 1118 break; 1119 case INSN_CONFIG_SET_CLOCK_SRC: 1120 /* 1121 * 8254 Timer/Counter clock sources: 1122 * 1123 * 0 = 8 MHz (reset state) 1124 * 1 = Ext. TC Clock 1 1125 * 2 = Ext. TX Clock 2 1126 * 3 = Ext. Pacer Clock 1127 * 4 = Previous TC out (chan 1 and 2 only) 1128 * 5 = High-Speed Digital Input Sampling signal (chan 1 only) 1129 */ 1130 src = data[1]; 1131 switch (chan) { 1132 case 0: 1133 max_src = 3; 1134 break; 1135 case 1: 1136 max_src = 5; 1137 break; 1138 case 2: 1139 max_src = 4; 1140 break; 1141 default: 1142 return -EINVAL; 1143 } 1144 if (src > max_src) 1145 return -EINVAL; 1146 1147 devpriv->timer_clk_src[chan] = src; 1148 writeb(src, dev->mmio + LAS0_8254_CLK_SEL(chan)); 1149 break; 1150 case INSN_CONFIG_GET_CLOCK_SRC: 1151 src = devpriv->timer_clk_src[chan]; 1152 data[1] = devpriv->timer_clk_src[chan]; 1153 data[2] = (src == 0) ? RTD_CLOCK_BASE : 0; 1154 break; 1155 default: 1156 return -EINVAL; 1157 } 1158 1159 return insn->n; 1160 } 1161 1162 static void rtd_reset(struct comedi_device *dev) 1163 { 1164 struct rtd_private *devpriv = dev->private; 1165 1166 writel(0, dev->mmio + LAS0_BOARD_RESET); 1167 usleep_range(100, 1000); /* needed? */ 1168 writel(0, devpriv->lcfg + PLX_REG_INTCSR); 1169 writew(0, dev->mmio + LAS0_IT); 1170 writew(~0, dev->mmio + LAS0_CLEAR); 1171 readw(dev->mmio + LAS0_CLEAR); 1172 } 1173 1174 /* 1175 * initialize board, per RTD spec 1176 * also, initialize shadow registers 1177 */ 1178 static void rtd_init_board(struct comedi_device *dev) 1179 { 1180 rtd_reset(dev); 1181 1182 writel(0, dev->mmio + LAS0_OVERRUN); 1183 writel(0, dev->mmio + LAS0_CGT_CLEAR); 1184 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR); 1185 writel(0, dev->mmio + LAS0_DAC_RESET(0)); 1186 writel(0, dev->mmio + LAS0_DAC_RESET(1)); 1187 /* clear digital IO fifo */ 1188 writew(0, dev->mmio + LAS0_DIO_STATUS); 1189 /* TODO: set user out source ??? */ 1190 } 1191 1192 /* The RTD driver does this */ 1193 static void rtd_pci_latency_quirk(struct comedi_device *dev, 1194 struct pci_dev *pcidev) 1195 { 1196 unsigned char pci_latency; 1197 1198 pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency); 1199 if (pci_latency < 32) { 1200 dev_info(dev->class_dev, 1201 "PCI latency changed from %d to %d\n", 1202 pci_latency, 32); 1203 pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32); 1204 } 1205 } 1206 1207 static int rtd_auto_attach(struct comedi_device *dev, 1208 unsigned long context) 1209 { 1210 struct pci_dev *pcidev = comedi_to_pci_dev(dev); 1211 const struct rtd_boardinfo *board = NULL; 1212 struct rtd_private *devpriv; 1213 struct comedi_subdevice *s; 1214 int ret; 1215 1216 if (context < ARRAY_SIZE(rtd520_boards)) 1217 board = &rtd520_boards[context]; 1218 if (!board) 1219 return -ENODEV; 1220 dev->board_ptr = board; 1221 dev->board_name = board->name; 1222 1223 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 1224 if (!devpriv) 1225 return -ENOMEM; 1226 1227 ret = comedi_pci_enable(dev); 1228 if (ret) 1229 return ret; 1230 1231 dev->mmio = pci_ioremap_bar(pcidev, 2); 1232 devpriv->las1 = pci_ioremap_bar(pcidev, 3); 1233 devpriv->lcfg = pci_ioremap_bar(pcidev, 0); 1234 if (!dev->mmio || !devpriv->las1 || !devpriv->lcfg) 1235 return -ENOMEM; 1236 1237 rtd_pci_latency_quirk(dev, pcidev); 1238 1239 if (pcidev->irq) { 1240 ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED, 1241 dev->board_name, dev); 1242 if (ret == 0) 1243 dev->irq = pcidev->irq; 1244 } 1245 1246 ret = comedi_alloc_subdevices(dev, 4); 1247 if (ret) 1248 return ret; 1249 1250 s = &dev->subdevices[0]; 1251 /* analog input subdevice */ 1252 s->type = COMEDI_SUBD_AI; 1253 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF; 1254 s->n_chan = 16; 1255 s->maxdata = 0x0fff; 1256 s->range_table = board->ai_range; 1257 s->len_chanlist = RTD_MAX_CHANLIST; 1258 s->insn_read = rtd_ai_rinsn; 1259 if (dev->irq) { 1260 dev->read_subdev = s; 1261 s->subdev_flags |= SDF_CMD_READ; 1262 s->do_cmd = rtd_ai_cmd; 1263 s->do_cmdtest = rtd_ai_cmdtest; 1264 s->cancel = rtd_ai_cancel; 1265 } 1266 1267 s = &dev->subdevices[1]; 1268 /* analog output subdevice */ 1269 s->type = COMEDI_SUBD_AO; 1270 s->subdev_flags = SDF_WRITABLE; 1271 s->n_chan = 2; 1272 s->maxdata = 0x0fff; 1273 s->range_table = &rtd_ao_range; 1274 s->insn_write = rtd_ao_insn_write; 1275 1276 ret = comedi_alloc_subdev_readback(s); 1277 if (ret) 1278 return ret; 1279 1280 s = &dev->subdevices[2]; 1281 /* digital i/o subdevice */ 1282 s->type = COMEDI_SUBD_DIO; 1283 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 1284 /* we only support port 0 right now. Ignoring port 1 and user IO */ 1285 s->n_chan = 8; 1286 s->maxdata = 1; 1287 s->range_table = &range_digital; 1288 s->insn_bits = rtd_dio_insn_bits; 1289 s->insn_config = rtd_dio_insn_config; 1290 1291 /* 8254 Timer/Counter subdevice */ 1292 s = &dev->subdevices[3]; 1293 dev->pacer = comedi_8254_mm_init(dev->mmio + LAS0_8254_TIMER_BASE, 1294 RTD_CLOCK_BASE, I8254_IO8, 2); 1295 if (!dev->pacer) 1296 return -ENOMEM; 1297 1298 comedi_8254_subdevice_init(s, dev->pacer); 1299 dev->pacer->insn_config = rtd_counter_insn_config; 1300 1301 rtd_init_board(dev); 1302 1303 ret = rtd520_probe_fifo_depth(dev); 1304 if (ret < 0) 1305 return ret; 1306 devpriv->fifosz = ret; 1307 1308 if (dev->irq) 1309 writel(PLX_INTCSR_PIEN | PLX_INTCSR_PLIEN, 1310 devpriv->lcfg + PLX_REG_INTCSR); 1311 1312 return 0; 1313 } 1314 1315 static void rtd_detach(struct comedi_device *dev) 1316 { 1317 struct rtd_private *devpriv = dev->private; 1318 1319 if (devpriv) { 1320 /* Shut down any board ops by resetting it */ 1321 if (dev->mmio && devpriv->lcfg) 1322 rtd_reset(dev); 1323 if (dev->irq) 1324 free_irq(dev->irq, dev); 1325 if (dev->mmio) 1326 iounmap(dev->mmio); 1327 if (devpriv->las1) 1328 iounmap(devpriv->las1); 1329 if (devpriv->lcfg) 1330 iounmap(devpriv->lcfg); 1331 } 1332 comedi_pci_disable(dev); 1333 } 1334 1335 static struct comedi_driver rtd520_driver = { 1336 .driver_name = "rtd520", 1337 .module = THIS_MODULE, 1338 .auto_attach = rtd_auto_attach, 1339 .detach = rtd_detach, 1340 }; 1341 1342 static int rtd520_pci_probe(struct pci_dev *dev, 1343 const struct pci_device_id *id) 1344 { 1345 return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data); 1346 } 1347 1348 static const struct pci_device_id rtd520_pci_table[] = { 1349 { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 }, 1350 { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 }, 1351 { 0 } 1352 }; 1353 MODULE_DEVICE_TABLE(pci, rtd520_pci_table); 1354 1355 static struct pci_driver rtd520_pci_driver = { 1356 .name = "rtd520", 1357 .id_table = rtd520_pci_table, 1358 .probe = rtd520_pci_probe, 1359 .remove = comedi_pci_auto_unconfig, 1360 }; 1361 module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver); 1362 1363 MODULE_AUTHOR("Comedi https://www.comedi.org"); 1364 MODULE_DESCRIPTION("Comedi low-level driver"); 1365 MODULE_LICENSE("GPL"); 1366