1/* 2 * comedi/drivers/amplc_pci230.c 3 * Driver for Amplicon PCI230 and PCI260 Multifunction I/O boards. 4 * 5 * Copyright (C) 2001 Allan Willcox <allanwillcox@ozemail.com.au> 6 * 7 * COMEDI - Linux Control and Measurement Device Interface 8 * Copyright (C) 2000 David A. Schleef <ds@schleef.org> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 */ 20 21/* 22 * Driver: amplc_pci230 23 * Description: Amplicon PCI230, PCI260 Multifunction I/O boards 24 * Author: Allan Willcox <allanwillcox@ozemail.com.au>, 25 * Steve D Sharples <steve.sharples@nottingham.ac.uk>, 26 * Ian Abbott <abbotti@mev.co.uk> 27 * Updated: Mon, 01 Sep 2014 10:09:16 +0000 28 * Devices: [Amplicon] PCI230 (amplc_pci230), PCI230+, PCI260, PCI260+ 29 * Status: works 30 * 31 * Configuration options: 32 * none 33 * 34 * Manual configuration of PCI cards is not supported; they are configured 35 * automatically. 36 * 37 * The PCI230+ and PCI260+ have the same PCI device IDs as the PCI230 and 38 * PCI260, but can be distinguished by the the size of the PCI regions. A 39 * card will be configured as a "+" model if detected as such. 40 * 41 * Subdevices: 42 * 43 * PCI230(+) PCI260(+) 44 * --------- --------- 45 * Subdevices 3 1 46 * 0 AI AI 47 * 1 AO 48 * 2 DIO 49 * 50 * AI Subdevice: 51 * 52 * The AI subdevice has 16 single-ended channels or 8 differential 53 * channels. 54 * 55 * The PCI230 and PCI260 cards have 12-bit resolution. The PCI230+ and 56 * PCI260+ cards have 16-bit resolution. 57 * 58 * For differential mode, use inputs 2N and 2N+1 for channel N (e.g. use 59 * inputs 14 and 15 for channel 7). If the card is physically a PCI230 60 * or PCI260 then it actually uses a "pseudo-differential" mode where the 61 * inputs are sampled a few microseconds apart. The PCI230+ and PCI260+ 62 * use true differential sampling. Another difference is that if the 63 * card is physically a PCI230 or PCI260, the inverting input is 2N, 64 * whereas for a PCI230+ or PCI260+ the inverting input is 2N+1. So if a 65 * PCI230 is physically replaced by a PCI230+ (or a PCI260 with a 66 * PCI260+) and differential mode is used, the differential inputs need 67 * to be physically swapped on the connector. 68 * 69 * The following input ranges are supported: 70 * 71 * 0 => [-10, +10] V 72 * 1 => [-5, +5] V 73 * 2 => [-2.5, +2.5] V 74 * 3 => [-1.25, +1.25] V 75 * 4 => [0, 10] V 76 * 5 => [0, 5] V 77 * 6 => [0, 2.5] V 78 * 79 * AI Commands: 80 * 81 * +=========+==============+===========+============+==========+ 82 * |start_src|scan_begin_src|convert_src|scan_end_src| stop_src | 83 * +=========+==============+===========+============+==========+ 84 * |TRIG_NOW | TRIG_FOLLOW |TRIG_TIMER | TRIG_COUNT |TRIG_NONE | 85 * |TRIG_INT | |TRIG_EXT(3)| |TRIG_COUNT| 86 * | | |TRIG_INT | | | 87 * | |--------------|-----------| | | 88 * | | TRIG_TIMER(1)|TRIG_TIMER | | | 89 * | | TRIG_EXT(2) | | | | 90 * | | TRIG_INT | | | | 91 * +---------+--------------+-----------+------------+----------+ 92 * 93 * Note 1: If AI command and AO command are used simultaneously, only 94 * one may have scan_begin_src == TRIG_TIMER. 95 * 96 * Note 2: For PCI230 and PCI230+, scan_begin_src == TRIG_EXT uses 97 * DIO channel 16 (pin 49) which will need to be configured as 98 * a digital input. For PCI260+, the EXTTRIG/EXTCONVCLK input 99 * (pin 17) is used instead. For PCI230, scan_begin_src == 100 * TRIG_EXT is not supported. The trigger is a rising edge 101 * on the input. 102 * 103 * Note 3: For convert_src == TRIG_EXT, the EXTTRIG/EXTCONVCLK input 104 * (pin 25 on PCI230(+), pin 17 on PCI260(+)) is used. The 105 * convert_arg value is interpreted as follows: 106 * 107 * convert_arg == (CR_EDGE | 0) => rising edge 108 * convert_arg == (CR_EDGE | CR_INVERT | 0) => falling edge 109 * convert_arg == 0 => falling edge (backwards compatibility) 110 * convert_arg == 1 => rising edge (backwards compatibility) 111 * 112 * All entries in the channel list must use the same analogue reference. 113 * If the analogue reference is not AREF_DIFF (not differential) each 114 * pair of channel numbers (0 and 1, 2 and 3, etc.) must use the same 115 * input range. The input ranges used in the sequence must be all 116 * bipolar (ranges 0 to 3) or all unipolar (ranges 4 to 6). The channel 117 * sequence must consist of 1 or more identical subsequences. Within the 118 * subsequence, channels must be in ascending order with no repeated 119 * channels. For example, the following sequences are valid: 0 1 2 3 120 * (single valid subsequence), 0 2 3 5 0 2 3 5 (repeated valid 121 * subsequence), 1 1 1 1 (repeated valid subsequence). The following 122 * sequences are invalid: 0 3 2 1 (invalid subsequence), 0 2 3 5 0 2 3 123 * (incompletely repeated subsequence). Some versions of the PCI230+ and 124 * PCI260+ have a bug that requires a subsequence longer than one entry 125 * long to include channel 0. 126 * 127 * AO Subdevice: 128 * 129 * The AO subdevice has 2 channels with 12-bit resolution. 130 * The following output ranges are supported: 131 * 0 => [0, 10] V 132 * 1 => [-10, +10] V 133 * 134 * AO Commands: 135 * 136 * +=========+==============+===========+============+==========+ 137 * |start_src|scan_begin_src|convert_src|scan_end_src| stop_src | 138 * +=========+==============+===========+============+==========+ 139 * |TRIG_INT | TRIG_TIMER(1)| TRIG_NOW | TRIG_COUNT |TRIG_NONE | 140 * | | TRIG_EXT(2) | | |TRIG_COUNT| 141 * | | TRIG_INT | | | | 142 * +---------+--------------+-----------+------------+----------+ 143 * 144 * Note 1: If AI command and AO command are used simultaneously, only 145 * one may have scan_begin_src == TRIG_TIMER. 146 * 147 * Note 2: scan_begin_src == TRIG_EXT is only supported if the card is 148 * configured as a PCI230+ and is only supported on later 149 * versions of the card. As a card configured as a PCI230+ is 150 * not guaranteed to support external triggering, please consider 151 * this support to be a bonus. It uses the EXTTRIG/ EXTCONVCLK 152 * input (PCI230+ pin 25). Triggering will be on the rising edge 153 * unless the CR_INVERT flag is set in scan_begin_arg. 154 * 155 * The channels in the channel sequence must be in ascending order with 156 * no repeats. All entries in the channel sequence must use the same 157 * output range. 158 * 159 * DIO Subdevice: 160 * 161 * The DIO subdevice is a 8255 chip providing 24 DIO channels. The DIO 162 * channels are configurable as inputs or outputs in four groups: 163 * 164 * Port A - channels 0 to 7 165 * Port B - channels 8 to 15 166 * Port CL - channels 16 to 19 167 * Port CH - channels 20 to 23 168 * 169 * Only mode 0 of the 8255 chip is supported. 170 * 171 * Bit 0 of port C (DIO channel 16) is also used as an external scan 172 * trigger input for AI commands on PCI230 and PCI230+, so would need to 173 * be configured as an input to use it for that purpose. 174 */ 175 176/* 177 * Extra triggered scan functionality, interrupt bug-fix added by Steve 178 * Sharples. Support for PCI230+/260+, more triggered scan functionality, 179 * and workarounds for (or detection of) various hardware problems added 180 * by Ian Abbott. 181 */ 182 183#include <linux/module.h> 184#include <linux/pci.h> 185#include <linux/delay.h> 186#include <linux/interrupt.h> 187 188#include "../comedidev.h" 189 190#include "comedi_fc.h" 191#include "8253.h" 192#include "8255.h" 193 194/* 195 * PCI230 PCI configuration register information 196 */ 197#define PCI_DEVICE_ID_PCI230 0x0000 198#define PCI_DEVICE_ID_PCI260 0x0006 199 200/* 201 * PCI230 i/o space 1 registers. 202 */ 203#define PCI230_PPI_X_BASE 0x00 /* User PPI (82C55) base */ 204#define PCI230_PPI_X_A 0x00 /* User PPI (82C55) port A */ 205#define PCI230_PPI_X_B 0x01 /* User PPI (82C55) port B */ 206#define PCI230_PPI_X_C 0x02 /* User PPI (82C55) port C */ 207#define PCI230_PPI_X_CMD 0x03 /* User PPI (82C55) control word */ 208#define PCI230_Z2_CT_BASE 0x14 /* 82C54 counter/timer base */ 209#define PCI230_Z2_CT0 0x14 /* 82C54 counter/timer 0 */ 210#define PCI230_Z2_CT1 0x15 /* 82C54 counter/timer 1 */ 211#define PCI230_Z2_CT2 0x16 /* 82C54 counter/timer 2 */ 212#define PCI230_Z2_CTC 0x17 /* 82C54 counter/timer control word */ 213#define PCI230_ZCLK_SCE 0x1A /* Group Z Clock Configuration */ 214#define PCI230_ZGAT_SCE 0x1D /* Group Z Gate Configuration */ 215#define PCI230_INT_SCE 0x1E /* Interrupt source mask (w) */ 216#define PCI230_INT_STAT 0x1E /* Interrupt status (r) */ 217 218/* 219 * PCI230 i/o space 2 registers. 220 */ 221#define PCI230_DACCON 0x00 /* DAC control */ 222#define PCI230_DACOUT1 0x02 /* DAC channel 0 (w) */ 223#define PCI230_DACOUT2 0x04 /* DAC channel 1 (w) (not FIFO mode) */ 224#define PCI230_ADCDATA 0x08 /* ADC data (r) */ 225#define PCI230_ADCSWTRIG 0x08 /* ADC software trigger (w) */ 226#define PCI230_ADCCON 0x0A /* ADC control */ 227#define PCI230_ADCEN 0x0C /* ADC channel enable bits */ 228#define PCI230_ADCG 0x0E /* ADC gain control bits */ 229/* PCI230+ i/o space 2 additional registers. */ 230#define PCI230P_ADCTRIG 0x10 /* ADC start acquisition trigger */ 231#define PCI230P_ADCTH 0x12 /* ADC analog trigger threshold */ 232#define PCI230P_ADCFFTH 0x14 /* ADC FIFO interrupt threshold */ 233#define PCI230P_ADCFFLEV 0x16 /* ADC FIFO level (r) */ 234#define PCI230P_ADCPTSC 0x18 /* ADC pre-trigger sample count (r) */ 235#define PCI230P_ADCHYST 0x1A /* ADC analog trigger hysteresys */ 236#define PCI230P_EXTFUNC 0x1C /* Extended functions */ 237#define PCI230P_HWVER 0x1E /* Hardware version (r) */ 238/* PCI230+ hardware version 2 onwards. */ 239#define PCI230P2_DACDATA 0x02 /* DAC data (FIFO mode) (w) */ 240#define PCI230P2_DACSWTRIG 0x02 /* DAC soft trigger (FIFO mode) (r) */ 241#define PCI230P2_DACEN 0x06 /* DAC channel enable (FIFO mode) */ 242 243/* 244 * DACCON read-write values. 245 */ 246#define PCI230_DAC_OR_UNI (0 << 0) /* Output range unipolar */ 247#define PCI230_DAC_OR_BIP (1 << 0) /* Output range bipolar */ 248#define PCI230_DAC_OR_MASK (1 << 0) 249/* 250 * The following applies only if DAC FIFO support is enabled in the EXTFUNC 251 * register (and only for PCI230+ hardware version 2 onwards). 252 */ 253#define PCI230P2_DAC_FIFO_EN (1 << 8) /* FIFO enable */ 254/* 255 * The following apply only if the DAC FIFO is enabled (and only for PCI230+ 256 * hardware version 2 onwards). 257 */ 258#define PCI230P2_DAC_TRIG_NONE (0 << 2) /* No trigger */ 259#define PCI230P2_DAC_TRIG_SW (1 << 2) /* Software trigger trigger */ 260#define PCI230P2_DAC_TRIG_EXTP (2 << 2) /* EXTTRIG +ve edge trigger */ 261#define PCI230P2_DAC_TRIG_EXTN (3 << 2) /* EXTTRIG -ve edge trigger */ 262#define PCI230P2_DAC_TRIG_Z2CT0 (4 << 2) /* CT0-OUT +ve edge trigger */ 263#define PCI230P2_DAC_TRIG_Z2CT1 (5 << 2) /* CT1-OUT +ve edge trigger */ 264#define PCI230P2_DAC_TRIG_Z2CT2 (6 << 2) /* CT2-OUT +ve edge trigger */ 265#define PCI230P2_DAC_TRIG_MASK (7 << 2) 266#define PCI230P2_DAC_FIFO_WRAP (1 << 7) /* FIFO wraparound mode */ 267#define PCI230P2_DAC_INT_FIFO_EMPTY (0 << 9) /* FIFO interrupt empty */ 268#define PCI230P2_DAC_INT_FIFO_NEMPTY (1 << 9) 269#define PCI230P2_DAC_INT_FIFO_NHALF (2 << 9) /* FIFO intr not half full */ 270#define PCI230P2_DAC_INT_FIFO_HALF (3 << 9) 271#define PCI230P2_DAC_INT_FIFO_NFULL (4 << 9) /* FIFO interrupt not full */ 272#define PCI230P2_DAC_INT_FIFO_FULL (5 << 9) 273#define PCI230P2_DAC_INT_FIFO_MASK (7 << 9) 274 275/* 276 * DACCON read-only values. 277 */ 278#define PCI230_DAC_BUSY (1 << 1) /* DAC busy. */ 279/* 280 * The following apply only if the DAC FIFO is enabled (and only for PCI230+ 281 * hardware version 2 onwards). 282 */ 283#define PCI230P2_DAC_FIFO_UNDERRUN_LATCHED (1 << 5) /* Underrun error */ 284#define PCI230P2_DAC_FIFO_EMPTY (1 << 13) /* FIFO empty */ 285#define PCI230P2_DAC_FIFO_FULL (1 << 14) /* FIFO full */ 286#define PCI230P2_DAC_FIFO_HALF (1 << 15) /* FIFO half full */ 287 288/* 289 * DACCON write-only, transient values. 290 */ 291/* 292 * The following apply only if the DAC FIFO is enabled (and only for PCI230+ 293 * hardware version 2 onwards). 294 */ 295#define PCI230P2_DAC_FIFO_UNDERRUN_CLEAR (1 << 5) /* Clear underrun */ 296#define PCI230P2_DAC_FIFO_RESET (1 << 12) /* FIFO reset */ 297 298/* 299 * PCI230+ hardware version 2 DAC FIFO levels. 300 */ 301#define PCI230P2_DAC_FIFOLEVEL_HALF 512 302#define PCI230P2_DAC_FIFOLEVEL_FULL 1024 303/* Free space in DAC FIFO. */ 304#define PCI230P2_DAC_FIFOROOM_EMPTY PCI230P2_DAC_FIFOLEVEL_FULL 305#define PCI230P2_DAC_FIFOROOM_ONETOHALF \ 306 (PCI230P2_DAC_FIFOLEVEL_FULL - PCI230P2_DAC_FIFOLEVEL_HALF) 307#define PCI230P2_DAC_FIFOROOM_HALFTOFULL 1 308#define PCI230P2_DAC_FIFOROOM_FULL 0 309 310/* 311 * ADCCON read/write values. 312 */ 313#define PCI230_ADC_TRIG_NONE (0 << 0) /* No trigger */ 314#define PCI230_ADC_TRIG_SW (1 << 0) /* Software trigger trigger */ 315#define PCI230_ADC_TRIG_EXTP (2 << 0) /* EXTTRIG +ve edge trigger */ 316#define PCI230_ADC_TRIG_EXTN (3 << 0) /* EXTTRIG -ve edge trigger */ 317#define PCI230_ADC_TRIG_Z2CT0 (4 << 0) /* CT0-OUT +ve edge trigger */ 318#define PCI230_ADC_TRIG_Z2CT1 (5 << 0) /* CT1-OUT +ve edge trigger */ 319#define PCI230_ADC_TRIG_Z2CT2 (6 << 0) /* CT2-OUT +ve edge trigger */ 320#define PCI230_ADC_TRIG_MASK (7 << 0) 321#define PCI230_ADC_IR_UNI (0 << 3) /* Input range unipolar */ 322#define PCI230_ADC_IR_BIP (1 << 3) /* Input range bipolar */ 323#define PCI230_ADC_IR_MASK (1 << 3) 324#define PCI230_ADC_IM_SE (0 << 4) /* Input mode single ended */ 325#define PCI230_ADC_IM_DIF (1 << 4) /* Input mode differential */ 326#define PCI230_ADC_IM_MASK (1 << 4) 327#define PCI230_ADC_FIFO_EN (1 << 8) /* FIFO enable */ 328#define PCI230_ADC_INT_FIFO_EMPTY (0 << 9) 329#define PCI230_ADC_INT_FIFO_NEMPTY (1 << 9) /* FIFO interrupt not empty */ 330#define PCI230_ADC_INT_FIFO_NHALF (2 << 9) 331#define PCI230_ADC_INT_FIFO_HALF (3 << 9) /* FIFO interrupt half full */ 332#define PCI230_ADC_INT_FIFO_NFULL (4 << 9) 333#define PCI230_ADC_INT_FIFO_FULL (5 << 9) /* FIFO interrupt full */ 334#define PCI230P_ADC_INT_FIFO_THRESH (7 << 9) /* FIFO interrupt threshold */ 335#define PCI230_ADC_INT_FIFO_MASK (7 << 9) 336 337/* 338 * ADCCON write-only, transient values. 339 */ 340#define PCI230_ADC_FIFO_RESET (1 << 12) /* FIFO reset */ 341#define PCI230_ADC_GLOB_RESET (1 << 13) /* Global reset */ 342 343/* 344 * ADCCON read-only values. 345 */ 346#define PCI230_ADC_BUSY (1 << 15) /* ADC busy */ 347#define PCI230_ADC_FIFO_EMPTY (1 << 12) /* FIFO empty */ 348#define PCI230_ADC_FIFO_FULL (1 << 13) /* FIFO full */ 349#define PCI230_ADC_FIFO_HALF (1 << 14) /* FIFO half full */ 350#define PCI230_ADC_FIFO_FULL_LATCHED (1 << 5) /* FIFO overrun occurred */ 351 352/* 353 * PCI230 ADC FIFO levels. 354 */ 355#define PCI230_ADC_FIFOLEVEL_HALFFULL 2049 /* Value for FIFO half full */ 356#define PCI230_ADC_FIFOLEVEL_FULL 4096 /* FIFO size */ 357 358/* 359 * PCI230+ EXTFUNC values. 360 */ 361/* Route EXTTRIG pin to external gate inputs. */ 362#define PCI230P_EXTFUNC_GAT_EXTTRIG (1 << 0) 363/* PCI230+ hardware version 2 values. */ 364/* Allow DAC FIFO to be enabled. */ 365#define PCI230P2_EXTFUNC_DACFIFO (1 << 1) 366 367/* 368 * Counter/timer clock input configuration sources. 369 */ 370#define CLK_CLK 0 /* reserved (channel-specific clock) */ 371#define CLK_10MHZ 1 /* internal 10 MHz clock */ 372#define CLK_1MHZ 2 /* internal 1 MHz clock */ 373#define CLK_100KHZ 3 /* internal 100 kHz clock */ 374#define CLK_10KHZ 4 /* internal 10 kHz clock */ 375#define CLK_1KHZ 5 /* internal 1 kHz clock */ 376#define CLK_OUTNM1 6 /* output of channel-1 modulo total */ 377#define CLK_EXT 7 /* external clock */ 378/* Macro to construct clock input configuration register value. */ 379#define CLK_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7)) 380/* Timebases in ns. */ 381#define TIMEBASE_10MHZ 100 382#define TIMEBASE_1MHZ 1000 383#define TIMEBASE_100KHZ 10000 384#define TIMEBASE_10KHZ 100000 385#define TIMEBASE_1KHZ 1000000 386 387/* 388 * Counter/timer gate input configuration sources. 389 */ 390#define GAT_VCC 0 /* VCC (i.e. enabled) */ 391#define GAT_GND 1 /* GND (i.e. disabled) */ 392#define GAT_EXT 2 /* external gate input (PPCn on PCI230) */ 393#define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */ 394/* Macro to construct gate input configuration register value. */ 395#define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7)) 396 397/* 398 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI230 and PCI260: 399 * 400 * Channel's Channel's 401 * clock input gate input 402 * Channel CLK_OUTNM1 GAT_NOUTNM2 403 * ------- ---------- ----------- 404 * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT 405 * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT 406 * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT 407 */ 408 409/* 410 * Interrupt enables/status register values. 411 */ 412#define PCI230_INT_DISABLE 0 413#define PCI230_INT_PPI_C0 (1 << 0) 414#define PCI230_INT_PPI_C3 (1 << 1) 415#define PCI230_INT_ADC (1 << 2) 416#define PCI230_INT_ZCLK_CT1 (1 << 5) 417/* For PCI230+ hardware version 2 when DAC FIFO enabled. */ 418#define PCI230P2_INT_DAC (1 << 4) 419 420/* 421 * (Potentially) shared resources and their owners 422 */ 423enum { 424 RES_Z2CT0 = (1U << 0), /* Z2-CT0 */ 425 RES_Z2CT1 = (1U << 1), /* Z2-CT1 */ 426 RES_Z2CT2 = (1U << 2) /* Z2-CT2 */ 427}; 428 429enum { 430 OWNER_AICMD, /* Owned by AI command */ 431 OWNER_AOCMD, /* Owned by AO command */ 432 NUM_OWNERS /* Number of owners */ 433}; 434 435/* 436 * Handy macros. 437 */ 438 439/* Combine old and new bits. */ 440#define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask))) 441 442/* Current CPU. XXX should this be hard_smp_processor_id()? */ 443#define THISCPU smp_processor_id() 444 445/* 446 * Board descriptions for the two boards supported. 447 */ 448 449struct pci230_board { 450 const char *name; 451 unsigned short id; 452 unsigned char ai_bits; 453 unsigned char ao_bits; 454 unsigned char min_hwver; /* Minimum hardware version supported. */ 455 bool have_dio:1; 456}; 457 458static const struct pci230_board pci230_boards[] = { 459 { 460 .name = "pci230+", 461 .id = PCI_DEVICE_ID_PCI230, 462 .ai_bits = 16, 463 .ao_bits = 12, 464 .have_dio = true, 465 .min_hwver = 1, 466 }, 467 { 468 .name = "pci260+", 469 .id = PCI_DEVICE_ID_PCI260, 470 .ai_bits = 16, 471 .min_hwver = 1, 472 }, 473 { 474 .name = "pci230", 475 .id = PCI_DEVICE_ID_PCI230, 476 .ai_bits = 12, 477 .ao_bits = 12, 478 .have_dio = true, 479 }, 480 { 481 .name = "pci260", 482 .id = PCI_DEVICE_ID_PCI260, 483 .ai_bits = 12, 484 }, 485}; 486 487struct pci230_private { 488 spinlock_t isr_spinlock; /* Interrupt spin lock */ 489 spinlock_t res_spinlock; /* Shared resources spin lock */ 490 spinlock_t ai_stop_spinlock; /* Spin lock for stopping AI command */ 491 spinlock_t ao_stop_spinlock; /* Spin lock for stopping AO command */ 492 unsigned long daqio; /* PCI230's DAQ I/O space */ 493 unsigned int ai_scan_count; /* Number of AI scans remaining */ 494 unsigned int ai_scan_pos; /* Current position within AI scan */ 495 unsigned int ao_scan_count; /* Number of AO scans remaining. */ 496 int intr_cpuid; /* ID of CPU running ISR */ 497 unsigned short hwver; /* Hardware version (for '+' models) */ 498 unsigned short adccon; /* ADCCON register value */ 499 unsigned short daccon; /* DACCON register value */ 500 unsigned short adcfifothresh; /* ADC FIFO threshold (PCI230+/260+) */ 501 unsigned short adcg; /* ADCG register value */ 502 unsigned char ier; /* Interrupt enable bits */ 503 unsigned char res_owned[NUM_OWNERS]; /* Owned resources */ 504 bool intr_running:1; /* Flag set in interrupt routine */ 505 bool ai_bipolar:1; /* Flag AI range is bipolar */ 506 bool ao_bipolar:1; /* Flag AO range is bipolar */ 507 bool ai_cmd_started:1; /* Flag AI command started */ 508 bool ao_cmd_started:1; /* Flag AO command started */ 509}; 510 511/* PCI230 clock source periods in ns */ 512static const unsigned int pci230_timebase[8] = { 513 [CLK_10MHZ] = TIMEBASE_10MHZ, 514 [CLK_1MHZ] = TIMEBASE_1MHZ, 515 [CLK_100KHZ] = TIMEBASE_100KHZ, 516 [CLK_10KHZ] = TIMEBASE_10KHZ, 517 [CLK_1KHZ] = TIMEBASE_1KHZ, 518}; 519 520/* PCI230 analogue input range table */ 521static const struct comedi_lrange pci230_ai_range = { 522 7, { 523 BIP_RANGE(10), 524 BIP_RANGE(5), 525 BIP_RANGE(2.5), 526 BIP_RANGE(1.25), 527 UNI_RANGE(10), 528 UNI_RANGE(5), 529 UNI_RANGE(2.5) 530 } 531}; 532 533/* PCI230 analogue gain bits for each input range. */ 534static const unsigned char pci230_ai_gain[7] = { 0, 1, 2, 3, 1, 2, 3 }; 535 536/* PCI230 analogue output range table */ 537static const struct comedi_lrange pci230_ao_range = { 538 2, { 539 UNI_RANGE(10), 540 BIP_RANGE(10) 541 } 542}; 543 544static unsigned short pci230_ai_read(struct comedi_device *dev) 545{ 546 const struct pci230_board *thisboard = dev->board_ptr; 547 struct pci230_private *devpriv = dev->private; 548 unsigned short data; 549 550 /* Read sample. */ 551 data = inw(devpriv->daqio + PCI230_ADCDATA); 552 /* 553 * PCI230 is 12 bit - stored in upper bits of 16 bit register 554 * (lower four bits reserved for expansion). PCI230+ is 16 bit AI. 555 * 556 * If a bipolar range was specified, mangle it 557 * (twos complement->straight binary). 558 */ 559 if (devpriv->ai_bipolar) 560 data ^= 0x8000; 561 data >>= (16 - thisboard->ai_bits); 562 return data; 563} 564 565static unsigned short pci230_ao_mangle_datum(struct comedi_device *dev, 566 unsigned short datum) 567{ 568 const struct pci230_board *thisboard = dev->board_ptr; 569 struct pci230_private *devpriv = dev->private; 570 571 /* 572 * PCI230 is 12 bit - stored in upper bits of 16 bit register (lower 573 * four bits reserved for expansion). PCI230+ is also 12 bit AO. 574 */ 575 datum <<= (16 - thisboard->ao_bits); 576 /* 577 * If a bipolar range was specified, mangle it 578 * (straight binary->twos complement). 579 */ 580 if (devpriv->ao_bipolar) 581 datum ^= 0x8000; 582 return datum; 583} 584 585static void pci230_ao_write_nofifo(struct comedi_device *dev, 586 unsigned short datum, unsigned int chan) 587{ 588 struct pci230_private *devpriv = dev->private; 589 590 /* Write mangled datum to appropriate DACOUT register. */ 591 outw(pci230_ao_mangle_datum(dev, datum), 592 devpriv->daqio + ((chan == 0) ? PCI230_DACOUT1 : PCI230_DACOUT2)); 593} 594 595static void pci230_ao_write_fifo(struct comedi_device *dev, 596 unsigned short datum, unsigned int chan) 597{ 598 struct pci230_private *devpriv = dev->private; 599 600 /* Write mangled datum to appropriate DACDATA register. */ 601 outw(pci230_ao_mangle_datum(dev, datum), 602 devpriv->daqio + PCI230P2_DACDATA); 603} 604 605static bool pci230_claim_shared(struct comedi_device *dev, 606 unsigned char res_mask, unsigned int owner) 607{ 608 struct pci230_private *devpriv = dev->private; 609 unsigned int o; 610 unsigned long irqflags; 611 612 spin_lock_irqsave(&devpriv->res_spinlock, irqflags); 613 for (o = 0; o < NUM_OWNERS; o++) { 614 if (o == owner) 615 continue; 616 if (devpriv->res_owned[o] & res_mask) { 617 spin_unlock_irqrestore(&devpriv->res_spinlock, 618 irqflags); 619 return false; 620 } 621 } 622 devpriv->res_owned[owner] |= res_mask; 623 spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags); 624 return true; 625} 626 627static void pci230_release_shared(struct comedi_device *dev, 628 unsigned char res_mask, unsigned int owner) 629{ 630 struct pci230_private *devpriv = dev->private; 631 unsigned long irqflags; 632 633 spin_lock_irqsave(&devpriv->res_spinlock, irqflags); 634 devpriv->res_owned[owner] &= ~res_mask; 635 spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags); 636} 637 638static void pci230_release_all_resources(struct comedi_device *dev, 639 unsigned int owner) 640{ 641 pci230_release_shared(dev, (unsigned char)~0, owner); 642} 643 644static unsigned int pci230_divide_ns(uint64_t ns, unsigned int timebase, 645 unsigned int flags) 646{ 647 uint64_t div; 648 unsigned int rem; 649 650 div = ns; 651 rem = do_div(div, timebase); 652 switch (flags & CMDF_ROUND_MASK) { 653 default: 654 case CMDF_ROUND_NEAREST: 655 div += (rem + (timebase / 2)) / timebase; 656 break; 657 case CMDF_ROUND_DOWN: 658 break; 659 case CMDF_ROUND_UP: 660 div += (rem + timebase - 1) / timebase; 661 break; 662 } 663 return div > UINT_MAX ? UINT_MAX : (unsigned int)div; 664} 665 666/* 667 * Given desired period in ns, returns the required internal clock source 668 * and gets the initial count. 669 */ 670static unsigned int pci230_choose_clk_count(uint64_t ns, unsigned int *count, 671 unsigned int flags) 672{ 673 unsigned int clk_src, cnt; 674 675 for (clk_src = CLK_10MHZ;; clk_src++) { 676 cnt = pci230_divide_ns(ns, pci230_timebase[clk_src], flags); 677 if (cnt <= 65536 || clk_src == CLK_1KHZ) 678 break; 679 } 680 *count = cnt; 681 return clk_src; 682} 683 684static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int flags) 685{ 686 unsigned int count; 687 unsigned int clk_src; 688 689 clk_src = pci230_choose_clk_count(*ns, &count, flags); 690 *ns = count * pci230_timebase[clk_src]; 691} 692 693static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct, 694 unsigned int mode, uint64_t ns, 695 unsigned int flags) 696{ 697 unsigned int clk_src; 698 unsigned int count; 699 700 /* Set mode. */ 701 i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, ct, mode); 702 /* Determine clock source and count. */ 703 clk_src = pci230_choose_clk_count(ns, &count, flags); 704 /* Program clock source. */ 705 outb(CLK_CONFIG(ct, clk_src), dev->iobase + PCI230_ZCLK_SCE); 706 /* Set initial count. */ 707 if (count >= 65536) 708 count = 0; 709 710 i8254_write(dev->iobase + PCI230_Z2_CT_BASE, 0, ct, count); 711} 712 713static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct) 714{ 715 i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, ct, I8254_MODE1); 716 /* Counter ct, 8254 mode 1, initial count not written. */ 717} 718 719static int pci230_ai_eoc(struct comedi_device *dev, 720 struct comedi_subdevice *s, 721 struct comedi_insn *insn, 722 unsigned long context) 723{ 724 struct pci230_private *devpriv = dev->private; 725 unsigned int status; 726 727 status = inw(devpriv->daqio + PCI230_ADCCON); 728 if ((status & PCI230_ADC_FIFO_EMPTY) == 0) 729 return 0; 730 return -EBUSY; 731} 732 733static int pci230_ai_insn_read(struct comedi_device *dev, 734 struct comedi_subdevice *s, 735 struct comedi_insn *insn, unsigned int *data) 736{ 737 struct pci230_private *devpriv = dev->private; 738 unsigned int n; 739 unsigned int chan, range, aref; 740 unsigned int gainshift; 741 unsigned short adccon, adcen; 742 int ret; 743 744 /* Unpack channel and range. */ 745 chan = CR_CHAN(insn->chanspec); 746 range = CR_RANGE(insn->chanspec); 747 aref = CR_AREF(insn->chanspec); 748 if (aref == AREF_DIFF) { 749 /* Differential. */ 750 if (chan >= s->n_chan / 2) { 751 dev_dbg(dev->class_dev, 752 "%s: differential channel number out of range 0 to %u\n", 753 __func__, (s->n_chan / 2) - 1); 754 return -EINVAL; 755 } 756 } 757 758 /* 759 * Use Z2-CT2 as a conversion trigger instead of the built-in 760 * software trigger, as otherwise triggering of differential channels 761 * doesn't work properly for some versions of PCI230/260. Also set 762 * FIFO mode because the ADC busy bit only works for software triggers. 763 */ 764 adccon = PCI230_ADC_TRIG_Z2CT2 | PCI230_ADC_FIFO_EN; 765 /* Set Z2-CT2 output low to avoid any false triggers. */ 766 i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE0); 767 devpriv->ai_bipolar = comedi_range_is_bipolar(s, range); 768 if (aref == AREF_DIFF) { 769 /* Differential. */ 770 gainshift = chan * 2; 771 if (devpriv->hwver == 0) { 772 /* 773 * Original PCI230/260 expects both inputs of the 774 * differential channel to be enabled. 775 */ 776 adcen = 3 << gainshift; 777 } else { 778 /* 779 * PCI230+/260+ expects only one input of the 780 * differential channel to be enabled. 781 */ 782 adcen = 1 << gainshift; 783 } 784 adccon |= PCI230_ADC_IM_DIF; 785 } else { 786 /* Single ended. */ 787 adcen = 1 << chan; 788 gainshift = chan & ~1; 789 adccon |= PCI230_ADC_IM_SE; 790 } 791 devpriv->adcg = (devpriv->adcg & ~(3 << gainshift)) | 792 (pci230_ai_gain[range] << gainshift); 793 if (devpriv->ai_bipolar) 794 adccon |= PCI230_ADC_IR_BIP; 795 else 796 adccon |= PCI230_ADC_IR_UNI; 797 798 /* 799 * Enable only this channel in the scan list - otherwise by default 800 * we'll get one sample from each channel. 801 */ 802 outw(adcen, devpriv->daqio + PCI230_ADCEN); 803 804 /* Set gain for channel. */ 805 outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG); 806 807 /* Specify uni/bip, se/diff, conversion source, and reset FIFO. */ 808 devpriv->adccon = adccon; 809 outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON); 810 811 /* Convert n samples */ 812 for (n = 0; n < insn->n; n++) { 813 /* 814 * Trigger conversion by toggling Z2-CT2 output 815 * (finish with output high). 816 */ 817 i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, 818 2, I8254_MODE0); 819 i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, 820 2, I8254_MODE1); 821 822 /* wait for conversion to end */ 823 ret = comedi_timeout(dev, s, insn, pci230_ai_eoc, 0); 824 if (ret) 825 return ret; 826 827 /* read data */ 828 data[n] = pci230_ai_read(dev); 829 } 830 831 /* return the number of samples read/written */ 832 return n; 833} 834 835static int pci230_ao_insn_write(struct comedi_device *dev, 836 struct comedi_subdevice *s, 837 struct comedi_insn *insn, 838 unsigned int *data) 839{ 840 struct pci230_private *devpriv = dev->private; 841 unsigned int chan = CR_CHAN(insn->chanspec); 842 unsigned int range = CR_RANGE(insn->chanspec); 843 unsigned int val = s->readback[chan]; 844 int i; 845 846 /* 847 * Set range - see analogue output range table; 0 => unipolar 10V, 848 * 1 => bipolar +/-10V range scale 849 */ 850 devpriv->ao_bipolar = comedi_range_is_bipolar(s, range); 851 outw(range, devpriv->daqio + PCI230_DACCON); 852 853 for (i = 0; i < insn->n; i++) { 854 val = data[i]; 855 pci230_ao_write_nofifo(dev, val, chan); 856 } 857 s->readback[chan] = val; 858 859 return insn->n; 860} 861 862static int pci230_ao_check_chanlist(struct comedi_device *dev, 863 struct comedi_subdevice *s, 864 struct comedi_cmd *cmd) 865{ 866 unsigned int prev_chan = CR_CHAN(cmd->chanlist[0]); 867 unsigned int range0 = CR_RANGE(cmd->chanlist[0]); 868 int i; 869 870 for (i = 1; i < cmd->chanlist_len; i++) { 871 unsigned int chan = CR_CHAN(cmd->chanlist[i]); 872 unsigned int range = CR_RANGE(cmd->chanlist[i]); 873 874 if (chan < prev_chan) { 875 dev_dbg(dev->class_dev, 876 "%s: channel numbers must increase\n", 877 __func__); 878 return -EINVAL; 879 } 880 881 if (range != range0) { 882 dev_dbg(dev->class_dev, 883 "%s: channels must have the same range\n", 884 __func__); 885 return -EINVAL; 886 } 887 888 prev_chan = chan; 889 } 890 891 return 0; 892} 893 894static int pci230_ao_cmdtest(struct comedi_device *dev, 895 struct comedi_subdevice *s, struct comedi_cmd *cmd) 896{ 897 const struct pci230_board *thisboard = dev->board_ptr; 898 struct pci230_private *devpriv = dev->private; 899 int err = 0; 900 unsigned int tmp; 901 902 /* Step 1 : check if triggers are trivially valid */ 903 904 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT); 905 906 tmp = TRIG_TIMER | TRIG_INT; 907 if (thisboard->min_hwver > 0 && devpriv->hwver >= 2) { 908 /* 909 * For PCI230+ hardware version 2 onwards, allow external 910 * trigger from EXTTRIG/EXTCONVCLK input (PCI230+ pin 25). 911 * 912 * FIXME: The permitted scan_begin_src values shouldn't depend 913 * on devpriv->hwver (the detected card's actual hardware 914 * version). They should only depend on thisboard->min_hwver 915 * (the static capabilities of the configured card). To fix 916 * it, a new card model, e.g. "pci230+2" would have to be 917 * defined with min_hwver set to 2. It doesn't seem worth it 918 * for this alone. At the moment, please consider 919 * scan_begin_src==TRIG_EXT support to be a bonus rather than a 920 * guarantee! 921 */ 922 tmp |= TRIG_EXT; 923 } 924 err |= cfc_check_trigger_src(&cmd->scan_begin_src, tmp); 925 926 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); 927 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 928 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 929 930 if (err) 931 return 1; 932 933 /* Step 2a : make sure trigger sources are unique */ 934 935 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); 936 err |= cfc_check_trigger_is_unique(cmd->stop_src); 937 938 /* Step 2b : and mutually compatible */ 939 940 if (err) 941 return 2; 942 943 /* Step 3: check if arguments are trivially valid */ 944 945 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 946 947#define MAX_SPEED_AO 8000 /* 8000 ns => 125 kHz */ 948/* 949 * Comedi limit due to unsigned int cmd. Driver limit = 950 * 2^16 (16bit * counter) * 1000000ns (1kHz onboard clock) = 65.536s 951 */ 952#define MIN_SPEED_AO 4294967295u /* 4294967295ns = 4.29s */ 953 954 switch (cmd->scan_begin_src) { 955 case TRIG_TIMER: 956 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 957 MAX_SPEED_AO); 958 err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 959 MIN_SPEED_AO); 960 break; 961 case TRIG_EXT: 962 /* 963 * External trigger - for PCI230+ hardware version 2 onwards. 964 */ 965 /* Trigger number must be 0. */ 966 if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) { 967 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, 968 ~CR_FLAGS_MASK); 969 err |= -EINVAL; 970 } 971 /* 972 * The only flags allowed are CR_EDGE and CR_INVERT. 973 * The CR_EDGE flag is ignored. 974 */ 975 if (cmd->scan_begin_arg & CR_FLAGS_MASK & 976 ~(CR_EDGE | CR_INVERT)) { 977 cmd->scan_begin_arg = 978 COMBINE(cmd->scan_begin_arg, 0, 979 CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT)); 980 err |= -EINVAL; 981 } 982 break; 983 default: 984 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); 985 break; 986 } 987 988 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); 989 990 if (cmd->stop_src == TRIG_COUNT) 991 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); 992 else /* TRIG_NONE */ 993 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 994 995 if (err) 996 return 3; 997 998 /* Step 4: fix up any arguments */ 999 1000 if (cmd->scan_begin_src == TRIG_TIMER) { 1001 tmp = cmd->scan_begin_arg; 1002 pci230_ns_to_single_timer(&cmd->scan_begin_arg, cmd->flags); 1003 if (tmp != cmd->scan_begin_arg) 1004 err++; 1005 } 1006 1007 if (err) 1008 return 4; 1009 1010 /* Step 5: check channel list if it exists */ 1011 if (cmd->chanlist && cmd->chanlist_len > 0) 1012 err |= pci230_ao_check_chanlist(dev, s, cmd); 1013 1014 if (err) 1015 return 5; 1016 1017 return 0; 1018} 1019 1020static void pci230_ao_stop(struct comedi_device *dev, 1021 struct comedi_subdevice *s) 1022{ 1023 struct pci230_private *devpriv = dev->private; 1024 unsigned long irqflags; 1025 unsigned char intsrc; 1026 bool started; 1027 struct comedi_cmd *cmd; 1028 1029 spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags); 1030 started = devpriv->ao_cmd_started; 1031 devpriv->ao_cmd_started = false; 1032 spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); 1033 if (!started) 1034 return; 1035 cmd = &s->async->cmd; 1036 if (cmd->scan_begin_src == TRIG_TIMER) { 1037 /* Stop scan rate generator. */ 1038 pci230_cancel_ct(dev, 1); 1039 } 1040 /* Determine interrupt source. */ 1041 if (devpriv->hwver < 2) { 1042 /* Not using DAC FIFO. Using CT1 interrupt. */ 1043 intsrc = PCI230_INT_ZCLK_CT1; 1044 } else { 1045 /* Using DAC FIFO interrupt. */ 1046 intsrc = PCI230P2_INT_DAC; 1047 } 1048 /* 1049 * Disable interrupt and wait for interrupt routine to finish running 1050 * unless we are called from the interrupt routine. 1051 */ 1052 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); 1053 devpriv->ier &= ~intsrc; 1054 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) { 1055 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); 1056 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); 1057 } 1058 outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); 1059 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); 1060 if (devpriv->hwver >= 2) { 1061 /* 1062 * Using DAC FIFO. Reset FIFO, clear underrun error, 1063 * disable FIFO. 1064 */ 1065 devpriv->daccon &= PCI230_DAC_OR_MASK; 1066 outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET | 1067 PCI230P2_DAC_FIFO_UNDERRUN_CLEAR, 1068 devpriv->daqio + PCI230_DACCON); 1069 } 1070 /* Release resources. */ 1071 pci230_release_all_resources(dev, OWNER_AOCMD); 1072} 1073 1074static void pci230_handle_ao_nofifo(struct comedi_device *dev, 1075 struct comedi_subdevice *s) 1076{ 1077 struct pci230_private *devpriv = dev->private; 1078 unsigned short data; 1079 int i, ret; 1080 struct comedi_async *async = s->async; 1081 struct comedi_cmd *cmd = &async->cmd; 1082 1083 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_scan_count == 0) 1084 return; 1085 for (i = 0; i < cmd->chanlist_len; i++) { 1086 unsigned int chan = CR_CHAN(cmd->chanlist[i]); 1087 1088 /* Read sample from Comedi's circular buffer. */ 1089 ret = comedi_buf_get(s, &data); 1090 if (ret == 0) { 1091 s->async->events |= COMEDI_CB_OVERFLOW; 1092 pci230_ao_stop(dev, s); 1093 dev_err(dev->class_dev, "AO buffer underrun\n"); 1094 return; 1095 } 1096 pci230_ao_write_nofifo(dev, data, chan); 1097 s->readback[chan] = data; 1098 } 1099 async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; 1100 if (cmd->stop_src == TRIG_COUNT) { 1101 devpriv->ao_scan_count--; 1102 if (devpriv->ao_scan_count == 0) { 1103 /* End of acquisition. */ 1104 async->events |= COMEDI_CB_EOA; 1105 pci230_ao_stop(dev, s); 1106 } 1107 } 1108} 1109 1110/* 1111 * Loads DAC FIFO (if using it) from buffer. 1112 * Returns false if AO finished due to completion or error, true if still going. 1113 */ 1114static bool pci230_handle_ao_fifo(struct comedi_device *dev, 1115 struct comedi_subdevice *s) 1116{ 1117 struct pci230_private *devpriv = dev->private; 1118 struct comedi_async *async = s->async; 1119 struct comedi_cmd *cmd = &async->cmd; 1120 unsigned int num_scans; 1121 unsigned int room; 1122 unsigned short dacstat; 1123 unsigned int i, n; 1124 unsigned int events = 0; 1125 bool running; 1126 1127 /* Get DAC FIFO status. */ 1128 dacstat = inw(devpriv->daqio + PCI230_DACCON); 1129 /* Determine number of scans available in buffer. */ 1130 num_scans = comedi_buf_read_n_available(s) / cfc_bytes_per_scan(s); 1131 if (cmd->stop_src == TRIG_COUNT) { 1132 /* Fixed number of scans. */ 1133 if (num_scans > devpriv->ao_scan_count) 1134 num_scans = devpriv->ao_scan_count; 1135 if (devpriv->ao_scan_count == 0) { 1136 /* End of acquisition. */ 1137 events |= COMEDI_CB_EOA; 1138 } 1139 } 1140 if (events == 0) { 1141 /* Check for FIFO underrun. */ 1142 if (dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) { 1143 dev_err(dev->class_dev, "AO FIFO underrun\n"); 1144 events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; 1145 } 1146 /* 1147 * Check for buffer underrun if FIFO less than half full 1148 * (otherwise there will be loads of "DAC FIFO not half full" 1149 * interrupts). 1150 */ 1151 if (num_scans == 0 && 1152 (dacstat & PCI230P2_DAC_FIFO_HALF) == 0) { 1153 dev_err(dev->class_dev, "AO buffer underrun\n"); 1154 events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; 1155 } 1156 } 1157 if (events == 0) { 1158 /* Determine how much room is in the FIFO (in samples). */ 1159 if (dacstat & PCI230P2_DAC_FIFO_FULL) 1160 room = PCI230P2_DAC_FIFOROOM_FULL; 1161 else if (dacstat & PCI230P2_DAC_FIFO_HALF) 1162 room = PCI230P2_DAC_FIFOROOM_HALFTOFULL; 1163 else if (dacstat & PCI230P2_DAC_FIFO_EMPTY) 1164 room = PCI230P2_DAC_FIFOROOM_EMPTY; 1165 else 1166 room = PCI230P2_DAC_FIFOROOM_ONETOHALF; 1167 /* Convert room to number of scans that can be added. */ 1168 room /= cmd->chanlist_len; 1169 /* Determine number of scans to process. */ 1170 if (num_scans > room) 1171 num_scans = room; 1172 /* Process scans. */ 1173 for (n = 0; n < num_scans; n++) { 1174 for (i = 0; i < cmd->chanlist_len; i++) { 1175 unsigned int chan = CR_CHAN(cmd->chanlist[i]); 1176 unsigned short datum; 1177 1178 comedi_buf_get(s, &datum); 1179 pci230_ao_write_fifo(dev, datum, chan); 1180 s->readback[chan] = datum; 1181 } 1182 } 1183 events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK; 1184 if (cmd->stop_src == TRIG_COUNT) { 1185 devpriv->ao_scan_count -= num_scans; 1186 if (devpriv->ao_scan_count == 0) { 1187 /* 1188 * All data for the command has been written 1189 * to FIFO. Set FIFO interrupt trigger level 1190 * to 'empty'. 1191 */ 1192 devpriv->daccon = 1193 (devpriv->daccon & 1194 ~PCI230P2_DAC_INT_FIFO_MASK) | 1195 PCI230P2_DAC_INT_FIFO_EMPTY; 1196 outw(devpriv->daccon, 1197 devpriv->daqio + PCI230_DACCON); 1198 } 1199 } 1200 /* Check if FIFO underrun occurred while writing to FIFO. */ 1201 dacstat = inw(devpriv->daqio + PCI230_DACCON); 1202 if (dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) { 1203 dev_err(dev->class_dev, "AO FIFO underrun\n"); 1204 events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; 1205 } 1206 } 1207 if (events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) { 1208 /* Stopping AO due to completion or error. */ 1209 pci230_ao_stop(dev, s); 1210 running = false; 1211 } else { 1212 running = true; 1213 } 1214 async->events |= events; 1215 return running; 1216} 1217 1218static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev, 1219 struct comedi_subdevice *s, 1220 unsigned int trig_num) 1221{ 1222 struct pci230_private *devpriv = dev->private; 1223 unsigned long irqflags; 1224 1225 if (trig_num) 1226 return -EINVAL; 1227 1228 spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags); 1229 if (!devpriv->ao_cmd_started) { 1230 spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); 1231 return 1; 1232 } 1233 /* Perform scan. */ 1234 if (devpriv->hwver < 2) { 1235 /* Not using DAC FIFO. */ 1236 spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); 1237 pci230_handle_ao_nofifo(dev, s); 1238 comedi_event(dev, s); 1239 } else { 1240 /* Using DAC FIFO. */ 1241 /* Read DACSWTRIG register to trigger conversion. */ 1242 inw(devpriv->daqio + PCI230P2_DACSWTRIG); 1243 spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); 1244 } 1245 /* Delay. Should driver be responsible for this? */ 1246 /* XXX TODO: See if DAC busy bit can be used. */ 1247 udelay(8); 1248 return 1; 1249} 1250 1251static void pci230_ao_start(struct comedi_device *dev, 1252 struct comedi_subdevice *s) 1253{ 1254 struct pci230_private *devpriv = dev->private; 1255 struct comedi_async *async = s->async; 1256 struct comedi_cmd *cmd = &async->cmd; 1257 unsigned long irqflags; 1258 1259 devpriv->ao_cmd_started = true; 1260 1261 if (devpriv->hwver >= 2) { 1262 /* Using DAC FIFO. */ 1263 unsigned short scantrig; 1264 bool run; 1265 1266 /* Preload FIFO data. */ 1267 run = pci230_handle_ao_fifo(dev, s); 1268 comedi_event(dev, s); 1269 if (!run) { 1270 /* Stopped. */ 1271 return; 1272 } 1273 /* Set scan trigger source. */ 1274 switch (cmd->scan_begin_src) { 1275 case TRIG_TIMER: 1276 scantrig = PCI230P2_DAC_TRIG_Z2CT1; 1277 break; 1278 case TRIG_EXT: 1279 /* Trigger on EXTTRIG/EXTCONVCLK pin. */ 1280 if ((cmd->scan_begin_arg & CR_INVERT) == 0) { 1281 /* +ve edge */ 1282 scantrig = PCI230P2_DAC_TRIG_EXTP; 1283 } else { 1284 /* -ve edge */ 1285 scantrig = PCI230P2_DAC_TRIG_EXTN; 1286 } 1287 break; 1288 case TRIG_INT: 1289 scantrig = PCI230P2_DAC_TRIG_SW; 1290 break; 1291 default: 1292 /* Shouldn't get here. */ 1293 scantrig = PCI230P2_DAC_TRIG_NONE; 1294 break; 1295 } 1296 devpriv->daccon = 1297 (devpriv->daccon & ~PCI230P2_DAC_TRIG_MASK) | scantrig; 1298 outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON); 1299 } 1300 switch (cmd->scan_begin_src) { 1301 case TRIG_TIMER: 1302 if (devpriv->hwver < 2) { 1303 /* Not using DAC FIFO. */ 1304 /* Enable CT1 timer interrupt. */ 1305 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); 1306 devpriv->ier |= PCI230_INT_ZCLK_CT1; 1307 outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); 1308 spin_unlock_irqrestore(&devpriv->isr_spinlock, 1309 irqflags); 1310 } 1311 /* Set CT1 gate high to start counting. */ 1312 outb(GAT_CONFIG(1, GAT_VCC), dev->iobase + PCI230_ZGAT_SCE); 1313 break; 1314 case TRIG_INT: 1315 async->inttrig = pci230_ao_inttrig_scan_begin; 1316 break; 1317 } 1318 if (devpriv->hwver >= 2) { 1319 /* Using DAC FIFO. Enable DAC FIFO interrupt. */ 1320 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); 1321 devpriv->ier |= PCI230P2_INT_DAC; 1322 outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); 1323 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); 1324 } 1325} 1326 1327static int pci230_ao_inttrig_start(struct comedi_device *dev, 1328 struct comedi_subdevice *s, 1329 unsigned int trig_num) 1330{ 1331 struct comedi_cmd *cmd = &s->async->cmd; 1332 1333 if (trig_num != cmd->start_src) 1334 return -EINVAL; 1335 1336 s->async->inttrig = NULL; 1337 pci230_ao_start(dev, s); 1338 1339 return 1; 1340} 1341 1342static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 1343{ 1344 struct pci230_private *devpriv = dev->private; 1345 unsigned short daccon; 1346 unsigned int range; 1347 1348 /* Get the command. */ 1349 struct comedi_cmd *cmd = &s->async->cmd; 1350 1351 if (cmd->scan_begin_src == TRIG_TIMER) { 1352 /* Claim Z2-CT1. */ 1353 if (!pci230_claim_shared(dev, RES_Z2CT1, OWNER_AOCMD)) 1354 return -EBUSY; 1355 } 1356 1357 devpriv->ao_scan_count = cmd->stop_arg; 1358 1359 /* 1360 * Set range - see analogue output range table; 0 => unipolar 10V, 1361 * 1 => bipolar +/-10V range scale 1362 */ 1363 range = CR_RANGE(cmd->chanlist[0]); 1364 devpriv->ao_bipolar = comedi_range_is_bipolar(s, range); 1365 daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI; 1366 /* Use DAC FIFO for hardware version 2 onwards. */ 1367 if (devpriv->hwver >= 2) { 1368 unsigned short dacen; 1369 unsigned int i; 1370 1371 dacen = 0; 1372 for (i = 0; i < cmd->chanlist_len; i++) 1373 dacen |= 1 << CR_CHAN(cmd->chanlist[i]); 1374 1375 /* Set channel scan list. */ 1376 outw(dacen, devpriv->daqio + PCI230P2_DACEN); 1377 /* 1378 * Enable DAC FIFO. 1379 * Set DAC scan source to 'none'. 1380 * Set DAC FIFO interrupt trigger level to 'not half full'. 1381 * Reset DAC FIFO and clear underrun. 1382 * 1383 * N.B. DAC FIFO interrupts are currently disabled. 1384 */ 1385 daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET | 1386 PCI230P2_DAC_FIFO_UNDERRUN_CLEAR | 1387 PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF; 1388 } 1389 1390 /* Set DACCON. */ 1391 outw(daccon, devpriv->daqio + PCI230_DACCON); 1392 /* Preserve most of DACCON apart from write-only, transient bits. */ 1393 devpriv->daccon = daccon & ~(PCI230P2_DAC_FIFO_RESET | 1394 PCI230P2_DAC_FIFO_UNDERRUN_CLEAR); 1395 1396 if (cmd->scan_begin_src == TRIG_TIMER) { 1397 /* 1398 * Set the counter timer 1 to the specified scan frequency. 1399 * cmd->scan_begin_arg is sampling period in ns. 1400 * Gate it off for now. 1401 */ 1402 outb(GAT_CONFIG(1, GAT_GND), dev->iobase + PCI230_ZGAT_SCE); 1403 pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3, 1404 cmd->scan_begin_arg, 1405 cmd->flags); 1406 } 1407 1408 /* N.B. cmd->start_src == TRIG_INT */ 1409 s->async->inttrig = pci230_ao_inttrig_start; 1410 1411 return 0; 1412} 1413 1414static int pci230_ao_cancel(struct comedi_device *dev, 1415 struct comedi_subdevice *s) 1416{ 1417 pci230_ao_stop(dev, s); 1418 return 0; 1419} 1420 1421static int pci230_ai_check_scan_period(struct comedi_cmd *cmd) 1422{ 1423 unsigned int min_scan_period, chanlist_len; 1424 int err = 0; 1425 1426 chanlist_len = cmd->chanlist_len; 1427 if (cmd->chanlist_len == 0) 1428 chanlist_len = 1; 1429 1430 min_scan_period = chanlist_len * cmd->convert_arg; 1431 if (min_scan_period < chanlist_len || 1432 min_scan_period < cmd->convert_arg) { 1433 /* Arithmetic overflow. */ 1434 min_scan_period = UINT_MAX; 1435 err++; 1436 } 1437 if (cmd->scan_begin_arg < min_scan_period) { 1438 cmd->scan_begin_arg = min_scan_period; 1439 err++; 1440 } 1441 1442 return !err; 1443} 1444 1445static int pci230_ai_check_chanlist(struct comedi_device *dev, 1446 struct comedi_subdevice *s, 1447 struct comedi_cmd *cmd) 1448{ 1449 struct pci230_private *devpriv = dev->private; 1450 unsigned int max_diff_chan = (s->n_chan / 2) - 1; 1451 unsigned int prev_chan = 0; 1452 unsigned int prev_range = 0; 1453 unsigned int prev_aref = 0; 1454 bool prev_bipolar = false; 1455 unsigned int subseq_len = 0; 1456 int i; 1457 1458 for (i = 0; i < cmd->chanlist_len; i++) { 1459 unsigned int chanspec = cmd->chanlist[i]; 1460 unsigned int chan = CR_CHAN(chanspec); 1461 unsigned int range = CR_RANGE(chanspec); 1462 unsigned int aref = CR_AREF(chanspec); 1463 bool bipolar = comedi_range_is_bipolar(s, range); 1464 1465 if (aref == AREF_DIFF && chan >= max_diff_chan) { 1466 dev_dbg(dev->class_dev, 1467 "%s: differential channel number out of range 0 to %u\n", 1468 __func__, max_diff_chan); 1469 return -EINVAL; 1470 } 1471 1472 if (i > 0) { 1473 /* 1474 * Channel numbers must strictly increase or 1475 * subsequence must repeat exactly. 1476 */ 1477 if (chan <= prev_chan && subseq_len == 0) 1478 subseq_len = i; 1479 1480 if (subseq_len > 0 && 1481 cmd->chanlist[i % subseq_len] != chanspec) { 1482 dev_dbg(dev->class_dev, 1483 "%s: channel numbers must increase or sequence must repeat exactly\n", 1484 __func__); 1485 return -EINVAL; 1486 } 1487 1488 if (aref != prev_aref) { 1489 dev_dbg(dev->class_dev, 1490 "%s: channel sequence analogue references must be all the same (single-ended or differential)\n", 1491 __func__); 1492 return -EINVAL; 1493 } 1494 1495 if (bipolar != prev_bipolar) { 1496 dev_dbg(dev->class_dev, 1497 "%s: channel sequence ranges must be all bipolar or all unipolar\n", 1498 __func__); 1499 return -EINVAL; 1500 } 1501 1502 if (aref != AREF_DIFF && range != prev_range && 1503 ((chan ^ prev_chan) & ~1) == 0) { 1504 dev_dbg(dev->class_dev, 1505 "%s: single-ended channel pairs must have the same range\n", 1506 __func__); 1507 return -EINVAL; 1508 } 1509 } 1510 prev_chan = chan; 1511 prev_range = range; 1512 prev_aref = aref; 1513 prev_bipolar = bipolar; 1514 } 1515 1516 if (subseq_len == 0) 1517 subseq_len = cmd->chanlist_len; 1518 1519 if (cmd->chanlist_len % subseq_len) { 1520 dev_dbg(dev->class_dev, 1521 "%s: sequence must repeat exactly\n", __func__); 1522 return -EINVAL; 1523 } 1524 1525 /* 1526 * Buggy PCI230+ or PCI260+ requires channel 0 to be (first) in the 1527 * sequence if the sequence contains more than one channel. Hardware 1528 * versions 1 and 2 have the bug. There is no hardware version 3. 1529 * 1530 * Actually, there are two firmwares that report themselves as 1531 * hardware version 1 (the boards have different ADC chips with 1532 * slightly different timing requirements, which was supposed to 1533 * be invisible to software). The first one doesn't seem to have 1534 * the bug, but the second one does, and we can't tell them apart! 1535 */ 1536 if (devpriv->hwver > 0 && devpriv->hwver < 4) { 1537 if (subseq_len > 1 && CR_CHAN(cmd->chanlist[0])) { 1538 dev_info(dev->class_dev, 1539 "amplc_pci230: ai_cmdtest: Buggy PCI230+/260+ h/w version %u requires first channel of multi-channel sequence to be 0 (corrected in h/w version 4)\n", 1540 devpriv->hwver); 1541 return -EINVAL; 1542 } 1543 } 1544 1545 return 0; 1546} 1547 1548static int pci230_ai_cmdtest(struct comedi_device *dev, 1549 struct comedi_subdevice *s, struct comedi_cmd *cmd) 1550{ 1551 const struct pci230_board *thisboard = dev->board_ptr; 1552 struct pci230_private *devpriv = dev->private; 1553 int err = 0; 1554 unsigned int tmp; 1555 1556 /* Step 1 : check if triggers are trivially valid */ 1557 1558 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); 1559 1560 tmp = TRIG_FOLLOW | TRIG_TIMER | TRIG_INT; 1561 if (thisboard->have_dio || thisboard->min_hwver > 0) { 1562 /* 1563 * Unfortunately, we cannot trigger a scan off an external 1564 * source on the PCI260 board, since it uses the PPIC0 (DIO) 1565 * input, which isn't present on the PCI260. For PCI260+ 1566 * we can use the EXTTRIG/EXTCONVCLK input on pin 17 instead. 1567 */ 1568 tmp |= TRIG_EXT; 1569 } 1570 err |= cfc_check_trigger_src(&cmd->scan_begin_src, tmp); 1571 err |= cfc_check_trigger_src(&cmd->convert_src, 1572 TRIG_TIMER | TRIG_INT | TRIG_EXT); 1573 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 1574 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 1575 1576 if (err) 1577 return 1; 1578 1579 /* Step 2a : make sure trigger sources are unique */ 1580 1581 err |= cfc_check_trigger_is_unique(cmd->start_src); 1582 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); 1583 err |= cfc_check_trigger_is_unique(cmd->convert_src); 1584 err |= cfc_check_trigger_is_unique(cmd->stop_src); 1585 1586 /* Step 2b : and mutually compatible */ 1587 1588 /* 1589 * If scan_begin_src is not TRIG_FOLLOW, then a monostable will be 1590 * set up to generate a fixed number of timed conversion pulses. 1591 */ 1592 if (cmd->scan_begin_src != TRIG_FOLLOW && 1593 cmd->convert_src != TRIG_TIMER) 1594 err |= -EINVAL; 1595 1596 if (err) 1597 return 2; 1598 1599 /* Step 3: check if arguments are trivially valid */ 1600 1601 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 1602 1603#define MAX_SPEED_AI_SE 3200 /* PCI230 SE: 3200 ns => 312.5 kHz */ 1604#define MAX_SPEED_AI_DIFF 8000 /* PCI230 DIFF: 8000 ns => 125 kHz */ 1605#define MAX_SPEED_AI_PLUS 4000 /* PCI230+: 4000 ns => 250 kHz */ 1606/* 1607 * Comedi limit due to unsigned int cmd. Driver limit = 1608 * 2^16 (16bit * counter) * 1000000ns (1kHz onboard clock) = 65.536s 1609 */ 1610#define MIN_SPEED_AI 4294967295u /* 4294967295ns = 4.29s */ 1611 1612 if (cmd->convert_src == TRIG_TIMER) { 1613 unsigned int max_speed_ai; 1614 1615 if (devpriv->hwver == 0) { 1616 /* 1617 * PCI230 or PCI260. Max speed depends whether 1618 * single-ended or pseudo-differential. 1619 */ 1620 if (cmd->chanlist && cmd->chanlist_len > 0) { 1621 /* Peek analogue reference of first channel. */ 1622 if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) 1623 max_speed_ai = MAX_SPEED_AI_DIFF; 1624 else 1625 max_speed_ai = MAX_SPEED_AI_SE; 1626 1627 } else { 1628 /* No channel list. Assume single-ended. */ 1629 max_speed_ai = MAX_SPEED_AI_SE; 1630 } 1631 } else { 1632 /* PCI230+ or PCI260+. */ 1633 max_speed_ai = MAX_SPEED_AI_PLUS; 1634 } 1635 1636 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 1637 max_speed_ai); 1638 err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 1639 MIN_SPEED_AI); 1640 } else if (cmd->convert_src == TRIG_EXT) { 1641 /* 1642 * external trigger 1643 * 1644 * convert_arg == (CR_EDGE | 0) 1645 * => trigger on +ve edge. 1646 * convert_arg == (CR_EDGE | CR_INVERT | 0) 1647 * => trigger on -ve edge. 1648 */ 1649 if (cmd->convert_arg & CR_FLAGS_MASK) { 1650 /* Trigger number must be 0. */ 1651 if (cmd->convert_arg & ~CR_FLAGS_MASK) { 1652 cmd->convert_arg = COMBINE(cmd->convert_arg, 0, 1653 ~CR_FLAGS_MASK); 1654 err |= -EINVAL; 1655 } 1656 /* 1657 * The only flags allowed are CR_INVERT and CR_EDGE. 1658 * CR_EDGE is required. 1659 */ 1660 if ((cmd->convert_arg & CR_FLAGS_MASK & ~CR_INVERT) != 1661 CR_EDGE) { 1662 /* Set CR_EDGE, preserve CR_INVERT. */ 1663 cmd->convert_arg = 1664 COMBINE(cmd->start_arg, CR_EDGE | 0, 1665 CR_FLAGS_MASK & ~CR_INVERT); 1666 err |= -EINVAL; 1667 } 1668 } else { 1669 /* 1670 * Backwards compatibility with previous versions: 1671 * convert_arg == 0 => trigger on -ve edge. 1672 * convert_arg == 1 => trigger on +ve edge. 1673 */ 1674 err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 1); 1675 } 1676 } else { 1677 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); 1678 } 1679 1680 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); 1681 1682 if (cmd->stop_src == TRIG_COUNT) 1683 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); 1684 else /* TRIG_NONE */ 1685 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 1686 1687 if (cmd->scan_begin_src == TRIG_EXT) { 1688 /* 1689 * external "trigger" to begin each scan: 1690 * scan_begin_arg==0 => use PPC0 input -> gate of CT0 -> gate 1691 * of CT2 (sample convert trigger is CT2) 1692 */ 1693 if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) { 1694 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, 1695 ~CR_FLAGS_MASK); 1696 err |= -EINVAL; 1697 } 1698 /* The only flag allowed is CR_EDGE, which is ignored. */ 1699 if (cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) { 1700 cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, 1701 CR_FLAGS_MASK & ~CR_EDGE); 1702 err |= -EINVAL; 1703 } 1704 } else if (cmd->scan_begin_src == TRIG_TIMER) { 1705 /* N.B. cmd->convert_arg is also TRIG_TIMER */ 1706 if (!pci230_ai_check_scan_period(cmd)) 1707 err |= -EINVAL; 1708 1709 } else { 1710 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); 1711 } 1712 1713 if (err) 1714 return 3; 1715 1716 /* Step 4: fix up any arguments */ 1717 1718 if (cmd->convert_src == TRIG_TIMER) { 1719 tmp = cmd->convert_arg; 1720 pci230_ns_to_single_timer(&cmd->convert_arg, cmd->flags); 1721 if (tmp != cmd->convert_arg) 1722 err++; 1723 } 1724 1725 if (cmd->scan_begin_src == TRIG_TIMER) { 1726 /* N.B. cmd->convert_arg is also TRIG_TIMER */ 1727 tmp = cmd->scan_begin_arg; 1728 pci230_ns_to_single_timer(&cmd->scan_begin_arg, cmd->flags); 1729 if (!pci230_ai_check_scan_period(cmd)) { 1730 /* Was below minimum required. Round up. */ 1731 pci230_ns_to_single_timer(&cmd->scan_begin_arg, 1732 CMDF_ROUND_UP); 1733 pci230_ai_check_scan_period(cmd); 1734 } 1735 if (tmp != cmd->scan_begin_arg) 1736 err++; 1737 } 1738 1739 if (err) 1740 return 4; 1741 1742 /* Step 5: check channel list if it exists */ 1743 if (cmd->chanlist && cmd->chanlist_len > 0) 1744 err |= pci230_ai_check_chanlist(dev, s, cmd); 1745 1746 if (err) 1747 return 5; 1748 1749 return 0; 1750} 1751 1752static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev, 1753 struct comedi_subdevice *s) 1754{ 1755 struct pci230_private *devpriv = dev->private; 1756 struct comedi_cmd *cmd = &s->async->cmd; 1757 unsigned int scanlen = cmd->scan_end_arg; 1758 unsigned int wake; 1759 unsigned short triglev; 1760 unsigned short adccon; 1761 1762 if (cmd->flags & CMDF_WAKE_EOS) 1763 wake = scanlen - devpriv->ai_scan_pos; 1764 else if (cmd->stop_src != TRIG_COUNT || 1765 devpriv->ai_scan_count >= PCI230_ADC_FIFOLEVEL_HALFFULL || 1766 scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL) 1767 wake = PCI230_ADC_FIFOLEVEL_HALFFULL; 1768 else 1769 wake = devpriv->ai_scan_count * scanlen - devpriv->ai_scan_pos; 1770 if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) { 1771 triglev = PCI230_ADC_INT_FIFO_HALF; 1772 } else if (wake > 1 && devpriv->hwver > 0) { 1773 /* PCI230+/260+ programmable FIFO interrupt level. */ 1774 if (devpriv->adcfifothresh != wake) { 1775 devpriv->adcfifothresh = wake; 1776 outw(wake, devpriv->daqio + PCI230P_ADCFFTH); 1777 } 1778 triglev = PCI230P_ADC_INT_FIFO_THRESH; 1779 } else { 1780 triglev = PCI230_ADC_INT_FIFO_NEMPTY; 1781 } 1782 adccon = (devpriv->adccon & ~PCI230_ADC_INT_FIFO_MASK) | triglev; 1783 if (adccon != devpriv->adccon) { 1784 devpriv->adccon = adccon; 1785 outw(adccon, devpriv->daqio + PCI230_ADCCON); 1786 } 1787} 1788 1789static int pci230_ai_inttrig_convert(struct comedi_device *dev, 1790 struct comedi_subdevice *s, 1791 unsigned int trig_num) 1792{ 1793 struct pci230_private *devpriv = dev->private; 1794 unsigned long irqflags; 1795 unsigned int delayus; 1796 1797 if (trig_num) 1798 return -EINVAL; 1799 1800 spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags); 1801 if (!devpriv->ai_cmd_started) { 1802 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags); 1803 return 1; 1804 } 1805 /* 1806 * Trigger conversion by toggling Z2-CT2 output. 1807 * Finish with output high. 1808 */ 1809 i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE0); 1810 i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE1); 1811 /* 1812 * Delay. Should driver be responsible for this? An 1813 * alternative would be to wait until conversion is complete, 1814 * but we can't tell when it's complete because the ADC busy 1815 * bit has a different meaning when FIFO enabled (and when 1816 * FIFO not enabled, it only works for software triggers). 1817 */ 1818 if ((devpriv->adccon & PCI230_ADC_IM_MASK) == PCI230_ADC_IM_DIF && 1819 devpriv->hwver == 0) { 1820 /* PCI230/260 in differential mode */ 1821 delayus = 8; 1822 } else { 1823 /* single-ended or PCI230+/260+ */ 1824 delayus = 4; 1825 } 1826 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags); 1827 udelay(delayus); 1828 return 1; 1829} 1830 1831static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev, 1832 struct comedi_subdevice *s, 1833 unsigned int trig_num) 1834{ 1835 struct pci230_private *devpriv = dev->private; 1836 unsigned long irqflags; 1837 unsigned char zgat; 1838 1839 if (trig_num) 1840 return -EINVAL; 1841 1842 spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags); 1843 if (devpriv->ai_cmd_started) { 1844 /* Trigger scan by waggling CT0 gate source. */ 1845 zgat = GAT_CONFIG(0, GAT_GND); 1846 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); 1847 zgat = GAT_CONFIG(0, GAT_VCC); 1848 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); 1849 } 1850 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags); 1851 1852 return 1; 1853} 1854 1855static void pci230_ai_stop(struct comedi_device *dev, 1856 struct comedi_subdevice *s) 1857{ 1858 struct pci230_private *devpriv = dev->private; 1859 unsigned long irqflags; 1860 struct comedi_cmd *cmd; 1861 bool started; 1862 1863 spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags); 1864 started = devpriv->ai_cmd_started; 1865 devpriv->ai_cmd_started = false; 1866 spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags); 1867 if (!started) 1868 return; 1869 cmd = &s->async->cmd; 1870 if (cmd->convert_src == TRIG_TIMER) { 1871 /* Stop conversion rate generator. */ 1872 pci230_cancel_ct(dev, 2); 1873 } 1874 if (cmd->scan_begin_src != TRIG_FOLLOW) { 1875 /* Stop scan period monostable. */ 1876 pci230_cancel_ct(dev, 0); 1877 } 1878 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); 1879 /* 1880 * Disable ADC interrupt and wait for interrupt routine to finish 1881 * running unless we are called from the interrupt routine. 1882 */ 1883 devpriv->ier &= ~PCI230_INT_ADC; 1884 while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) { 1885 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); 1886 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); 1887 } 1888 outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); 1889 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); 1890 /* 1891 * Reset FIFO, disable FIFO and set start conversion source to none. 1892 * Keep se/diff and bip/uni settings. 1893 */ 1894 devpriv->adccon = 1895 (devpriv->adccon & (PCI230_ADC_IR_MASK | PCI230_ADC_IM_MASK)) | 1896 PCI230_ADC_TRIG_NONE; 1897 outw(devpriv->adccon | PCI230_ADC_FIFO_RESET, 1898 devpriv->daqio + PCI230_ADCCON); 1899 /* Release resources. */ 1900 pci230_release_all_resources(dev, OWNER_AICMD); 1901} 1902 1903static void pci230_ai_start(struct comedi_device *dev, 1904 struct comedi_subdevice *s) 1905{ 1906 struct pci230_private *devpriv = dev->private; 1907 unsigned long irqflags; 1908 unsigned short conv; 1909 struct comedi_async *async = s->async; 1910 struct comedi_cmd *cmd = &async->cmd; 1911 1912 devpriv->ai_cmd_started = true; 1913 1914 /* Enable ADC FIFO trigger level interrupt. */ 1915 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); 1916 devpriv->ier |= PCI230_INT_ADC; 1917 outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); 1918 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); 1919 1920 /* 1921 * Update conversion trigger source which is currently set 1922 * to CT2 output, which is currently stuck high. 1923 */ 1924 switch (cmd->convert_src) { 1925 default: 1926 conv = PCI230_ADC_TRIG_NONE; 1927 break; 1928 case TRIG_TIMER: 1929 /* Using CT2 output. */ 1930 conv = PCI230_ADC_TRIG_Z2CT2; 1931 break; 1932 case TRIG_EXT: 1933 if (cmd->convert_arg & CR_EDGE) { 1934 if ((cmd->convert_arg & CR_INVERT) == 0) { 1935 /* Trigger on +ve edge. */ 1936 conv = PCI230_ADC_TRIG_EXTP; 1937 } else { 1938 /* Trigger on -ve edge. */ 1939 conv = PCI230_ADC_TRIG_EXTN; 1940 } 1941 } else { 1942 /* Backwards compatibility. */ 1943 if (cmd->convert_arg) { 1944 /* Trigger on +ve edge. */ 1945 conv = PCI230_ADC_TRIG_EXTP; 1946 } else { 1947 /* Trigger on -ve edge. */ 1948 conv = PCI230_ADC_TRIG_EXTN; 1949 } 1950 } 1951 break; 1952 case TRIG_INT: 1953 /* 1954 * Use CT2 output for software trigger due to problems 1955 * in differential mode on PCI230/260. 1956 */ 1957 conv = PCI230_ADC_TRIG_Z2CT2; 1958 break; 1959 } 1960 devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK) | conv; 1961 outw(devpriv->adccon, devpriv->daqio + PCI230_ADCCON); 1962 if (cmd->convert_src == TRIG_INT) 1963 async->inttrig = pci230_ai_inttrig_convert; 1964 1965 /* 1966 * Update FIFO interrupt trigger level, which is currently 1967 * set to "full". 1968 */ 1969 pci230_ai_update_fifo_trigger_level(dev, s); 1970 if (cmd->convert_src == TRIG_TIMER) { 1971 /* Update timer gates. */ 1972 unsigned char zgat; 1973 1974 if (cmd->scan_begin_src != TRIG_FOLLOW) { 1975 /* 1976 * Conversion timer CT2 needs to be gated by 1977 * inverted output of monostable CT2. 1978 */ 1979 zgat = GAT_CONFIG(2, GAT_NOUTNM2); 1980 } else { 1981 /* 1982 * Conversion timer CT2 needs to be gated on 1983 * continuously. 1984 */ 1985 zgat = GAT_CONFIG(2, GAT_VCC); 1986 } 1987 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); 1988 if (cmd->scan_begin_src != TRIG_FOLLOW) { 1989 /* Set monostable CT0 trigger source. */ 1990 switch (cmd->scan_begin_src) { 1991 default: 1992 zgat = GAT_CONFIG(0, GAT_VCC); 1993 break; 1994 case TRIG_EXT: 1995 /* 1996 * For CT0 on PCI230, the external trigger 1997 * (gate) signal comes from PPC0, which is 1998 * channel 16 of the DIO subdevice. The 1999 * application needs to configure this as an 2000 * input in order to use it as an external scan 2001 * trigger. 2002 */ 2003 zgat = GAT_CONFIG(0, GAT_EXT); 2004 break; 2005 case TRIG_TIMER: 2006 /* 2007 * Monostable CT0 triggered by rising edge on 2008 * inverted output of CT1 (falling edge on CT1). 2009 */ 2010 zgat = GAT_CONFIG(0, GAT_NOUTNM2); 2011 break; 2012 case TRIG_INT: 2013 /* 2014 * Monostable CT0 is triggered by inttrig 2015 * function waggling the CT0 gate source. 2016 */ 2017 zgat = GAT_CONFIG(0, GAT_VCC); 2018 break; 2019 } 2020 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); 2021 switch (cmd->scan_begin_src) { 2022 case TRIG_TIMER: 2023 /* 2024 * Scan period timer CT1 needs to be 2025 * gated on to start counting. 2026 */ 2027 zgat = GAT_CONFIG(1, GAT_VCC); 2028 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); 2029 break; 2030 case TRIG_INT: 2031 async->inttrig = pci230_ai_inttrig_scan_begin; 2032 break; 2033 } 2034 } 2035 } else if (cmd->convert_src != TRIG_INT) { 2036 /* No longer need Z2-CT2. */ 2037 pci230_release_shared(dev, RES_Z2CT2, OWNER_AICMD); 2038 } 2039} 2040 2041static int pci230_ai_inttrig_start(struct comedi_device *dev, 2042 struct comedi_subdevice *s, 2043 unsigned int trig_num) 2044{ 2045 struct comedi_cmd *cmd = &s->async->cmd; 2046 2047 if (trig_num != cmd->start_arg) 2048 return -EINVAL; 2049 2050 s->async->inttrig = NULL; 2051 pci230_ai_start(dev, s); 2052 2053 return 1; 2054} 2055 2056static void pci230_handle_ai(struct comedi_device *dev, 2057 struct comedi_subdevice *s) 2058{ 2059 struct pci230_private *devpriv = dev->private; 2060 struct comedi_async *async = s->async; 2061 struct comedi_cmd *cmd = &async->cmd; 2062 unsigned int scanlen = cmd->scan_end_arg; 2063 unsigned int events = 0; 2064 unsigned int status_fifo; 2065 unsigned int i; 2066 unsigned int todo; 2067 unsigned int fifoamount; 2068 2069 /* Determine number of samples to read. */ 2070 if (cmd->stop_src != TRIG_COUNT) { 2071 todo = PCI230_ADC_FIFOLEVEL_HALFFULL; 2072 } else if (devpriv->ai_scan_count == 0) { 2073 todo = 0; 2074 } else if (devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL || 2075 scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL) { 2076 todo = PCI230_ADC_FIFOLEVEL_HALFFULL; 2077 } else { 2078 todo = devpriv->ai_scan_count * scanlen - devpriv->ai_scan_pos; 2079 if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL) 2080 todo = PCI230_ADC_FIFOLEVEL_HALFFULL; 2081 } 2082 if (todo == 0) 2083 return; 2084 fifoamount = 0; 2085 for (i = 0; i < todo; i++) { 2086 if (fifoamount == 0) { 2087 /* Read FIFO state. */ 2088 status_fifo = inw(devpriv->daqio + PCI230_ADCCON); 2089 if (status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) { 2090 /* 2091 * Report error otherwise FIFO overruns will go 2092 * unnoticed by the caller. 2093 */ 2094 dev_err(dev->class_dev, "AI FIFO overrun\n"); 2095 events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; 2096 break; 2097 } else if (status_fifo & PCI230_ADC_FIFO_EMPTY) { 2098 /* FIFO empty. */ 2099 break; 2100 } else if (status_fifo & PCI230_ADC_FIFO_HALF) { 2101 /* FIFO half full. */ 2102 fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL; 2103 } else if (devpriv->hwver > 0) { 2104 /* Read PCI230+/260+ ADC FIFO level. */ 2105 fifoamount = inw(devpriv->daqio + 2106 PCI230P_ADCFFLEV); 2107 if (fifoamount == 0) 2108 break; /* Shouldn't happen. */ 2109 } else { 2110 /* FIFO not empty. */ 2111 fifoamount = 1; 2112 } 2113 } 2114 /* Read sample and store in Comedi's circular buffer. */ 2115 if (comedi_buf_put(s, pci230_ai_read(dev)) == 0) { 2116 events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW; 2117 dev_err(dev->class_dev, "AI buffer overflow\n"); 2118 break; 2119 } 2120 fifoamount--; 2121 devpriv->ai_scan_pos++; 2122 if (devpriv->ai_scan_pos == scanlen) { 2123 /* End of scan. */ 2124 devpriv->ai_scan_pos = 0; 2125 devpriv->ai_scan_count--; 2126 async->events |= COMEDI_CB_EOS; 2127 } 2128 } 2129 if (cmd->stop_src == TRIG_COUNT && devpriv->ai_scan_count == 0) { 2130 /* End of acquisition. */ 2131 events |= COMEDI_CB_EOA; 2132 } else { 2133 /* More samples required, tell Comedi to block. */ 2134 events |= COMEDI_CB_BLOCK; 2135 } 2136 async->events |= events; 2137 if (async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | 2138 COMEDI_CB_OVERFLOW)) { 2139 /* disable hardware conversions */ 2140 pci230_ai_stop(dev, s); 2141 } else { 2142 /* update FIFO interrupt trigger level */ 2143 pci230_ai_update_fifo_trigger_level(dev, s); 2144 } 2145} 2146 2147static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 2148{ 2149 struct pci230_private *devpriv = dev->private; 2150 unsigned int i, chan, range, diff; 2151 unsigned int res_mask; 2152 unsigned short adccon, adcen; 2153 unsigned char zgat; 2154 2155 /* Get the command. */ 2156 struct comedi_async *async = s->async; 2157 struct comedi_cmd *cmd = &async->cmd; 2158 2159 /* 2160 * Determine which shared resources are needed. 2161 */ 2162 res_mask = 0; 2163 /* 2164 * Need Z2-CT2 to supply a conversion trigger source at a high 2165 * logic level, even if not doing timed conversions. 2166 */ 2167 res_mask |= RES_Z2CT2; 2168 if (cmd->scan_begin_src != TRIG_FOLLOW) { 2169 /* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */ 2170 res_mask |= RES_Z2CT0; 2171 if (cmd->scan_begin_src == TRIG_TIMER) { 2172 /* Using Z2-CT1 for scan frequency */ 2173 res_mask |= RES_Z2CT1; 2174 } 2175 } 2176 /* Claim resources. */ 2177 if (!pci230_claim_shared(dev, res_mask, OWNER_AICMD)) 2178 return -EBUSY; 2179 2180 devpriv->ai_scan_count = cmd->stop_arg; 2181 devpriv->ai_scan_pos = 0; /* Position within scan. */ 2182 2183 /* 2184 * Steps: 2185 * - Set channel scan list. 2186 * - Set channel gains. 2187 * - Enable and reset FIFO, specify uni/bip, se/diff, and set 2188 * start conversion source to point to something at a high logic 2189 * level (we use the output of counter/timer 2 for this purpose. 2190 * - PAUSE to allow things to settle down. 2191 * - Reset the FIFO again because it needs resetting twice and there 2192 * may have been a false conversion trigger on some versions of 2193 * PCI230/260 due to the start conversion source being set to a 2194 * high logic level. 2195 * - Enable ADC FIFO level interrupt. 2196 * - Set actual conversion trigger source and FIFO interrupt trigger 2197 * level. 2198 * - If convert_src is TRIG_TIMER, set up the timers. 2199 */ 2200 2201 adccon = PCI230_ADC_FIFO_EN; 2202 adcen = 0; 2203 2204 if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) { 2205 /* Differential - all channels must be differential. */ 2206 diff = 1; 2207 adccon |= PCI230_ADC_IM_DIF; 2208 } else { 2209 /* Single ended - all channels must be single-ended. */ 2210 diff = 0; 2211 adccon |= PCI230_ADC_IM_SE; 2212 } 2213 2214 range = CR_RANGE(cmd->chanlist[0]); 2215 devpriv->ai_bipolar = comedi_range_is_bipolar(s, range); 2216 if (devpriv->ai_bipolar) 2217 adccon |= PCI230_ADC_IR_BIP; 2218 else 2219 adccon |= PCI230_ADC_IR_UNI; 2220 2221 for (i = 0; i < cmd->chanlist_len; i++) { 2222 unsigned int gainshift; 2223 2224 chan = CR_CHAN(cmd->chanlist[i]); 2225 range = CR_RANGE(cmd->chanlist[i]); 2226 if (diff) { 2227 gainshift = 2 * chan; 2228 if (devpriv->hwver == 0) { 2229 /* 2230 * Original PCI230/260 expects both inputs of 2231 * the differential channel to be enabled. 2232 */ 2233 adcen |= 3 << gainshift; 2234 } else { 2235 /* 2236 * PCI230+/260+ expects only one input of the 2237 * differential channel to be enabled. 2238 */ 2239 adcen |= 1 << gainshift; 2240 } 2241 } else { 2242 gainshift = chan & ~1; 2243 adcen |= 1 << chan; 2244 } 2245 devpriv->adcg = (devpriv->adcg & ~(3 << gainshift)) | 2246 (pci230_ai_gain[range] << gainshift); 2247 } 2248 2249 /* Set channel scan list. */ 2250 outw(adcen, devpriv->daqio + PCI230_ADCEN); 2251 2252 /* Set channel gains. */ 2253 outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG); 2254 2255 /* 2256 * Set counter/timer 2 output high for use as the initial start 2257 * conversion source. 2258 */ 2259 i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE1); 2260 2261 /* 2262 * Temporarily use CT2 output as conversion trigger source and 2263 * temporarily set FIFO interrupt trigger level to 'full'. 2264 */ 2265 adccon |= PCI230_ADC_INT_FIFO_FULL | PCI230_ADC_TRIG_Z2CT2; 2266 2267 /* 2268 * Enable and reset FIFO, specify FIFO trigger level full, specify 2269 * uni/bip, se/diff, and temporarily set the start conversion source 2270 * to CT2 output. Note that CT2 output is currently high, and this 2271 * will produce a false conversion trigger on some versions of the 2272 * PCI230/260, but that will be dealt with later. 2273 */ 2274 devpriv->adccon = adccon; 2275 outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON); 2276 2277 /* 2278 * Delay - 2279 * Failure to include this will result in the first few channels'-worth 2280 * of data being corrupt, normally manifesting itself by large negative 2281 * voltages. It seems the board needs time to settle between the first 2282 * FIFO reset (above) and the second FIFO reset (below). Setting the 2283 * channel gains and scan list _before_ the first FIFO reset also 2284 * helps, though only slightly. 2285 */ 2286 usleep_range(25, 100); 2287 2288 /* Reset FIFO again. */ 2289 outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON); 2290 2291 if (cmd->convert_src == TRIG_TIMER) { 2292 /* 2293 * Set up CT2 as conversion timer, but gate it off for now. 2294 * Note, counter/timer output 2 can be monitored on the 2295 * connector: PCI230 pin 21, PCI260 pin 18. 2296 */ 2297 zgat = GAT_CONFIG(2, GAT_GND); 2298 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); 2299 /* Set counter/timer 2 to the specified conversion period. */ 2300 pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg, 2301 cmd->flags); 2302 if (cmd->scan_begin_src != TRIG_FOLLOW) { 2303 /* 2304 * Set up monostable on CT0 output for scan timing. A 2305 * rising edge on the trigger (gate) input of CT0 will 2306 * trigger the monostable, causing its output to go low 2307 * for the configured period. The period depends on 2308 * the conversion period and the number of conversions 2309 * in the scan. 2310 * 2311 * Set the trigger high before setting up the 2312 * monostable to stop it triggering. The trigger 2313 * source will be changed later. 2314 */ 2315 zgat = GAT_CONFIG(0, GAT_VCC); 2316 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); 2317 pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1, 2318 ((uint64_t)cmd->convert_arg * 2319 cmd->scan_end_arg), 2320 CMDF_ROUND_UP); 2321 if (cmd->scan_begin_src == TRIG_TIMER) { 2322 /* 2323 * Monostable on CT0 will be triggered by 2324 * output of CT1 at configured scan frequency. 2325 * 2326 * Set up CT1 but gate it off for now. 2327 */ 2328 zgat = GAT_CONFIG(1, GAT_GND); 2329 outb(zgat, dev->iobase + PCI230_ZGAT_SCE); 2330 pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3, 2331 cmd->scan_begin_arg, 2332 cmd->flags); 2333 } 2334 } 2335 } 2336 2337 if (cmd->start_src == TRIG_INT) 2338 s->async->inttrig = pci230_ai_inttrig_start; 2339 else /* TRIG_NOW */ 2340 pci230_ai_start(dev, s); 2341 2342 return 0; 2343} 2344 2345static int pci230_ai_cancel(struct comedi_device *dev, 2346 struct comedi_subdevice *s) 2347{ 2348 pci230_ai_stop(dev, s); 2349 return 0; 2350} 2351 2352/* Interrupt handler */ 2353static irqreturn_t pci230_interrupt(int irq, void *d) 2354{ 2355 unsigned char status_int, valid_status_int, temp_ier; 2356 struct comedi_device *dev = (struct comedi_device *)d; 2357 struct pci230_private *devpriv = dev->private; 2358 struct comedi_subdevice *s; 2359 unsigned long irqflags; 2360 2361 /* Read interrupt status/enable register. */ 2362 status_int = inb(dev->iobase + PCI230_INT_STAT); 2363 2364 if (status_int == PCI230_INT_DISABLE) 2365 return IRQ_NONE; 2366 2367 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); 2368 valid_status_int = devpriv->ier & status_int; 2369 /* 2370 * Disable triggered interrupts. 2371 * (Only those interrupts that need re-enabling, are, later in the 2372 * handler). 2373 */ 2374 temp_ier = devpriv->ier & ~status_int; 2375 outb(temp_ier, dev->iobase + PCI230_INT_SCE); 2376 devpriv->intr_running = true; 2377 devpriv->intr_cpuid = THISCPU; 2378 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); 2379 2380 /* 2381 * Check the source of interrupt and handle it. 2382 * The PCI230 can cope with concurrent ADC, DAC, PPI C0 and C3 2383 * interrupts. However, at present (Comedi-0.7.60) does not allow 2384 * concurrent execution of commands, instructions or a mixture of the 2385 * two. 2386 */ 2387 2388 if (valid_status_int & PCI230_INT_ZCLK_CT1) { 2389 s = dev->write_subdev; 2390 pci230_handle_ao_nofifo(dev, s); 2391 comedi_event(dev, s); 2392 } 2393 2394 if (valid_status_int & PCI230P2_INT_DAC) { 2395 s = dev->write_subdev; 2396 pci230_handle_ao_fifo(dev, s); 2397 comedi_event(dev, s); 2398 } 2399 2400 if (valid_status_int & PCI230_INT_ADC) { 2401 s = dev->read_subdev; 2402 pci230_handle_ai(dev, s); 2403 comedi_event(dev, s); 2404 } 2405 2406 /* Reenable interrupts. */ 2407 spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); 2408 if (devpriv->ier != temp_ier) 2409 outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); 2410 devpriv->intr_running = false; 2411 spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); 2412 2413 return IRQ_HANDLED; 2414} 2415 2416/* Check if PCI device matches a specific board. */ 2417static bool pci230_match_pci_board(const struct pci230_board *board, 2418 struct pci_dev *pci_dev) 2419{ 2420 /* assume pci_dev->device != PCI_DEVICE_ID_INVALID */ 2421 if (board->id != pci_dev->device) 2422 return false; 2423 if (board->min_hwver == 0) 2424 return true; 2425 /* Looking for a '+' model. First check length of registers. */ 2426 if (pci_resource_len(pci_dev, 3) < 32) 2427 return false; /* Not a '+' model. */ 2428 /* 2429 * TODO: temporarily enable PCI device and read the hardware version 2430 * register. For now, assume it's okay. 2431 */ 2432 return true; 2433} 2434 2435/* Look for board matching PCI device. */ 2436static const struct pci230_board *pci230_find_pci_board(struct pci_dev *pci_dev) 2437{ 2438 unsigned int i; 2439 2440 for (i = 0; i < ARRAY_SIZE(pci230_boards); i++) 2441 if (pci230_match_pci_board(&pci230_boards[i], pci_dev)) 2442 return &pci230_boards[i]; 2443 return NULL; 2444} 2445 2446static int pci230_auto_attach(struct comedi_device *dev, 2447 unsigned long context_unused) 2448{ 2449 struct pci_dev *pci_dev = comedi_to_pci_dev(dev); 2450 const struct pci230_board *thisboard; 2451 struct pci230_private *devpriv; 2452 struct comedi_subdevice *s; 2453 int rc; 2454 2455 dev_info(dev->class_dev, "amplc_pci230: attach pci %s\n", 2456 pci_name(pci_dev)); 2457 2458 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 2459 if (!devpriv) 2460 return -ENOMEM; 2461 2462 spin_lock_init(&devpriv->isr_spinlock); 2463 spin_lock_init(&devpriv->res_spinlock); 2464 spin_lock_init(&devpriv->ai_stop_spinlock); 2465 spin_lock_init(&devpriv->ao_stop_spinlock); 2466 2467 dev->board_ptr = pci230_find_pci_board(pci_dev); 2468 if (dev->board_ptr == NULL) { 2469 dev_err(dev->class_dev, 2470 "amplc_pci230: BUG! cannot determine board type!\n"); 2471 return -EINVAL; 2472 } 2473 thisboard = dev->board_ptr; 2474 dev->board_name = thisboard->name; 2475 2476 rc = comedi_pci_enable(dev); 2477 if (rc) 2478 return rc; 2479 2480 /* 2481 * Read base addresses of the PCI230's two I/O regions from PCI 2482 * configuration register. 2483 */ 2484 dev->iobase = pci_resource_start(pci_dev, 2); 2485 devpriv->daqio = pci_resource_start(pci_dev, 3); 2486 dev_dbg(dev->class_dev, 2487 "%s I/O region 1 0x%04lx I/O region 2 0x%04lx\n", 2488 dev->board_name, dev->iobase, devpriv->daqio); 2489 /* Read bits of DACCON register - only the output range. */ 2490 devpriv->daccon = inw(devpriv->daqio + PCI230_DACCON) & 2491 PCI230_DAC_OR_MASK; 2492 /* 2493 * Read hardware version register and set extended function register 2494 * if they exist. 2495 */ 2496 if (pci_resource_len(pci_dev, 3) >= 32) { 2497 unsigned short extfunc = 0; 2498 2499 devpriv->hwver = inw(devpriv->daqio + PCI230P_HWVER); 2500 if (devpriv->hwver < thisboard->min_hwver) { 2501 dev_err(dev->class_dev, 2502 "%s - bad hardware version - got %u, need %u\n", 2503 dev->board_name, devpriv->hwver, 2504 thisboard->min_hwver); 2505 return -EIO; 2506 } 2507 if (devpriv->hwver > 0) { 2508 if (!thisboard->have_dio) { 2509 /* 2510 * No DIO ports. Route counters' external gates 2511 * to the EXTTRIG signal (PCI260+ pin 17). 2512 * (Otherwise, they would be routed to DIO 2513 * inputs PC0, PC1 and PC2 which don't exist 2514 * on PCI260[+].) 2515 */ 2516 extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG; 2517 } 2518 if (thisboard->ao_bits && devpriv->hwver >= 2) { 2519 /* Enable DAC FIFO functionality. */ 2520 extfunc |= PCI230P2_EXTFUNC_DACFIFO; 2521 } 2522 } 2523 outw(extfunc, devpriv->daqio + PCI230P_EXTFUNC); 2524 if (extfunc & PCI230P2_EXTFUNC_DACFIFO) { 2525 /* 2526 * Temporarily enable DAC FIFO, reset it and disable 2527 * FIFO wraparound. 2528 */ 2529 outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN | 2530 PCI230P2_DAC_FIFO_RESET, 2531 devpriv->daqio + PCI230_DACCON); 2532 /* Clear DAC FIFO channel enable register. */ 2533 outw(0, devpriv->daqio + PCI230P2_DACEN); 2534 /* Disable DAC FIFO. */ 2535 outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON); 2536 } 2537 } 2538 /* Disable board's interrupts. */ 2539 outb(0, dev->iobase + PCI230_INT_SCE); 2540 /* Set ADC to a reasonable state. */ 2541 devpriv->adcg = 0; 2542 devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE | 2543 PCI230_ADC_IR_BIP; 2544 outw(1 << 0, devpriv->daqio + PCI230_ADCEN); 2545 outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG); 2546 outw(devpriv->adccon | PCI230_ADC_FIFO_RESET, 2547 devpriv->daqio + PCI230_ADCCON); 2548 2549 if (pci_dev->irq) { 2550 rc = request_irq(pci_dev->irq, pci230_interrupt, IRQF_SHARED, 2551 dev->board_name, dev); 2552 if (rc == 0) 2553 dev->irq = pci_dev->irq; 2554 } 2555 2556 rc = comedi_alloc_subdevices(dev, 3); 2557 if (rc) 2558 return rc; 2559 2560 s = &dev->subdevices[0]; 2561 /* analog input subdevice */ 2562 s->type = COMEDI_SUBD_AI; 2563 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND; 2564 s->n_chan = 16; 2565 s->maxdata = (1 << thisboard->ai_bits) - 1; 2566 s->range_table = &pci230_ai_range; 2567 s->insn_read = pci230_ai_insn_read; 2568 s->len_chanlist = 256; /* but there are restrictions. */ 2569 if (dev->irq) { 2570 dev->read_subdev = s; 2571 s->subdev_flags |= SDF_CMD_READ; 2572 s->do_cmd = pci230_ai_cmd; 2573 s->do_cmdtest = pci230_ai_cmdtest; 2574 s->cancel = pci230_ai_cancel; 2575 } 2576 2577 s = &dev->subdevices[1]; 2578 /* analog output subdevice */ 2579 if (thisboard->ao_bits) { 2580 s->type = COMEDI_SUBD_AO; 2581 s->subdev_flags = SDF_WRITABLE | SDF_GROUND; 2582 s->n_chan = 2; 2583 s->maxdata = (1 << thisboard->ao_bits) - 1; 2584 s->range_table = &pci230_ao_range; 2585 s->insn_write = pci230_ao_insn_write; 2586 s->insn_read = comedi_readback_insn_read; 2587 s->len_chanlist = 2; 2588 if (dev->irq) { 2589 dev->write_subdev = s; 2590 s->subdev_flags |= SDF_CMD_WRITE; 2591 s->do_cmd = pci230_ao_cmd; 2592 s->do_cmdtest = pci230_ao_cmdtest; 2593 s->cancel = pci230_ao_cancel; 2594 } 2595 2596 rc = comedi_alloc_subdev_readback(s); 2597 if (rc) 2598 return rc; 2599 } else { 2600 s->type = COMEDI_SUBD_UNUSED; 2601 } 2602 2603 s = &dev->subdevices[2]; 2604 /* digital i/o subdevice */ 2605 if (thisboard->have_dio) { 2606 rc = subdev_8255_init(dev, s, NULL, PCI230_PPI_X_BASE); 2607 if (rc) 2608 return rc; 2609 } else { 2610 s->type = COMEDI_SUBD_UNUSED; 2611 } 2612 2613 return 0; 2614} 2615 2616static struct comedi_driver amplc_pci230_driver = { 2617 .driver_name = "amplc_pci230", 2618 .module = THIS_MODULE, 2619 .auto_attach = pci230_auto_attach, 2620 .detach = comedi_pci_detach, 2621}; 2622 2623static int amplc_pci230_pci_probe(struct pci_dev *dev, 2624 const struct pci_device_id *id) 2625{ 2626 return comedi_pci_auto_config(dev, &lc_pci230_driver, 2627 id->driver_data); 2628} 2629 2630static const struct pci_device_id amplc_pci230_pci_table[] = { 2631 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230) }, 2632 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260) }, 2633 { 0 } 2634}; 2635MODULE_DEVICE_TABLE(pci, amplc_pci230_pci_table); 2636 2637static struct pci_driver amplc_pci230_pci_driver = { 2638 .name = "amplc_pci230", 2639 .id_table = amplc_pci230_pci_table, 2640 .probe = amplc_pci230_pci_probe, 2641 .remove = comedi_pci_auto_unconfig, 2642}; 2643module_comedi_pci_driver(amplc_pci230_driver, amplc_pci230_pci_driver); 2644 2645MODULE_AUTHOR("Comedi http://www.comedi.org"); 2646MODULE_DESCRIPTION("Comedi driver for Amplicon PCI230(+) and PCI260(+)"); 2647MODULE_LICENSE("GPL"); 2648