Merge remote-tracking branch 'staging/staging-next'
[deliverable/linux.git] / drivers / staging / comedi / drivers / cb_pcidas64.c
CommitLineData
88b12a9a 1/*
28fec2e6
AJ
2 * comedi/drivers/cb_pcidas64.c
3 * This is a driver for the ComputerBoards/MeasurementComputing PCI-DAS
4 * 64xx, 60xx, and 4020 cards.
5 *
6 * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
7 * Copyright (C) 2001, 2002 Frank Mori Hess
8 *
9 * Thanks also go to the following people:
10 *
11 * Steve Rosenbluth, for providing the source code for
12 * his pci-das6402 driver, and source code for working QNX pci-6402
13 * drivers by Greg Laird and Mariusz Bogacz. None of the code was
14 * used directly here, but it was useful as an additional source of
15 * documentation on how to program the boards.
16 *
17 * John Sims, for much testing and feedback on pcidas-4020 support.
18 *
19 * COMEDI - Linux Control and Measurement Device Interface
20 * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
21 *
22 * This program is free software; you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License as published by
24 * the Free Software Foundation; either version 2 of the License, or
25 * (at your option) any later version.
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
31 */
88b12a9a
FMH
32
33/*
11aade26
IA
34 * Driver: cb_pcidas64
35 * Description: MeasurementComputing PCI-DAS64xx, 60XX, and 4020 series
36 * with the PLX 9080 PCI controller
37 * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
38 * Status: works
39 * Updated: Fri, 02 Nov 2012 18:58:55 +0000
40 * Devices: [Measurement Computing] PCI-DAS6402/16 (cb_pcidas64),
41 * PCI-DAS6402/12, PCI-DAS64/M1/16, PCI-DAS64/M2/16,
42 * PCI-DAS64/M3/16, PCI-DAS6402/16/JR, PCI-DAS64/M1/16/JR,
43 * PCI-DAS64/M2/16/JR, PCI-DAS64/M3/16/JR, PCI-DAS64/M1/14,
44 * PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6013, PCI-DAS6014,
45 * PCI-DAS6023, PCI-DAS6025, PCI-DAS6030,
46 * PCI-DAS6031, PCI-DAS6032, PCI-DAS6033, PCI-DAS6034,
47 * PCI-DAS6035, PCI-DAS6036, PCI-DAS6040, PCI-DAS6052,
48 * PCI-DAS6070, PCI-DAS6071, PCI-DAS4020/12
49 *
50 * Configuration options:
51 * None.
52 *
53 * Manual attachment of PCI cards with the comedi_config utility is not
54 * supported by this driver; they are attached automatically.
55 *
56 * These boards may be autocalibrated with the comedi_calibrate utility.
57 *
58 * To select the bnc trigger input on the 4020 (instead of the dio input),
59 * specify a nonzero channel in the chanspec. If you wish to use an external
60 * master clock on the 4020, you may do so by setting the scan_begin_src
61 * to TRIG_OTHER, and using an INSN_CONFIG_TIMER_1 configuration insn
62 * to configure the divisor to use for the external clock.
63 *
64 * Some devices are not identified because the PCI device IDs are not yet
65 * known. If you have such a board, please let the maintainers know.
66 */
88b12a9a
FMH
67
68/*
28fec2e6
AJ
69 * TODO:
70 * make it return error if user attempts an ai command that uses the
71 * external queue, and an ao command simultaneously user counter subdevice
72 * there are a number of boards this driver will support when they are
73 * fully released, but does not yet since the pci device id numbers
74 * are not yet available.
75 *
76 * support prescaled 100khz clock for slow pacing (not available on 6000
77 * series?)
78 *
79 * make ao fifo size adjustable like ai fifo
80 */
88b12a9a 81
ce157f80 82#include <linux/module.h>
88b12a9a 83#include <linux/delay.h>
70265d24 84#include <linux/interrupt.h>
88b12a9a 85
32640680 86#include "../comedi_pci.h"
33782dd5 87
88b12a9a
FMH
88#include "8255.h"
89#include "plx9080.h"
88b12a9a 90
9ef4dea6 91#define TIMER_BASE 25 /* 40MHz master clock */
28fec2e6
AJ
92/*
93 * 100kHz 'prescaled' clock for slow acquisition,
94 * maybe I'll support this someday
95 */
46ca84c4 96#define PRESCALED_TIMER_BASE 10000
9f963096
AJ
97#define DMA_BUFFER_SIZE 0x1000
98#define DAC_FIFO_SIZE 0x2000
88b12a9a 99
28fec2e6 100/* maximum value that can be loaded into board's 24-bit counters */
88b12a9a
FMH
101static const int max_counter_value = 0xffffff;
102
103/* PCI-DAS64xxx base addresses */
104
681d335a 105/* devpriv->main_iobase registers */
88b12a9a 106enum write_only_registers {
28fec2e6
AJ
107 INTR_ENABLE_REG = 0x0, /* interrupt enable register */
108 HW_CONFIG_REG = 0x2, /* hardware config register */
88b12a9a
FMH
109 DAQ_SYNC_REG = 0xc,
110 DAQ_ATRIG_LOW_4020_REG = 0xc,
28fec2e6
AJ
111 ADC_CONTROL0_REG = 0x10, /* adc control register 0 */
112 ADC_CONTROL1_REG = 0x12, /* adc control register 1 */
88b12a9a 113 CALIBRATION_REG = 0x14,
28fec2e6 114 /* lower 16 bits of adc sample interval counter */
46ca84c4 115 ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16,
28fec2e6 116 /* upper 8 bits of adc sample interval counter */
46ca84c4 117 ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18,
28fec2e6 118 /* lower 16 bits of delay interval counter */
46ca84c4 119 ADC_DELAY_INTERVAL_LOWER_REG = 0x1a,
28fec2e6 120 /* upper 8 bits of delay interval counter */
46ca84c4 121 ADC_DELAY_INTERVAL_UPPER_REG = 0x1c,
28fec2e6 122 /* lower 16 bits of hardware conversion/scan counter */
46ca84c4 123 ADC_COUNT_LOWER_REG = 0x1e,
28fec2e6 124 /* upper 8 bits of hardware conversion/scan counter */
46ca84c4 125 ADC_COUNT_UPPER_REG = 0x20,
28fec2e6
AJ
126 ADC_START_REG = 0x22, /* software trigger to start acquisition */
127 ADC_CONVERT_REG = 0x24, /* initiates single conversion */
128 ADC_QUEUE_CLEAR_REG = 0x26, /* clears adc queue */
129 ADC_QUEUE_LOAD_REG = 0x28, /* loads adc queue */
88b12a9a 130 ADC_BUFFER_CLEAR_REG = 0x2a,
28fec2e6 131 /* high channel for internal queue, use adc_chan_bits() inline above */
46ca84c4 132 ADC_QUEUE_HIGH_REG = 0x2c,
28fec2e6
AJ
133 DAC_CONTROL0_REG = 0x50, /* dac control register 0 */
134 DAC_CONTROL1_REG = 0x52, /* dac control register 0 */
135 /* lower 16 bits of dac sample interval counter */
46ca84c4 136 DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54,
28fec2e6 137 /* upper 8 bits of dac sample interval counter */
46ca84c4 138 DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56,
88b12a9a
FMH
139 DAC_SELECT_REG = 0x60,
140 DAC_START_REG = 0x64,
28fec2e6 141 DAC_BUFFER_CLEAR_REG = 0x66, /* clear dac buffer */
88b12a9a 142};
46ca84c4 143
88b12a9a
FMH
144static inline unsigned int dac_convert_reg(unsigned int channel)
145{
146 return 0x70 + (2 * (channel & 0x1));
147}
0a85b6f0 148
88b12a9a
FMH
149static inline unsigned int dac_lsb_4020_reg(unsigned int channel)
150{
151 return 0x70 + (4 * (channel & 0x1));
152}
0a85b6f0 153
88b12a9a
FMH
154static inline unsigned int dac_msb_4020_reg(unsigned int channel)
155{
156 return 0x72 + (4 * (channel & 0x1));
157}
158
159enum read_only_registers {
85c12b82
AD
160 /*
161 * hardware status register,
162 * reading this apparently clears pending interrupts as well
163 */
46ca84c4 164 HW_STATUS_REG = 0x0,
88b12a9a
FMH
165 PIPE1_READ_REG = 0x4,
166 ADC_READ_PNTR_REG = 0x8,
167 LOWER_XFER_REG = 0x10,
168 ADC_WRITE_PNTR_REG = 0xc,
169 PREPOST_REG = 0x14,
170};
171
172enum read_write_registers {
12f992ad
AJ
173 I8255_4020_REG = 0x48, /* 8255 offset, for 4020 only */
174 /* external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG */
46ca84c4 175 ADC_QUEUE_FIFO_REG = 0x100,
88b12a9a 176 ADC_FIFO_REG = 0x200, /* adc data fifo */
46ca84c4
IA
177 /* dac data fifo, has weird interactions with external channel queue */
178 DAC_FIFO_REG = 0x300,
88b12a9a
FMH
179};
180
9ebd1028 181/* dev->mmio registers */
88b12a9a
FMH
182enum dio_counter_registers {
183 DIO_8255_OFFSET = 0x0,
184 DO_REG = 0x20,
185 DI_REG = 0x28,
186 DIO_DIRECTION_60XX_REG = 0x40,
187 DIO_DATA_60XX_REG = 0x48,
188};
189
9ef4dea6 190/* bit definitions for write-only registers */
88b12a9a
FMH
191
192enum intr_enable_contents {
12f992ad
AJ
193 ADC_INTR_SRC_MASK = 0x3, /* adc interrupt source mask */
194 ADC_INTR_QFULL_BITS = 0x0, /* interrupt fifo quarter full */
195 ADC_INTR_EOC_BITS = 0x1, /* interrupt end of conversion */
196 ADC_INTR_EOSCAN_BITS = 0x2, /* interrupt end of scan */
197 ADC_INTR_EOSEQ_BITS = 0x3, /* interrupt end of sequence mask */
198 EN_ADC_INTR_SRC_BIT = 0x4, /* enable adc interrupt source */
199 EN_ADC_DONE_INTR_BIT = 0x8, /* enable adc acquisition done intr */
88b12a9a
FMH
200 DAC_INTR_SRC_MASK = 0x30,
201 DAC_INTR_QEMPTY_BITS = 0x0,
202 DAC_INTR_HIGH_CHAN_BITS = 0x10,
12f992ad 203 EN_DAC_INTR_SRC_BIT = 0x40, /* enable dac interrupt source */
88b12a9a 204 EN_DAC_DONE_INTR_BIT = 0x80,
12f992ad
AJ
205 EN_ADC_ACTIVE_INTR_BIT = 0x200, /* enable adc active interrupt */
206 EN_ADC_STOP_INTR_BIT = 0x400, /* enable adc stop trigger interrupt */
207 EN_DAC_ACTIVE_INTR_BIT = 0x800, /* enable dac active interrupt */
208 EN_DAC_UNDERRUN_BIT = 0x4000, /* enable dac underrun status bit */
209 EN_ADC_OVERRUN_BIT = 0x8000, /* enable adc overrun status bit */
88b12a9a
FMH
210};
211
212enum hw_config_contents {
12f992ad
AJ
213 MASTER_CLOCK_4020_MASK = 0x3, /* master clock source mask for 4020 */
214 INTERNAL_CLOCK_4020_BITS = 0x1, /* use 40 MHz internal master clock */
215 BNC_CLOCK_4020_BITS = 0x2, /* use BNC input for master clock */
216 EXT_CLOCK_4020_BITS = 0x3, /* use dio input for master clock */
217 EXT_QUEUE_BIT = 0x200, /* use external channel/gain queue */
218 /* use 225 nanosec strobe when loading dac instead of 50 nanosec */
46ca84c4 219 SLOW_DAC_BIT = 0x400,
12f992ad
AJ
220 /*
221 * bit with unknown function yet given as default value in pci-das64
222 * manual
28fec2e6 223 */
46ca84c4 224 HW_CONFIG_DUMMY_BITS = 0x2000,
12f992ad 225 /* bit selects channels 1/0 for analog input/output, otherwise 0/1 */
46ca84c4 226 DMA_CH_SELECT_BIT = 0x8000,
12f992ad
AJ
227 FIFO_SIZE_REG = 0x4, /* allows adjustment of fifo sizes */
228 DAC_FIFO_SIZE_MASK = 0xff00, /* bits that set dac fifo size */
229 DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */
88b12a9a 230};
88b12a9a
FMH
231
232enum daq_atrig_low_4020_contents {
12f992ad 233 /* use trig/ext clk bnc input for analog gate signal */
46ca84c4 234 EXT_AGATE_BNC_BIT = 0x8000,
12f992ad 235 /* use trig/ext clk bnc input for external stop trigger signal */
46ca84c4 236 EXT_STOP_TRIG_BNC_BIT = 0x4000,
12f992ad 237 /* use trig/ext clk bnc input for external start trigger signal */
46ca84c4 238 EXT_START_TRIG_BNC_BIT = 0x2000,
88b12a9a 239};
46ca84c4 240
88b12a9a
FMH
241static inline uint16_t analog_trig_low_threshold_bits(uint16_t threshold)
242{
243 return threshold & 0xfff;
244}
245
246enum adc_control0_contents {
12f992ad
AJ
247 ADC_GATE_SRC_MASK = 0x3, /* bits that select gate */
248 ADC_SOFT_GATE_BITS = 0x1, /* software gate */
249 ADC_EXT_GATE_BITS = 0x2, /* external digital gate */
250 ADC_ANALOG_GATE_BITS = 0x3, /* analog level gate */
251 /* level-sensitive gate (for digital) */
f51ff7e4 252 ADC_GATE_LEVEL_BIT = 0x4,
12f992ad 253 ADC_GATE_POLARITY_BIT = 0x8, /* gate active low */
88b12a9a
FMH
254 ADC_START_TRIG_SOFT_BITS = 0x10,
255 ADC_START_TRIG_EXT_BITS = 0x20,
256 ADC_START_TRIG_ANALOG_BITS = 0x30,
257 ADC_START_TRIG_MASK = 0x30,
12f992ad
AJ
258 ADC_START_TRIG_FALLING_BIT = 0x40, /* trig 1 uses falling edge */
259 /* external pacing uses falling edge */
46ca84c4 260 ADC_EXT_CONV_FALLING_BIT = 0x800,
12f992ad 261 /* enable hardware scan counter */
46ca84c4 262 ADC_SAMPLE_COUNTER_EN_BIT = 0x1000,
12f992ad
AJ
263 ADC_DMA_DISABLE_BIT = 0x4000, /* disables dma */
264 ADC_ENABLE_BIT = 0x8000, /* master adc enable */
88b12a9a
FMH
265};
266
267enum adc_control1_contents {
12f992ad 268 /* should be set for boards with > 16 channels */
46ca84c4 269 ADC_QUEUE_CONFIG_BIT = 0x1,
88b12a9a
FMH
270 CONVERT_POLARITY_BIT = 0x10,
271 EOC_POLARITY_BIT = 0x20,
12f992ad
AJ
272 ADC_SW_GATE_BIT = 0x40, /* software gate of adc */
273 ADC_DITHER_BIT = 0x200, /* turn on extra noise for dithering */
88b12a9a
FMH
274 RETRIGGER_BIT = 0x800,
275 ADC_LO_CHANNEL_4020_MASK = 0x300,
276 ADC_HI_CHANNEL_4020_MASK = 0xc00,
12f992ad
AJ
277 TWO_CHANNEL_4020_BITS = 0x1000, /* two channel mode for 4020 */
278 FOUR_CHANNEL_4020_BITS = 0x2000, /* four channel mode for 4020 */
88b12a9a
FMH
279 CHANNEL_MODE_4020_MASK = 0x3000,
280 ADC_MODE_MASK = 0xf000,
281};
46ca84c4 282
88b12a9a
FMH
283static inline uint16_t adc_lo_chan_4020_bits(unsigned int channel)
284{
285 return (channel & 0x3) << 8;
286};
0a85b6f0 287
88b12a9a
FMH
288static inline uint16_t adc_hi_chan_4020_bits(unsigned int channel)
289{
290 return (channel & 0x3) << 10;
291};
0a85b6f0 292
88b12a9a
FMH
293static inline uint16_t adc_mode_bits(unsigned int mode)
294{
295 return (mode & 0xf) << 12;
296};
297
298enum calibration_contents {
299 SELECT_8800_BIT = 0x1,
300 SELECT_8402_64XX_BIT = 0x2,
301 SELECT_1590_60XX_BIT = 0x2,
12f992ad 302 CAL_EN_64XX_BIT = 0x40, /* calibration enable for 64xx series */
88b12a9a
FMH
303 SERIAL_DATA_IN_BIT = 0x80,
304 SERIAL_CLOCK_BIT = 0x100,
12f992ad 305 CAL_EN_60XX_BIT = 0x200, /* calibration enable for 60xx series */
88b12a9a
FMH
306 CAL_GAIN_BIT = 0x800,
307};
46ca84c4 308
85c12b82
AD
309/*
310 * calibration sources for 6025 are:
88b12a9a
FMH
311 * 0 : ground
312 * 1 : 10V
313 * 2 : 5V
314 * 3 : 0.5V
315 * 4 : 0.05V
316 * 5 : ground
317 * 6 : dac channel 0
318 * 7 : dac channel 1
319 */
46ca84c4 320
88b12a9a
FMH
321static inline uint16_t adc_src_bits(unsigned int source)
322{
323 return (source & 0xf) << 3;
324};
325
326static inline uint16_t adc_convert_chan_4020_bits(unsigned int channel)
327{
328 return (channel & 0x3) << 8;
329};
330
331enum adc_queue_load_contents {
12f992ad
AJ
332 UNIP_BIT = 0x800, /* unipolar/bipolar bit */
333 ADC_SE_DIFF_BIT = 0x1000, /* single-ended/ differential bit */
334 /* non-referenced single-ended (common-mode input) */
46ca84c4 335 ADC_COMMON_BIT = 0x2000,
12f992ad
AJ
336 QUEUE_EOSEQ_BIT = 0x4000, /* queue end of sequence */
337 QUEUE_EOSCAN_BIT = 0x8000, /* queue end of scan */
88b12a9a 338};
46ca84c4 339
88b12a9a
FMH
340static inline uint16_t adc_chan_bits(unsigned int channel)
341{
342 return channel & 0x3f;
343};
344
345enum dac_control0_contents {
12f992ad 346 DAC_ENABLE_BIT = 0x8000, /* dac controller enable bit */
88b12a9a
FMH
347 DAC_CYCLIC_STOP_BIT = 0x4000,
348 DAC_WAVEFORM_MODE_BIT = 0x100,
349 DAC_EXT_UPDATE_FALLING_BIT = 0x80,
350 DAC_EXT_UPDATE_ENABLE_BIT = 0x40,
351 WAVEFORM_TRIG_MASK = 0x30,
352 WAVEFORM_TRIG_DISABLED_BITS = 0x0,
353 WAVEFORM_TRIG_SOFT_BITS = 0x10,
354 WAVEFORM_TRIG_EXT_BITS = 0x20,
355 WAVEFORM_TRIG_ADC1_BITS = 0x30,
356 WAVEFORM_TRIG_FALLING_BIT = 0x8,
357 WAVEFORM_GATE_LEVEL_BIT = 0x4,
358 WAVEFORM_GATE_ENABLE_BIT = 0x2,
359 WAVEFORM_GATE_SELECT_BIT = 0x1,
360};
361
362enum dac_control1_contents {
363 DAC_WRITE_POLARITY_BIT = 0x800, /* board-dependent setting */
364 DAC1_EXT_REF_BIT = 0x200,
365 DAC0_EXT_REF_BIT = 0x100,
12f992ad 366 DAC_OUTPUT_ENABLE_BIT = 0x80, /* dac output enable bit */
88b12a9a
FMH
367 DAC_UPDATE_POLARITY_BIT = 0x40, /* board-dependent setting */
368 DAC_SW_GATE_BIT = 0x20,
369 DAC1_UNIPOLAR_BIT = 0x8,
370 DAC0_UNIPOLAR_BIT = 0x2,
371};
372
9ef4dea6 373/* bit definitions for read-only registers */
88b12a9a
FMH
374enum hw_status_contents {
375 DAC_UNDERRUN_BIT = 0x1,
376 ADC_OVERRUN_BIT = 0x2,
377 DAC_ACTIVE_BIT = 0x4,
378 ADC_ACTIVE_BIT = 0x8,
379 DAC_INTR_PENDING_BIT = 0x10,
380 ADC_INTR_PENDING_BIT = 0x20,
381 DAC_DONE_BIT = 0x40,
382 ADC_DONE_BIT = 0x80,
383 EXT_INTR_PENDING_BIT = 0x100,
384 ADC_STOP_BIT = 0x200,
385};
46ca84c4 386
88b12a9a
FMH
387static inline uint16_t pipe_full_bits(uint16_t hw_status_bits)
388{
389 return (hw_status_bits >> 10) & 0x3;
390};
391
392static inline unsigned int dma_chain_flag_bits(uint16_t prepost_bits)
393{
394 return (prepost_bits >> 6) & 0x3;
395}
0a85b6f0 396
88b12a9a
FMH
397static inline unsigned int adc_upper_read_ptr_code(uint16_t prepost_bits)
398{
399 return (prepost_bits >> 12) & 0x3;
400}
0a85b6f0 401
88b12a9a
FMH
402static inline unsigned int adc_upper_write_ptr_code(uint16_t prepost_bits)
403{
404 return (prepost_bits >> 14) & 0x3;
405}
406
9ef4dea6 407/* I2C addresses for 4020 */
88b12a9a
FMH
408enum i2c_addresses {
409 RANGE_CAL_I2C_ADDR = 0x20,
410 CALDAC0_I2C_ADDR = 0xc,
411 CALDAC1_I2C_ADDR = 0xd,
412};
413
414enum range_cal_i2c_contents {
12f992ad 415 /* bits that set what source the adc converter measures */
46ca84c4 416 ADC_SRC_4020_MASK = 0x70,
12f992ad 417 /* make bnc trig/ext clock threshold 0V instead of 2.5V */
46ca84c4 418 BNC_TRIG_THRESHOLD_0V_BIT = 0x80,
88b12a9a 419};
46ca84c4 420
88b12a9a
FMH
421static inline uint8_t adc_src_4020_bits(unsigned int source)
422{
423 return (source << 4) & ADC_SRC_4020_MASK;
424};
0a85b6f0 425
88b12a9a
FMH
426static inline uint8_t attenuate_bit(unsigned int channel)
427{
12f992ad 428 /* attenuate channel (+-5V input range) */
88b12a9a
FMH
429 return 1 << (channel & 0x3);
430};
431
9ef4dea6 432/* analog input ranges for 64xx boards */
9ced1de6 433static const struct comedi_lrange ai_ranges_64xx = {
82dc1255
HS
434 8, {
435 BIP_RANGE(10),
436 BIP_RANGE(5),
437 BIP_RANGE(2.5),
438 BIP_RANGE(1.25),
439 UNI_RANGE(10),
440 UNI_RANGE(5),
441 UNI_RANGE(2.5),
442 UNI_RANGE(1.25)
443 }
88b12a9a
FMH
444};
445
be8e8908
IA
446static const uint8_t ai_range_code_64xx[8] = {
447 0x0, 0x1, 0x2, 0x3, /* bipolar 10, 5, 2,5, 1.25 */
448 0x8, 0x9, 0xa, 0xb /* unipolar 10, 5, 2.5, 1.25 */
449};
450
451/* analog input ranges for 64-Mx boards */
452static const struct comedi_lrange ai_ranges_64_mx = {
453 7, {
454 BIP_RANGE(5),
455 BIP_RANGE(2.5),
456 BIP_RANGE(1.25),
457 BIP_RANGE(0.625),
458 UNI_RANGE(5),
459 UNI_RANGE(2.5),
460 UNI_RANGE(1.25)
461 }
462};
463
464static const uint8_t ai_range_code_64_mx[7] = {
465 0x0, 0x1, 0x2, 0x3, /* bipolar 5, 2.5, 1.25, 0.625 */
466 0x9, 0xa, 0xb /* unipolar 5, 2.5, 1.25 */
467};
468
88b12a9a 469/* analog input ranges for 60xx boards */
9ced1de6 470static const struct comedi_lrange ai_ranges_60xx = {
82dc1255
HS
471 4, {
472 BIP_RANGE(10),
473 BIP_RANGE(5),
474 BIP_RANGE(0.5),
475 BIP_RANGE(0.05)
476 }
88b12a9a
FMH
477};
478
be8e8908
IA
479static const uint8_t ai_range_code_60xx[4] = {
480 0x0, 0x1, 0x4, 0x7 /* bipolar 10, 5, 0.5, 0.05 */
481};
482
88b12a9a 483/* analog input ranges for 6030, etc boards */
9ced1de6 484static const struct comedi_lrange ai_ranges_6030 = {
82dc1255
HS
485 14, {
486 BIP_RANGE(10),
487 BIP_RANGE(5),
488 BIP_RANGE(2),
489 BIP_RANGE(1),
490 BIP_RANGE(0.5),
491 BIP_RANGE(0.2),
492 BIP_RANGE(0.1),
493 UNI_RANGE(10),
494 UNI_RANGE(5),
495 UNI_RANGE(2),
496 UNI_RANGE(1),
497 UNI_RANGE(0.5),
498 UNI_RANGE(0.2),
499 UNI_RANGE(0.1)
500 }
88b12a9a
FMH
501};
502
be8e8908
IA
503static const uint8_t ai_range_code_6030[14] = {
504 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, /* bip 10, 5, 2, 1, 0.5, 0.2, 0.1 */
505 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* uni 10, 5, 2, 1, 0.5, 0.2, 0.1 */
506};
507
88b12a9a 508/* analog input ranges for 6052, etc boards */
9ced1de6 509static const struct comedi_lrange ai_ranges_6052 = {
82dc1255
HS
510 15, {
511 BIP_RANGE(10),
512 BIP_RANGE(5),
513 BIP_RANGE(2.5),
514 BIP_RANGE(1),
515 BIP_RANGE(0.5),
516 BIP_RANGE(0.25),
517 BIP_RANGE(0.1),
518 BIP_RANGE(0.05),
519 UNI_RANGE(10),
520 UNI_RANGE(5),
521 UNI_RANGE(2),
522 UNI_RANGE(1),
523 UNI_RANGE(0.5),
524 UNI_RANGE(0.2),
525 UNI_RANGE(0.1)
526 }
88b12a9a
FMH
527};
528
be8e8908
IA
529static const uint8_t ai_range_code_6052[15] = {
530 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, /* bipolar 10 ... 0.05 */
531 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* unipolar 10 ... 0.1 */
532};
533
9ef4dea6 534/* analog input ranges for 4020 board */
9ced1de6 535static const struct comedi_lrange ai_ranges_4020 = {
82dc1255
HS
536 2, {
537 BIP_RANGE(5),
538 BIP_RANGE(1)
539 }
88b12a9a
FMH
540};
541
9ef4dea6 542/* analog output ranges */
9ced1de6 543static const struct comedi_lrange ao_ranges_64xx = {
82dc1255
HS
544 4, {
545 BIP_RANGE(5),
546 BIP_RANGE(10),
547 UNI_RANGE(5),
548 UNI_RANGE(10)
549 }
88b12a9a 550};
0a85b6f0 551
88b12a9a
FMH
552static const int ao_range_code_64xx[] = {
553 0x0,
554 0x1,
555 0x2,
556 0x3,
557};
558
88b12a9a
FMH
559static const int ao_range_code_60xx[] = {
560 0x0,
561};
562
9ced1de6 563static const struct comedi_lrange ao_ranges_6030 = {
82dc1255
HS
564 2, {
565 BIP_RANGE(10),
566 UNI_RANGE(10)
567 }
88b12a9a 568};
0a85b6f0 569
88b12a9a
FMH
570static const int ao_range_code_6030[] = {
571 0x0,
572 0x2,
573};
574
9ced1de6 575static const struct comedi_lrange ao_ranges_4020 = {
82dc1255
HS
576 2, {
577 BIP_RANGE(5),
578 BIP_RANGE(10)
579 }
88b12a9a 580};
0a85b6f0 581
88b12a9a
FMH
582static const int ao_range_code_4020[] = {
583 0x1,
584 0x0,
585};
586
587enum register_layout {
588 LAYOUT_60XX,
589 LAYOUT_64XX,
590 LAYOUT_4020,
591};
592
675935dd 593struct hw_fifo_info {
88b12a9a
FMH
594 unsigned int num_segments;
595 unsigned int max_segment_length;
596 unsigned int sample_packing_ratio;
597 uint16_t fifo_size_reg_mask;
675935dd 598};
88b12a9a 599
463740d4
HS
600enum pcidas64_boardid {
601 BOARD_PCIDAS6402_16,
602 BOARD_PCIDAS6402_12,
603 BOARD_PCIDAS64_M1_16,
604 BOARD_PCIDAS64_M2_16,
605 BOARD_PCIDAS64_M3_16,
606 BOARD_PCIDAS6013,
607 BOARD_PCIDAS6014,
608 BOARD_PCIDAS6023,
609 BOARD_PCIDAS6025,
610 BOARD_PCIDAS6030,
611 BOARD_PCIDAS6031,
612 BOARD_PCIDAS6032,
613 BOARD_PCIDAS6033,
614 BOARD_PCIDAS6034,
615 BOARD_PCIDAS6035,
616 BOARD_PCIDAS6036,
617 BOARD_PCIDAS6040,
618 BOARD_PCIDAS6052,
619 BOARD_PCIDAS6070,
620 BOARD_PCIDAS6071,
621 BOARD_PCIDAS4020_12,
622 BOARD_PCIDAS6402_16_JR,
623 BOARD_PCIDAS64_M1_16_JR,
624 BOARD_PCIDAS64_M2_16_JR,
625 BOARD_PCIDAS64_M3_16_JR,
626 BOARD_PCIDAS64_M1_14,
627 BOARD_PCIDAS64_M2_14,
628 BOARD_PCIDAS64_M3_14,
629};
630
222ab1bc 631struct pcidas64_board {
88b12a9a 632 const char *name;
12f992ad
AJ
633 int ai_se_chans; /* number of ai inputs in single-ended mode */
634 int ai_bits; /* analog input resolution */
635 int ai_speed; /* fastest conversion period in ns */
9ced1de6 636 const struct comedi_lrange *ai_range_table;
be8e8908 637 const uint8_t *ai_range_code;
12f992ad
AJ
638 int ao_nchan; /* number of analog out channels */
639 int ao_bits; /* analog output resolution */
640 int ao_scan_speed; /* analog output scan speed */
9ced1de6 641 const struct comedi_lrange *ao_range_table;
88b12a9a 642 const int *ao_range_code;
675935dd 643 const struct hw_fifo_info *const ai_fifo;
12f992ad 644 /* different board families have slightly different registers */
46ca84c4 645 enum register_layout layout;
88b12a9a 646 unsigned has_8255:1;
222ab1bc 647};
88b12a9a 648
675935dd 649static const struct hw_fifo_info ai_fifo_4020 = {
68c3dbff
BP
650 .num_segments = 2,
651 .max_segment_length = 0x8000,
652 .sample_packing_ratio = 2,
653 .fifo_size_reg_mask = 0x7f,
88b12a9a
FMH
654};
655
675935dd 656static const struct hw_fifo_info ai_fifo_64xx = {
68c3dbff
BP
657 .num_segments = 4,
658 .max_segment_length = 0x800,
659 .sample_packing_ratio = 1,
660 .fifo_size_reg_mask = 0x3f,
88b12a9a
FMH
661};
662
675935dd 663static const struct hw_fifo_info ai_fifo_60xx = {
68c3dbff
BP
664 .num_segments = 4,
665 .max_segment_length = 0x800,
666 .sample_packing_ratio = 1,
667 .fifo_size_reg_mask = 0x7f,
88b12a9a
FMH
668};
669
85c12b82
AD
670/*
671 * maximum number of dma transfers we will chain together into a ring
672 * (and the maximum number of dma buffers we maintain)
673 */
88b12a9a
FMH
674#define MAX_AI_DMA_RING_COUNT (0x80000 / DMA_BUFFER_SIZE)
675#define MIN_AI_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
676#define AO_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
b07244ce 677static inline unsigned int ai_dma_ring_count(const struct pcidas64_board *board)
88b12a9a
FMH
678{
679 if (board->layout == LAYOUT_4020)
680 return MAX_AI_DMA_RING_COUNT;
4ffeead3
HS
681
682 return MIN_AI_DMA_RING_COUNT;
88b12a9a
FMH
683}
684
685static const int bytes_in_sample = 2;
686
222ab1bc 687static const struct pcidas64_board pcidas64_boards[] = {
463740d4 688 [BOARD_PCIDAS6402_16] = {
2ccdb964
HS
689 .name = "pci-das6402/16",
690 .ai_se_chans = 64,
691 .ai_bits = 16,
692 .ai_speed = 5000,
693 .ao_nchan = 2,
694 .ao_bits = 16,
695 .ao_scan_speed = 10000,
696 .layout = LAYOUT_64XX,
697 .ai_range_table = &ai_ranges_64xx,
be8e8908 698 .ai_range_code = ai_range_code_64xx,
2ccdb964
HS
699 .ao_range_table = &ao_ranges_64xx,
700 .ao_range_code = ao_range_code_64xx,
701 .ai_fifo = &ai_fifo_64xx,
702 .has_8255 = 1,
703 },
463740d4 704 [BOARD_PCIDAS6402_12] = {
12f992ad 705 .name = "pci-das6402/12", /* XXX check */
2ccdb964
HS
706 .ai_se_chans = 64,
707 .ai_bits = 12,
708 .ai_speed = 5000,
709 .ao_nchan = 2,
710 .ao_bits = 12,
711 .ao_scan_speed = 10000,
712 .layout = LAYOUT_64XX,
713 .ai_range_table = &ai_ranges_64xx,
be8e8908 714 .ai_range_code = ai_range_code_64xx,
2ccdb964
HS
715 .ao_range_table = &ao_ranges_64xx,
716 .ao_range_code = ao_range_code_64xx,
717 .ai_fifo = &ai_fifo_64xx,
718 .has_8255 = 1,
719 },
463740d4 720 [BOARD_PCIDAS64_M1_16] = {
2ccdb964
HS
721 .name = "pci-das64/m1/16",
722 .ai_se_chans = 64,
723 .ai_bits = 16,
724 .ai_speed = 1000,
725 .ao_nchan = 2,
726 .ao_bits = 16,
727 .ao_scan_speed = 10000,
728 .layout = LAYOUT_64XX,
be8e8908
IA
729 .ai_range_table = &ai_ranges_64_mx,
730 .ai_range_code = ai_range_code_64_mx,
2ccdb964
HS
731 .ao_range_table = &ao_ranges_64xx,
732 .ao_range_code = ao_range_code_64xx,
733 .ai_fifo = &ai_fifo_64xx,
734 .has_8255 = 1,
735 },
463740d4 736 [BOARD_PCIDAS64_M2_16] = {
2ccdb964
HS
737 .name = "pci-das64/m2/16",
738 .ai_se_chans = 64,
739 .ai_bits = 16,
740 .ai_speed = 500,
741 .ao_nchan = 2,
742 .ao_bits = 16,
743 .ao_scan_speed = 10000,
744 .layout = LAYOUT_64XX,
be8e8908
IA
745 .ai_range_table = &ai_ranges_64_mx,
746 .ai_range_code = ai_range_code_64_mx,
2ccdb964
HS
747 .ao_range_table = &ao_ranges_64xx,
748 .ao_range_code = ao_range_code_64xx,
749 .ai_fifo = &ai_fifo_64xx,
750 .has_8255 = 1,
751 },
463740d4 752 [BOARD_PCIDAS64_M3_16] = {
2ccdb964
HS
753 .name = "pci-das64/m3/16",
754 .ai_se_chans = 64,
755 .ai_bits = 16,
756 .ai_speed = 333,
757 .ao_nchan = 2,
758 .ao_bits = 16,
759 .ao_scan_speed = 10000,
760 .layout = LAYOUT_64XX,
be8e8908
IA
761 .ai_range_table = &ai_ranges_64_mx,
762 .ai_range_code = ai_range_code_64_mx,
2ccdb964
HS
763 .ao_range_table = &ao_ranges_64xx,
764 .ao_range_code = ao_range_code_64xx,
765 .ai_fifo = &ai_fifo_64xx,
766 .has_8255 = 1,
767 },
463740d4 768 [BOARD_PCIDAS6013] = {
2ccdb964
HS
769 .name = "pci-das6013",
770 .ai_se_chans = 16,
771 .ai_bits = 16,
772 .ai_speed = 5000,
773 .ao_nchan = 0,
774 .ao_bits = 16,
775 .layout = LAYOUT_60XX,
776 .ai_range_table = &ai_ranges_60xx,
be8e8908 777 .ai_range_code = ai_range_code_60xx,
7cf24bb4 778 .ao_range_table = &range_bipolar10,
2ccdb964
HS
779 .ao_range_code = ao_range_code_60xx,
780 .ai_fifo = &ai_fifo_60xx,
781 .has_8255 = 0,
782 },
463740d4 783 [BOARD_PCIDAS6014] = {
2ccdb964
HS
784 .name = "pci-das6014",
785 .ai_se_chans = 16,
786 .ai_bits = 16,
787 .ai_speed = 5000,
788 .ao_nchan = 2,
789 .ao_bits = 16,
790 .ao_scan_speed = 100000,
791 .layout = LAYOUT_60XX,
792 .ai_range_table = &ai_ranges_60xx,
be8e8908 793 .ai_range_code = ai_range_code_60xx,
7cf24bb4 794 .ao_range_table = &range_bipolar10,
2ccdb964
HS
795 .ao_range_code = ao_range_code_60xx,
796 .ai_fifo = &ai_fifo_60xx,
797 .has_8255 = 0,
798 },
463740d4 799 [BOARD_PCIDAS6023] = {
2ccdb964
HS
800 .name = "pci-das6023",
801 .ai_se_chans = 16,
802 .ai_bits = 12,
803 .ai_speed = 5000,
804 .ao_nchan = 0,
805 .ao_scan_speed = 100000,
806 .layout = LAYOUT_60XX,
807 .ai_range_table = &ai_ranges_60xx,
be8e8908 808 .ai_range_code = ai_range_code_60xx,
7cf24bb4 809 .ao_range_table = &range_bipolar10,
2ccdb964
HS
810 .ao_range_code = ao_range_code_60xx,
811 .ai_fifo = &ai_fifo_60xx,
812 .has_8255 = 1,
813 },
463740d4 814 [BOARD_PCIDAS6025] = {
2ccdb964
HS
815 .name = "pci-das6025",
816 .ai_se_chans = 16,
817 .ai_bits = 12,
818 .ai_speed = 5000,
819 .ao_nchan = 2,
820 .ao_bits = 12,
821 .ao_scan_speed = 100000,
822 .layout = LAYOUT_60XX,
823 .ai_range_table = &ai_ranges_60xx,
be8e8908 824 .ai_range_code = ai_range_code_60xx,
7cf24bb4 825 .ao_range_table = &range_bipolar10,
2ccdb964
HS
826 .ao_range_code = ao_range_code_60xx,
827 .ai_fifo = &ai_fifo_60xx,
828 .has_8255 = 1,
829 },
463740d4 830 [BOARD_PCIDAS6030] = {
2ccdb964
HS
831 .name = "pci-das6030",
832 .ai_se_chans = 16,
833 .ai_bits = 16,
834 .ai_speed = 10000,
835 .ao_nchan = 2,
836 .ao_bits = 16,
837 .ao_scan_speed = 10000,
838 .layout = LAYOUT_60XX,
839 .ai_range_table = &ai_ranges_6030,
be8e8908 840 .ai_range_code = ai_range_code_6030,
2ccdb964
HS
841 .ao_range_table = &ao_ranges_6030,
842 .ao_range_code = ao_range_code_6030,
843 .ai_fifo = &ai_fifo_60xx,
844 .has_8255 = 0,
845 },
463740d4 846 [BOARD_PCIDAS6031] = {
2ccdb964
HS
847 .name = "pci-das6031",
848 .ai_se_chans = 64,
849 .ai_bits = 16,
850 .ai_speed = 10000,
851 .ao_nchan = 2,
852 .ao_bits = 16,
853 .ao_scan_speed = 10000,
854 .layout = LAYOUT_60XX,
855 .ai_range_table = &ai_ranges_6030,
be8e8908 856 .ai_range_code = ai_range_code_6030,
2ccdb964
HS
857 .ao_range_table = &ao_ranges_6030,
858 .ao_range_code = ao_range_code_6030,
859 .ai_fifo = &ai_fifo_60xx,
860 .has_8255 = 0,
861 },
463740d4 862 [BOARD_PCIDAS6032] = {
2ccdb964
HS
863 .name = "pci-das6032",
864 .ai_se_chans = 16,
865 .ai_bits = 16,
866 .ai_speed = 10000,
867 .ao_nchan = 0,
868 .layout = LAYOUT_60XX,
869 .ai_range_table = &ai_ranges_6030,
be8e8908 870 .ai_range_code = ai_range_code_6030,
2ccdb964
HS
871 .ai_fifo = &ai_fifo_60xx,
872 .has_8255 = 0,
873 },
463740d4 874 [BOARD_PCIDAS6033] = {
2ccdb964
HS
875 .name = "pci-das6033",
876 .ai_se_chans = 64,
877 .ai_bits = 16,
878 .ai_speed = 10000,
879 .ao_nchan = 0,
880 .layout = LAYOUT_60XX,
881 .ai_range_table = &ai_ranges_6030,
be8e8908 882 .ai_range_code = ai_range_code_6030,
2ccdb964
HS
883 .ai_fifo = &ai_fifo_60xx,
884 .has_8255 = 0,
885 },
463740d4 886 [BOARD_PCIDAS6034] = {
2ccdb964
HS
887 .name = "pci-das6034",
888 .ai_se_chans = 16,
889 .ai_bits = 16,
890 .ai_speed = 5000,
891 .ao_nchan = 0,
892 .ao_scan_speed = 0,
893 .layout = LAYOUT_60XX,
894 .ai_range_table = &ai_ranges_60xx,
be8e8908 895 .ai_range_code = ai_range_code_60xx,
2ccdb964
HS
896 .ai_fifo = &ai_fifo_60xx,
897 .has_8255 = 0,
898 },
463740d4 899 [BOARD_PCIDAS6035] = {
2ccdb964
HS
900 .name = "pci-das6035",
901 .ai_se_chans = 16,
902 .ai_bits = 16,
903 .ai_speed = 5000,
904 .ao_nchan = 2,
905 .ao_bits = 12,
906 .ao_scan_speed = 100000,
907 .layout = LAYOUT_60XX,
908 .ai_range_table = &ai_ranges_60xx,
be8e8908 909 .ai_range_code = ai_range_code_60xx,
7cf24bb4 910 .ao_range_table = &range_bipolar10,
2ccdb964
HS
911 .ao_range_code = ao_range_code_60xx,
912 .ai_fifo = &ai_fifo_60xx,
913 .has_8255 = 0,
914 },
463740d4 915 [BOARD_PCIDAS6036] = {
2ccdb964
HS
916 .name = "pci-das6036",
917 .ai_se_chans = 16,
918 .ai_bits = 16,
919 .ai_speed = 5000,
920 .ao_nchan = 2,
921 .ao_bits = 16,
922 .ao_scan_speed = 100000,
923 .layout = LAYOUT_60XX,
924 .ai_range_table = &ai_ranges_60xx,
be8e8908 925 .ai_range_code = ai_range_code_60xx,
7cf24bb4 926 .ao_range_table = &range_bipolar10,
2ccdb964
HS
927 .ao_range_code = ao_range_code_60xx,
928 .ai_fifo = &ai_fifo_60xx,
929 .has_8255 = 0,
930 },
463740d4 931 [BOARD_PCIDAS6040] = {
2ccdb964
HS
932 .name = "pci-das6040",
933 .ai_se_chans = 16,
934 .ai_bits = 12,
935 .ai_speed = 2000,
936 .ao_nchan = 2,
937 .ao_bits = 12,
938 .ao_scan_speed = 1000,
939 .layout = LAYOUT_60XX,
940 .ai_range_table = &ai_ranges_6052,
be8e8908 941 .ai_range_code = ai_range_code_6052,
2ccdb964
HS
942 .ao_range_table = &ao_ranges_6030,
943 .ao_range_code = ao_range_code_6030,
944 .ai_fifo = &ai_fifo_60xx,
945 .has_8255 = 0,
946 },
463740d4 947 [BOARD_PCIDAS6052] = {
2ccdb964
HS
948 .name = "pci-das6052",
949 .ai_se_chans = 16,
950 .ai_bits = 16,
951 .ai_speed = 3333,
952 .ao_nchan = 2,
953 .ao_bits = 16,
954 .ao_scan_speed = 3333,
955 .layout = LAYOUT_60XX,
956 .ai_range_table = &ai_ranges_6052,
be8e8908 957 .ai_range_code = ai_range_code_6052,
2ccdb964
HS
958 .ao_range_table = &ao_ranges_6030,
959 .ao_range_code = ao_range_code_6030,
960 .ai_fifo = &ai_fifo_60xx,
961 .has_8255 = 0,
962 },
463740d4 963 [BOARD_PCIDAS6070] = {
2ccdb964
HS
964 .name = "pci-das6070",
965 .ai_se_chans = 16,
966 .ai_bits = 12,
967 .ai_speed = 800,
968 .ao_nchan = 2,
969 .ao_bits = 12,
970 .ao_scan_speed = 1000,
971 .layout = LAYOUT_60XX,
972 .ai_range_table = &ai_ranges_6052,
be8e8908 973 .ai_range_code = ai_range_code_6052,
2ccdb964
HS
974 .ao_range_table = &ao_ranges_6030,
975 .ao_range_code = ao_range_code_6030,
976 .ai_fifo = &ai_fifo_60xx,
977 .has_8255 = 0,
978 },
463740d4 979 [BOARD_PCIDAS6071] = {
2ccdb964
HS
980 .name = "pci-das6071",
981 .ai_se_chans = 64,
982 .ai_bits = 12,
983 .ai_speed = 800,
984 .ao_nchan = 2,
985 .ao_bits = 12,
986 .ao_scan_speed = 1000,
987 .layout = LAYOUT_60XX,
988 .ai_range_table = &ai_ranges_6052,
be8e8908 989 .ai_range_code = ai_range_code_6052,
2ccdb964
HS
990 .ao_range_table = &ao_ranges_6030,
991 .ao_range_code = ao_range_code_6030,
992 .ai_fifo = &ai_fifo_60xx,
993 .has_8255 = 0,
994 },
463740d4 995 [BOARD_PCIDAS4020_12] = {
2ccdb964
HS
996 .name = "pci-das4020/12",
997 .ai_se_chans = 4,
998 .ai_bits = 12,
999 .ai_speed = 50,
1000 .ao_bits = 12,
1001 .ao_nchan = 2,
12f992ad 1002 .ao_scan_speed = 0, /* no hardware pacing on ao */
2ccdb964
HS
1003 .layout = LAYOUT_4020,
1004 .ai_range_table = &ai_ranges_4020,
1005 .ao_range_table = &ao_ranges_4020,
1006 .ao_range_code = ao_range_code_4020,
1007 .ai_fifo = &ai_fifo_4020,
1008 .has_8255 = 1,
1009 },
88b12a9a 1010#if 0
12f992ad 1011 /* The device id for these boards is unknown */
463740d4
HS
1012
1013 [BOARD_PCIDAS6402_16_JR] = {
2ccdb964
HS
1014 .name = "pci-das6402/16/jr",
1015 .ai_se_chans = 64,
1016 .ai_bits = 16,
1017 .ai_speed = 5000,
1018 .ao_nchan = 0,
1019 .ao_scan_speed = 10000,
1020 .layout = LAYOUT_64XX,
1021 .ai_range_table = &ai_ranges_64xx,
be8e8908 1022 .ai_range_code = ai_range_code_64xx,
2ccdb964
HS
1023 .ai_fifo = ai_fifo_64xx,
1024 .has_8255 = 1,
1025 },
463740d4 1026 [BOARD_PCIDAS64_M1_16_JR] = {
2ccdb964
HS
1027 .name = "pci-das64/m1/16/jr",
1028 .ai_se_chans = 64,
1029 .ai_bits = 16,
1030 .ai_speed = 1000,
1031 .ao_nchan = 0,
1032 .ao_scan_speed = 10000,
1033 .layout = LAYOUT_64XX,
be8e8908
IA
1034 .ai_range_table = &ai_ranges_64_mx,
1035 .ai_range_code = ai_range_code_64_mx,
2ccdb964
HS
1036 .ai_fifo = ai_fifo_64xx,
1037 .has_8255 = 1,
1038 },
463740d4 1039 [BOARD_PCIDAS64_M2_16_JR] = {
2ccdb964
HS
1040 .name = "pci-das64/m2/16/jr",
1041 .ai_se_chans = 64,
1042 .ai_bits = 16,
1043 .ai_speed = 500,
1044 .ao_nchan = 0,
1045 .ao_scan_speed = 10000,
1046 .layout = LAYOUT_64XX,
be8e8908
IA
1047 .ai_range_table = &ai_ranges_64_mx,
1048 .ai_range_code = ai_range_code_64_mx,
2ccdb964
HS
1049 .ai_fifo = ai_fifo_64xx,
1050 .has_8255 = 1,
1051 },
463740d4 1052 [BOARD_PCIDAS64_M3_16_JR] = {
2ccdb964
HS
1053 .name = "pci-das64/m3/16/jr",
1054 .ai_se_chans = 64,
1055 .ai_bits = 16,
1056 .ai_speed = 333,
1057 .ao_nchan = 0,
1058 .ao_scan_speed = 10000,
1059 .layout = LAYOUT_64XX,
be8e8908
IA
1060 .ai_range_table = &ai_ranges_64_mx,
1061 .ai_range_code = ai_range_code_64_mx,
2ccdb964
HS
1062 .ai_fifo = ai_fifo_64xx,
1063 .has_8255 = 1,
1064 },
463740d4 1065 [BOARD_PCIDAS64_M1_14] = {
2ccdb964
HS
1066 .name = "pci-das64/m1/14",
1067 .ai_se_chans = 64,
1068 .ai_bits = 14,
1069 .ai_speed = 1000,
1070 .ao_nchan = 2,
1071 .ao_scan_speed = 10000,
1072 .layout = LAYOUT_64XX,
be8e8908
IA
1073 .ai_range_table = &ai_ranges_64_mx,
1074 .ai_range_code = ai_range_code_64_mx,
2ccdb964
HS
1075 .ai_fifo = ai_fifo_64xx,
1076 .has_8255 = 1,
1077 },
463740d4 1078 [BOARD_PCIDAS64_M2_14] = {
2ccdb964
HS
1079 .name = "pci-das64/m2/14",
1080 .ai_se_chans = 64,
1081 .ai_bits = 14,
1082 .ai_speed = 500,
1083 .ao_nchan = 2,
1084 .ao_scan_speed = 10000,
1085 .layout = LAYOUT_64XX,
be8e8908
IA
1086 .ai_range_table = &ai_ranges_64_mx,
1087 .ai_range_code = ai_range_code_64_mx,
2ccdb964
HS
1088 .ai_fifo = ai_fifo_64xx,
1089 .has_8255 = 1,
1090 },
463740d4 1091 [BOARD_PCIDAS64_M3_14] = {
2ccdb964
HS
1092 .name = "pci-das64/m3/14",
1093 .ai_se_chans = 64,
1094 .ai_bits = 14,
1095 .ai_speed = 333,
1096 .ao_nchan = 2,
1097 .ao_scan_speed = 10000,
1098 .layout = LAYOUT_64XX,
be8e8908
IA
1099 .ai_range_table = &ai_ranges_64_mx,
1100 .ai_range_code = ai_range_code_64_mx,
2ccdb964
HS
1101 .ai_fifo = ai_fifo_64xx,
1102 .has_8255 = 1,
1103 },
88b12a9a
FMH
1104#endif
1105};
1106
da91b269 1107static inline unsigned short se_diff_bit_6xxx(struct comedi_device *dev,
0a85b6f0 1108 int use_differential)
88b12a9a 1109{
52762ad1 1110 const struct pcidas64_board *board = dev->board_ptr;
b07244ce 1111
52762ad1
HS
1112 if ((board->layout == LAYOUT_64XX && !use_differential) ||
1113 (board->layout == LAYOUT_60XX && use_differential))
88b12a9a 1114 return ADC_SE_DIFF_BIT;
4ffeead3
HS
1115
1116 return 0;
1117}
88b12a9a
FMH
1118
1119struct ext_clock_info {
12f992ad 1120 /* master clock divisor to use for scans with external master clock */
46ca84c4 1121 unsigned int divisor;
12f992ad 1122 /* chanspec for master clock input when used as scan begin src */
46ca84c4 1123 unsigned int chanspec;
88b12a9a
FMH
1124};
1125
1126/* this structure is for data unique to this hardware driver. */
450032a3 1127struct pcidas64_private {
12f992ad 1128 /* base addresses (physical) */
88b12a9a
FMH
1129 resource_size_t main_phys_iobase;
1130 resource_size_t dio_counter_phys_iobase;
12f992ad 1131 /* base addresses (ioremapped) */
f31d0008
GKH
1132 void __iomem *plx9080_iobase;
1133 void __iomem *main_iobase;
12f992ad 1134 /* local address (used by dma controller) */
88b12a9a
FMH
1135 uint32_t local0_iobase;
1136 uint32_t local1_iobase;
12f992ad 1137 /* dma buffers for analog input */
46ca84c4 1138 uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT];
12f992ad 1139 /* physical addresses of ai dma buffers */
46ca84c4 1140 dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT];
12f992ad
AJ
1141 /*
1142 * array of ai dma descriptors read by plx9080,
1143 * allocated to get proper alignment
28fec2e6 1144 */
46ca84c4 1145 struct plx_dma_desc *ai_dma_desc;
12f992ad 1146 /* physical address of ai dma descriptor array */
46ca84c4 1147 dma_addr_t ai_dma_desc_bus_addr;
12f992ad
AJ
1148 /*
1149 * index of the ai dma descriptor/buffer
1150 * that is currently being used
28fec2e6 1151 */
0f99981a 1152 unsigned int ai_dma_index;
12f992ad 1153 /* dma buffers for analog output */
46ca84c4 1154 uint16_t *ao_buffer[AO_DMA_RING_COUNT];
12f992ad 1155 /* physical addresses of ao dma buffers */
46ca84c4 1156 dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT];
88b12a9a
FMH
1157 struct plx_dma_desc *ao_dma_desc;
1158 dma_addr_t ao_dma_desc_bus_addr;
12f992ad 1159 /* keeps track of buffer where the next ao sample should go */
0f99981a 1160 unsigned int ao_dma_index;
12f992ad
AJ
1161 unsigned int hw_revision; /* stc chip hardware revision number */
1162 /* last bits sent to INTR_ENABLE_REG register */
0f99981a 1163 unsigned int intr_enable_bits;
12f992ad 1164 /* last bits sent to ADC_CONTROL1_REG register */
0f99981a 1165 uint16_t adc_control1_bits;
12f992ad 1166 /* last bits sent to FIFO_SIZE_REG register */
0f99981a 1167 uint16_t fifo_size_bits;
12f992ad 1168 /* last bits sent to HW_CONFIG_REG register */
0f99981a
HS
1169 uint16_t hw_config_bits;
1170 uint16_t dac_control1_bits;
12f992ad 1171 /* last bits written to plx9080 control register */
0f99981a 1172 uint32_t plx_control_bits;
12f992ad 1173 /* last bits written to plx interrupt control and status register */
0f99981a 1174 uint32_t plx_intcsr_bits;
12f992ad 1175 /* index of calibration source readable through ai ch0 */
0f99981a 1176 int calibration_source;
12f992ad 1177 /* bits written to i2c calibration/range register */
0f99981a 1178 uint8_t i2c_cal_range_bits;
12f992ad 1179 /* configure digital triggers to trigger on falling edge */
0f99981a 1180 unsigned int ext_trig_falling;
0f99981a 1181 short ai_cmd_running;
88b12a9a
FMH
1182 unsigned int ai_fifo_segment_length;
1183 struct ext_clock_info ext_clock;
05220638 1184 unsigned short ao_bounce_buffer[DAC_FIFO_SIZE];
450032a3
BP
1185};
1186
814900c9 1187static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
0a85b6f0 1188 unsigned int range_index)
88b12a9a 1189{
52762ad1 1190 const struct pcidas64_board *board = dev->board_ptr;
be8e8908 1191
52762ad1 1192 return board->ai_range_code[range_index] << 8;
88b12a9a
FMH
1193}
1194
da91b269 1195static unsigned int hw_revision(const struct comedi_device *dev,
0a85b6f0 1196 uint16_t hw_status_bits)
88b12a9a 1197{
52762ad1 1198 const struct pcidas64_board *board = dev->board_ptr;
b07244ce 1199
52762ad1 1200 if (board->layout == LAYOUT_4020)
88b12a9a
FMH
1201 return (hw_status_bits >> 13) & 0x7;
1202
1203 return (hw_status_bits >> 12) & 0xf;
1204}
1205
0a85b6f0 1206static void set_dac_range_bits(struct comedi_device *dev,
350a3276 1207 uint16_t *bits, unsigned int channel,
0a85b6f0 1208 unsigned int range)
88b12a9a 1209{
52762ad1
HS
1210 const struct pcidas64_board *board = dev->board_ptr;
1211 unsigned int code = board->ao_range_code[range];
88b12a9a
FMH
1212
1213 if (channel > 1)
e176d78c 1214 dev_err(dev->class_dev, "bug! bad channel?\n");
88b12a9a 1215 if (code & ~0x3)
e176d78c 1216 dev_err(dev->class_dev, "bug! bad range code?\n");
88b12a9a
FMH
1217
1218 *bits &= ~(0x3 << (2 * channel));
1219 *bits |= code << (2 * channel);
1220};
1221
da91b269 1222static inline int ao_cmd_is_supported(const struct pcidas64_board *board)
88b12a9a
FMH
1223{
1224 return board->ao_nchan && board->layout != LAYOUT_4020;
1225}
1226
012e642c
IA
1227static void abort_dma(struct comedi_device *dev, unsigned int channel)
1228{
1229 struct pcidas64_private *devpriv = dev->private;
1230 unsigned long flags;
1231
12f992ad 1232 /* spinlock for plx dma control/status reg */
012e642c
IA
1233 spin_lock_irqsave(&dev->spinlock, flags);
1234
1235 plx9080_abort_dma(devpriv->plx9080_iobase, channel);
1236
1237 spin_unlock_irqrestore(&dev->spinlock, flags);
1238}
1239
dd379fa2
IA
1240static void disable_plx_interrupts(struct comedi_device *dev)
1241{
1242 struct pcidas64_private *devpriv = dev->private;
1243
1244 devpriv->plx_intcsr_bits = 0;
1245 writel(devpriv->plx_intcsr_bits,
c644a11a 1246 devpriv->plx9080_iobase + PLX_REG_INTCSR);
dd379fa2
IA
1247}
1248
1249static void disable_ai_interrupts(struct comedi_device *dev)
1250{
1251 struct pcidas64_private *devpriv = dev->private;
1252 unsigned long flags;
1253
1254 spin_lock_irqsave(&dev->spinlock, flags);
1255 devpriv->intr_enable_bits &=
1256 ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT &
1257 ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT &
1258 ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK;
1259 writew(devpriv->intr_enable_bits,
1260 devpriv->main_iobase + INTR_ENABLE_REG);
1261 spin_unlock_irqrestore(&dev->spinlock, flags);
dd379fa2
IA
1262}
1263
1264static void enable_ai_interrupts(struct comedi_device *dev,
1265 const struct comedi_cmd *cmd)
1266{
52762ad1 1267 const struct pcidas64_board *board = dev->board_ptr;
dd379fa2
IA
1268 struct pcidas64_private *devpriv = dev->private;
1269 uint32_t bits;
1270 unsigned long flags;
1271
1272 bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT |
1273 EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT;
85c12b82
AD
1274 /*
1275 * Use pio transfer and interrupt on end of conversion
1276 * if CMDF_WAKE_EOS flag is set.
1277 */
0ad08e4b 1278 if (cmd->flags & CMDF_WAKE_EOS) {
12f992ad 1279 /* 4020 doesn't support pio transfers except for fifo dregs */
52762ad1 1280 if (board->layout != LAYOUT_4020)
dd379fa2
IA
1281 bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT;
1282 }
1283 spin_lock_irqsave(&dev->spinlock, flags);
1284 devpriv->intr_enable_bits |= bits;
1285 writew(devpriv->intr_enable_bits,
1286 devpriv->main_iobase + INTR_ENABLE_REG);
dd379fa2
IA
1287 spin_unlock_irqrestore(&dev->spinlock, flags);
1288}
1289
9ef4dea6 1290/* initialize plx9080 chip */
da91b269 1291static void init_plx9080(struct comedi_device *dev)
88b12a9a 1292{
52762ad1 1293 const struct pcidas64_board *board = dev->board_ptr;
681d335a 1294 struct pcidas64_private *devpriv = dev->private;
88b12a9a 1295 uint32_t bits;
681d335a 1296 void __iomem *plx_iobase = devpriv->plx9080_iobase;
88b12a9a 1297
681d335a 1298 devpriv->plx_control_bits =
c644a11a 1299 readl(devpriv->plx9080_iobase + PLX_REG_CNTRL);
88b12a9a 1300
88b12a9a 1301#ifdef __BIG_ENDIAN
a9c254a7 1302 bits = PLX_BIGEND_DMA0 | PLX_BIGEND_DMA1;
88b12a9a
FMH
1303#else
1304 bits = 0;
1305#endif
c644a11a 1306 writel(bits, devpriv->plx9080_iobase + PLX_REG_BIGEND);
88b12a9a
FMH
1307
1308 disable_plx_interrupts(dev);
1309
1310 abort_dma(dev, 0);
1311 abort_dma(dev, 1);
1312
12f992ad 1313 /* configure dma0 mode */
88b12a9a 1314 bits = 0;
12f992ad 1315 /* enable ready input, not sure if this is necessary */
65bf53de 1316 bits |= PLX_DMAMODE_READYIEN;
12f992ad 1317 /* enable bterm, not sure if this is necessary */
65bf53de 1318 bits |= PLX_DMAMODE_BTERMIEN;
12f992ad 1319 /* enable dma chaining */
65bf53de 1320 bits |= PLX_DMAMODE_CHAINEN;
12f992ad
AJ
1321 /*
1322 * enable interrupt on dma done
1323 * (probably don't need this, since chain never finishes)
28fec2e6 1324 */
65bf53de 1325 bits |= PLX_DMAMODE_DONEIEN;
12f992ad
AJ
1326 /*
1327 * don't increment local address during transfers
1328 * (we are transferring from a fixed fifo register)
28fec2e6 1329 */
65bf53de 1330 bits |= PLX_DMAMODE_LACONST;
12f992ad 1331 /* route dma interrupt to pci bus */
65bf53de 1332 bits |= PLX_DMAMODE_INTRPCI;
12f992ad 1333 /* enable demand mode */
65bf53de 1334 bits |= PLX_DMAMODE_DEMAND;
12f992ad 1335 /* enable local burst mode */
65bf53de 1336 bits |= PLX_DMAMODE_BURSTEN;
12f992ad 1337 /* 4020 uses 32 bit dma */
52762ad1 1338 if (board->layout == LAYOUT_4020)
686869b4 1339 bits |= PLX_DMAMODE_WIDTH_32;
12f992ad 1340 else /* localspace0 bus is 16 bits wide */
686869b4 1341 bits |= PLX_DMAMODE_WIDTH_16;
c644a11a 1342 writel(bits, plx_iobase + PLX_REG_DMAMODE1);
52762ad1 1343 if (ao_cmd_is_supported(board))
c644a11a 1344 writel(bits, plx_iobase + PLX_REG_DMAMODE0);
88b12a9a 1345
12f992ad 1346 /* enable interrupts on plx 9080 */
681d335a 1347 devpriv->plx_intcsr_bits |=
9dc53852
IA
1348 PLX_INTCSR_LSEABORTEN | PLX_INTCSR_LSEPARITYEN | PLX_INTCSR_PIEN |
1349 PLX_INTCSR_PLIEN | PLX_INTCSR_PABORTIEN | PLX_INTCSR_LIOEN |
1350 PLX_INTCSR_DMA0IEN | PLX_INTCSR_DMA1IEN;
681d335a 1351 writel(devpriv->plx_intcsr_bits,
c644a11a 1352 devpriv->plx9080_iobase + PLX_REG_INTCSR);
88b12a9a
FMH
1353}
1354
012e642c
IA
1355static void disable_ai_pacing(struct comedi_device *dev)
1356{
1357 struct pcidas64_private *devpriv = dev->private;
1358 unsigned long flags;
1359
1360 disable_ai_interrupts(dev);
1361
1362 spin_lock_irqsave(&dev->spinlock, flags);
1363 devpriv->adc_control1_bits &= ~ADC_SW_GATE_BIT;
1364 writew(devpriv->adc_control1_bits,
1365 devpriv->main_iobase + ADC_CONTROL1_REG);
1366 spin_unlock_irqrestore(&dev->spinlock, flags);
1367
1368 /* disable pacing, triggering, etc */
1369 writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT,
1370 devpriv->main_iobase + ADC_CONTROL0_REG);
1371}
1372
dd379fa2
IA
1373static int set_ai_fifo_segment_length(struct comedi_device *dev,
1374 unsigned int num_entries)
1375{
52762ad1 1376 const struct pcidas64_board *board = dev->board_ptr;
dd379fa2
IA
1377 struct pcidas64_private *devpriv = dev->private;
1378 static const int increment_size = 0x100;
52762ad1 1379 const struct hw_fifo_info *const fifo = board->ai_fifo;
dd379fa2
IA
1380 unsigned int num_increments;
1381 uint16_t bits;
1382
1383 if (num_entries < increment_size)
1384 num_entries = increment_size;
1385 if (num_entries > fifo->max_segment_length)
1386 num_entries = fifo->max_segment_length;
1387
12f992ad 1388 /* 1 == 256 entries, 2 == 512 entries, etc */
2ead7b32 1389 num_increments = DIV_ROUND_CLOSEST(num_entries, increment_size);
dd379fa2
IA
1390
1391 bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask;
1392 devpriv->fifo_size_bits &= ~fifo->fifo_size_reg_mask;
1393 devpriv->fifo_size_bits |= bits;
1394 writew(devpriv->fifo_size_bits,
1395 devpriv->main_iobase + FIFO_SIZE_REG);
1396
1397 devpriv->ai_fifo_segment_length = num_increments * increment_size;
1398
dd379fa2
IA
1399 return devpriv->ai_fifo_segment_length;
1400}
1401
f51ff7e4
AD
1402/*
1403 * adjusts the size of hardware fifo (which determines block size for dma xfers)
1404 */
dd379fa2
IA
1405static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples)
1406{
52762ad1 1407 const struct pcidas64_board *board = dev->board_ptr;
dd379fa2
IA
1408 unsigned int num_fifo_entries;
1409 int retval;
52762ad1 1410 const struct hw_fifo_info *const fifo = board->ai_fifo;
dd379fa2
IA
1411
1412 num_fifo_entries = num_samples / fifo->sample_packing_ratio;
1413
1414 retval = set_ai_fifo_segment_length(dev,
1415 num_fifo_entries /
1416 fifo->num_segments);
1417 if (retval < 0)
1418 return retval;
1419
1420 num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio;
1421
dd379fa2
IA
1422 return num_samples;
1423}
1424
1425/* query length of fifo */
1426static unsigned int ai_fifo_size(struct comedi_device *dev)
1427{
52762ad1 1428 const struct pcidas64_board *board = dev->board_ptr;
dd379fa2
IA
1429 struct pcidas64_private *devpriv = dev->private;
1430
1431 return devpriv->ai_fifo_segment_length *
52762ad1
HS
1432 board->ai_fifo->num_segments *
1433 board->ai_fifo->sample_packing_ratio;
dd379fa2
IA
1434}
1435
da91b269 1436static void init_stc_registers(struct comedi_device *dev)
88b12a9a 1437{
52762ad1 1438 const struct pcidas64_board *board = dev->board_ptr;
681d335a 1439 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
1440 uint16_t bits;
1441 unsigned long flags;
1442
5f74ea14 1443 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a 1444
85c12b82
AD
1445 /*
1446 * bit should be set for 6025,
1447 * although docs say boards with <= 16 chans should be cleared XXX
1448 */
88b12a9a 1449 if (1)
681d335a
HS
1450 devpriv->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT;
1451 writew(devpriv->adc_control1_bits,
1452 devpriv->main_iobase + ADC_CONTROL1_REG);
88b12a9a 1453
12f992ad 1454 /* 6402/16 manual says this register must be initialized to 0xff? */
681d335a 1455 writew(0xff, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
88b12a9a
FMH
1456
1457 bits = SLOW_DAC_BIT | DMA_CH_SELECT_BIT;
52762ad1 1458 if (board->layout == LAYOUT_4020)
88b12a9a 1459 bits |= INTERNAL_CLOCK_4020_BITS;
681d335a
HS
1460 devpriv->hw_config_bits |= bits;
1461 writew(devpriv->hw_config_bits,
1462 devpriv->main_iobase + HW_CONFIG_REG);
88b12a9a 1463
681d335a
HS
1464 writew(0, devpriv->main_iobase + DAQ_SYNC_REG);
1465 writew(0, devpriv->main_iobase + CALIBRATION_REG);
88b12a9a 1466
5f74ea14 1467 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 1468
12f992ad 1469 /* set fifos to maximum size */
681d335a 1470 devpriv->fifo_size_bits |= DAC_FIFO_BITS;
52762ad1 1471 set_ai_fifo_segment_length(dev, board->ai_fifo->max_segment_length);
88b12a9a 1472
681d335a 1473 devpriv->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT;
46ca84c4
IA
1474 devpriv->intr_enable_bits =
1475 /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */
1476 EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT;
681d335a
HS
1477 writew(devpriv->intr_enable_bits,
1478 devpriv->main_iobase + INTR_ENABLE_REG);
88b12a9a
FMH
1479
1480 disable_ai_pacing(dev);
1481};
1482
f31d0008 1483static int alloc_and_init_dma_members(struct comedi_device *dev)
88b12a9a 1484{
52762ad1 1485 const struct pcidas64_board *board = dev->board_ptr;
000e2635 1486 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
681d335a 1487 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
1488 int i;
1489
12f992ad 1490 /* allocate pci dma buffers */
52762ad1 1491 for (i = 0; i < ai_dma_ring_count(board); i++) {
681d335a 1492 devpriv->ai_buffer[i] =
d2b0fc6e
AKC
1493 dma_alloc_coherent(&pcidev->dev, DMA_BUFFER_SIZE,
1494 &devpriv->ai_buffer_bus_addr[i],
1495 GFP_KERNEL);
854472c2 1496 if (!devpriv->ai_buffer[i])
88b12a9a 1497 return -ENOMEM;
88b12a9a
FMH
1498 }
1499 for (i = 0; i < AO_DMA_RING_COUNT; i++) {
52762ad1 1500 if (ao_cmd_is_supported(board)) {
681d335a 1501 devpriv->ao_buffer[i] =
d2b0fc6e
AKC
1502 dma_alloc_coherent(&pcidev->dev,
1503 DMA_BUFFER_SIZE,
1504 &devpriv->
1505 ao_buffer_bus_addr[i],
1506 GFP_KERNEL);
854472c2 1507 if (!devpriv->ao_buffer[i])
88b12a9a 1508 return -ENOMEM;
88b12a9a
FMH
1509 }
1510 }
12f992ad 1511 /* allocate dma descriptors */
681d335a 1512 devpriv->ai_dma_desc =
d2b0fc6e
AKC
1513 dma_alloc_coherent(&pcidev->dev, sizeof(struct plx_dma_desc) *
1514 ai_dma_ring_count(board),
1515 &devpriv->ai_dma_desc_bus_addr, GFP_KERNEL);
854472c2 1516 if (!devpriv->ai_dma_desc)
88b12a9a 1517 return -ENOMEM;
90cae794 1518
52762ad1 1519 if (ao_cmd_is_supported(board)) {
681d335a 1520 devpriv->ao_dma_desc =
d2b0fc6e
AKC
1521 dma_alloc_coherent(&pcidev->dev,
1522 sizeof(struct plx_dma_desc) *
1523 AO_DMA_RING_COUNT,
1524 &devpriv->ao_dma_desc_bus_addr,
1525 GFP_KERNEL);
854472c2 1526 if (!devpriv->ao_dma_desc)
88b12a9a 1527 return -ENOMEM;
88b12a9a 1528 }
12f992ad 1529 /* initialize dma descriptors */
52762ad1 1530 for (i = 0; i < ai_dma_ring_count(board); i++) {
681d335a 1531 devpriv->ai_dma_desc[i].pci_start_addr =
46ca84c4 1532 cpu_to_le32(devpriv->ai_buffer_bus_addr[i]);
52762ad1 1533 if (board->layout == LAYOUT_4020)
681d335a 1534 devpriv->ai_dma_desc[i].local_start_addr =
46ca84c4
IA
1535 cpu_to_le32(devpriv->local1_iobase +
1536 ADC_FIFO_REG);
88b12a9a 1537 else
681d335a 1538 devpriv->ai_dma_desc[i].local_start_addr =
46ca84c4
IA
1539 cpu_to_le32(devpriv->local0_iobase +
1540 ADC_FIFO_REG);
681d335a
HS
1541 devpriv->ai_dma_desc[i].transfer_size = cpu_to_le32(0);
1542 devpriv->ai_dma_desc[i].next =
46ca84c4 1543 cpu_to_le32((devpriv->ai_dma_desc_bus_addr +
52762ad1 1544 ((i + 1) % ai_dma_ring_count(board)) *
46ca84c4 1545 sizeof(devpriv->ai_dma_desc[0])) |
dde90d89
IA
1546 PLX_DMADPR_DESCPCI | PLX_DMADPR_TCINTR |
1547 PLX_DMADPR_XFERL2P);
88b12a9a 1548 }
52762ad1 1549 if (ao_cmd_is_supported(board)) {
88b12a9a 1550 for (i = 0; i < AO_DMA_RING_COUNT; i++) {
681d335a 1551 devpriv->ao_dma_desc[i].pci_start_addr =
46ca84c4 1552 cpu_to_le32(devpriv->ao_buffer_bus_addr[i]);
681d335a 1553 devpriv->ao_dma_desc[i].local_start_addr =
46ca84c4
IA
1554 cpu_to_le32(devpriv->local0_iobase +
1555 DAC_FIFO_REG);
1556 devpriv->ao_dma_desc[i].transfer_size = cpu_to_le32(0);
681d335a 1557 devpriv->ao_dma_desc[i].next =
46ca84c4
IA
1558 cpu_to_le32((devpriv->ao_dma_desc_bus_addr +
1559 ((i + 1) % (AO_DMA_RING_COUNT)) *
1560 sizeof(devpriv->ao_dma_desc[0])) |
dde90d89
IA
1561 PLX_DMADPR_DESCPCI |
1562 PLX_DMADPR_TCINTR);
88b12a9a
FMH
1563 }
1564 }
1565 return 0;
1566}
1567
f9804323
HS
1568static void cb_pcidas64_free_dma(struct comedi_device *dev)
1569{
52762ad1 1570 const struct pcidas64_board *board = dev->board_ptr;
f9804323
HS
1571 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1572 struct pcidas64_private *devpriv = dev->private;
1573 int i;
1574
1575 if (!devpriv)
1576 return;
1577
1578 /* free pci dma buffers */
52762ad1 1579 for (i = 0; i < ai_dma_ring_count(board); i++) {
f9804323 1580 if (devpriv->ai_buffer[i])
d2b0fc6e
AKC
1581 dma_free_coherent(&pcidev->dev,
1582 DMA_BUFFER_SIZE,
1583 devpriv->ai_buffer[i],
1584 devpriv->ai_buffer_bus_addr[i]);
f9804323
HS
1585 }
1586 for (i = 0; i < AO_DMA_RING_COUNT; i++) {
1587 if (devpriv->ao_buffer[i])
d2b0fc6e
AKC
1588 dma_free_coherent(&pcidev->dev,
1589 DMA_BUFFER_SIZE,
1590 devpriv->ao_buffer[i],
1591 devpriv->ao_buffer_bus_addr[i]);
f9804323
HS
1592 }
1593 /* free dma descriptors */
1594 if (devpriv->ai_dma_desc)
d2b0fc6e
AKC
1595 dma_free_coherent(&pcidev->dev,
1596 sizeof(struct plx_dma_desc) *
1597 ai_dma_ring_count(board),
1598 devpriv->ai_dma_desc,
1599 devpriv->ai_dma_desc_bus_addr);
f9804323 1600 if (devpriv->ao_dma_desc)
d2b0fc6e
AKC
1601 dma_free_coherent(&pcidev->dev,
1602 sizeof(struct plx_dma_desc) *
1603 AO_DMA_RING_COUNT,
1604 devpriv->ao_dma_desc,
1605 devpriv->ao_dma_desc_bus_addr);
f9804323
HS
1606}
1607
da91b269 1608static inline void warn_external_queue(struct comedi_device *dev)
88b12a9a 1609{
e176d78c
HS
1610 dev_err(dev->class_dev,
1611 "AO command and AI external channel queue cannot be used simultaneously\n");
1612 dev_err(dev->class_dev,
1613 "Use internal AI channel queue (channels must be consecutive and use same range/aref)\n");
88b12a9a
FMH
1614}
1615
f51ff7e4
AD
1616/*
1617 * their i2c requires a huge delay on setting clock or data high for some reason
1618 */
012e642c
IA
1619static const int i2c_high_udelay = 1000;
1620static const int i2c_low_udelay = 10;
1621
1622/* set i2c data line high or low */
1623static void i2c_set_sda(struct comedi_device *dev, int state)
1624{
1625 struct pcidas64_private *devpriv = dev->private;
a3228bc8 1626 static const int data_bit = PLX_CNTRL_EEWB;
012e642c 1627 void __iomem *plx_control_addr = devpriv->plx9080_iobase +
c644a11a 1628 PLX_REG_CNTRL;
012e642c 1629
12f992ad 1630 if (state) { /* set data line high */
012e642c
IA
1631 devpriv->plx_control_bits &= ~data_bit;
1632 writel(devpriv->plx_control_bits, plx_control_addr);
1633 udelay(i2c_high_udelay);
12f992ad 1634 } else { /* set data line low */
012e642c
IA
1635 devpriv->plx_control_bits |= data_bit;
1636 writel(devpriv->plx_control_bits, plx_control_addr);
1637 udelay(i2c_low_udelay);
1638 }
1639}
1640
1641/* set i2c clock line high or low */
1642static void i2c_set_scl(struct comedi_device *dev, int state)
1643{
1644 struct pcidas64_private *devpriv = dev->private;
a3228bc8 1645 static const int clock_bit = PLX_CNTRL_USERO;
012e642c 1646 void __iomem *plx_control_addr = devpriv->plx9080_iobase +
c644a11a 1647 PLX_REG_CNTRL;
012e642c 1648
12f992ad 1649 if (state) { /* set clock line high */
012e642c
IA
1650 devpriv->plx_control_bits &= ~clock_bit;
1651 writel(devpriv->plx_control_bits, plx_control_addr);
1652 udelay(i2c_high_udelay);
12f992ad 1653 } else { /* set clock line low */
012e642c
IA
1654 devpriv->plx_control_bits |= clock_bit;
1655 writel(devpriv->plx_control_bits, plx_control_addr);
1656 udelay(i2c_low_udelay);
1657 }
1658}
1659
1660static void i2c_write_byte(struct comedi_device *dev, uint8_t byte)
1661{
1662 uint8_t bit;
1663 unsigned int num_bits = 8;
1664
012e642c
IA
1665 for (bit = 1 << (num_bits - 1); bit; bit >>= 1) {
1666 i2c_set_scl(dev, 0);
1667 if ((byte & bit))
1668 i2c_set_sda(dev, 1);
1669 else
1670 i2c_set_sda(dev, 0);
1671 i2c_set_scl(dev, 1);
1672 }
1673}
1674
1675/* we can't really read the lines, so fake it */
1676static int i2c_read_ack(struct comedi_device *dev)
1677{
1678 i2c_set_scl(dev, 0);
1679 i2c_set_sda(dev, 1);
1680 i2c_set_scl(dev, 1);
1681
12f992ad 1682 return 0; /* return fake acknowledge bit */
012e642c
IA
1683}
1684
1685/* send start bit */
1686static void i2c_start(struct comedi_device *dev)
1687{
1688 i2c_set_scl(dev, 1);
1689 i2c_set_sda(dev, 1);
1690 i2c_set_sda(dev, 0);
1691}
1692
1693/* send stop bit */
1694static void i2c_stop(struct comedi_device *dev)
1695{
1696 i2c_set_scl(dev, 0);
1697 i2c_set_sda(dev, 0);
1698 i2c_set_scl(dev, 1);
1699 i2c_set_sda(dev, 1);
1700}
1701
1702static void i2c_write(struct comedi_device *dev, unsigned int address,
1703 const uint8_t *data, unsigned int length)
1704{
1705 struct pcidas64_private *devpriv = dev->private;
1706 unsigned int i;
1707 uint8_t bitstream;
1708 static const int read_bit = 0x1;
1709
85c12b82
AD
1710 /*
1711 * XXX need mutex to prevent simultaneous attempts to access
1712 * eeprom and i2c bus
1713 */
012e642c 1714
12f992ad 1715 /* make sure we dont send anything to eeprom */
a3228bc8 1716 devpriv->plx_control_bits &= ~PLX_CNTRL_EECS;
012e642c
IA
1717
1718 i2c_stop(dev);
1719 i2c_start(dev);
1720
12f992ad 1721 /* send address and write bit */
012e642c
IA
1722 bitstream = (address << 1) & ~read_bit;
1723 i2c_write_byte(dev, bitstream);
1724
12f992ad 1725 /* get acknowledge */
012e642c 1726 if (i2c_read_ack(dev) != 0) {
cd25503f 1727 dev_err(dev->class_dev, "failed: no acknowledge\n");
012e642c
IA
1728 i2c_stop(dev);
1729 return;
1730 }
12f992ad 1731 /* write data bytes */
012e642c
IA
1732 for (i = 0; i < length; i++) {
1733 i2c_write_byte(dev, data[i]);
1734 if (i2c_read_ack(dev) != 0) {
cd25503f 1735 dev_err(dev->class_dev, "failed: no acknowledge\n");
012e642c
IA
1736 i2c_stop(dev);
1737 return;
1738 }
1739 }
1740 i2c_stop(dev);
1741}
1742
96ed0850
HS
1743static int cb_pcidas64_ai_eoc(struct comedi_device *dev,
1744 struct comedi_subdevice *s,
1745 struct comedi_insn *insn,
1746 unsigned long context)
1747{
52762ad1 1748 const struct pcidas64_board *board = dev->board_ptr;
96ed0850
HS
1749 struct pcidas64_private *devpriv = dev->private;
1750 unsigned int status;
1751
1752 status = readw(devpriv->main_iobase + HW_STATUS_REG);
52762ad1 1753 if (board->layout == LAYOUT_4020) {
96ed0850
HS
1754 status = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG);
1755 if (status)
1756 return 0;
1757 } else {
1758 if (pipe_full_bits(status))
1759 return 0;
1760 }
1761 return -EBUSY;
1762}
1763
da91b269 1764static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 1765 struct comedi_insn *insn, unsigned int *data)
88b12a9a 1766{
52762ad1 1767 const struct pcidas64_board *board = dev->board_ptr;
681d335a 1768 struct pcidas64_private *devpriv = dev->private;
96ed0850 1769 unsigned int bits = 0, n;
88b12a9a
FMH
1770 unsigned int channel, range, aref;
1771 unsigned long flags;
96ed0850 1772 int ret;
88b12a9a 1773
88b12a9a
FMH
1774 channel = CR_CHAN(insn->chanspec);
1775 range = CR_RANGE(insn->chanspec);
1776 aref = CR_AREF(insn->chanspec);
1777
12f992ad
AJ
1778 /* disable card's analog input interrupt sources and pacing */
1779 /* 4020 generates dac done interrupts even though they are disabled */
88b12a9a
FMH
1780 disable_ai_pacing(dev);
1781
5f74ea14 1782 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a 1783 if (insn->chanspec & CR_ALT_FILTER)
681d335a 1784 devpriv->adc_control1_bits |= ADC_DITHER_BIT;
88b12a9a 1785 else
681d335a
HS
1786 devpriv->adc_control1_bits &= ~ADC_DITHER_BIT;
1787 writew(devpriv->adc_control1_bits,
1788 devpriv->main_iobase + ADC_CONTROL1_REG);
5f74ea14 1789 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 1790
52762ad1 1791 if (board->layout != LAYOUT_4020) {
12f992ad 1792 /* use internal queue */
681d335a
HS
1793 devpriv->hw_config_bits &= ~EXT_QUEUE_BIT;
1794 writew(devpriv->hw_config_bits,
1795 devpriv->main_iobase + HW_CONFIG_REG);
88b12a9a 1796
12f992ad 1797 /* ALT_SOURCE is internal calibration reference */
88b12a9a
FMH
1798 if (insn->chanspec & CR_ALT_SOURCE) {
1799 unsigned int cal_en_bit;
1800
52762ad1 1801 if (board->layout == LAYOUT_60XX)
88b12a9a
FMH
1802 cal_en_bit = CAL_EN_60XX_BIT;
1803 else
1804 cal_en_bit = CAL_EN_64XX_BIT;
85c12b82
AD
1805 /*
1806 * select internal reference source to connect
1807 * to channel 0
1808 */
0a85b6f0 1809 writew(cal_en_bit |
681d335a
HS
1810 adc_src_bits(devpriv->calibration_source),
1811 devpriv->main_iobase + CALIBRATION_REG);
88b12a9a 1812 } else {
85c12b82
AD
1813 /*
1814 * make sure internal calibration source
1815 * is turned off
1816 */
681d335a 1817 writew(0, devpriv->main_iobase + CALIBRATION_REG);
88b12a9a 1818 }
12f992ad 1819 /* load internal queue */
88b12a9a 1820 bits = 0;
12f992ad 1821 /* set gain */
88b12a9a 1822 bits |= ai_range_bits_6xxx(dev, CR_RANGE(insn->chanspec));
12f992ad 1823 /* set single-ended / differential */
88b12a9a
FMH
1824 bits |= se_diff_bit_6xxx(dev, aref == AREF_DIFF);
1825 if (aref == AREF_COMMON)
1826 bits |= ADC_COMMON_BIT;
1827 bits |= adc_chan_bits(channel);
12f992ad 1828 /* set stop channel */
88b12a9a 1829 writew(adc_chan_bits(channel),
681d335a 1830 devpriv->main_iobase + ADC_QUEUE_HIGH_REG);
12f992ad 1831 /* set start channel, and rest of settings */
681d335a 1832 writew(bits, devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
88b12a9a 1833 } else {
681d335a 1834 uint8_t old_cal_range_bits = devpriv->i2c_cal_range_bits;
88b12a9a 1835
681d335a 1836 devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
88b12a9a 1837 if (insn->chanspec & CR_ALT_SOURCE) {
681d335a 1838 devpriv->i2c_cal_range_bits |=
46ca84c4 1839 adc_src_4020_bits(devpriv->calibration_source);
9ef4dea6 1840 } else { /* select BNC inputs */
681d335a 1841 devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4);
88b12a9a 1842 }
12f992ad 1843 /* select range */
88b12a9a 1844 if (range == 0)
681d335a 1845 devpriv->i2c_cal_range_bits |= attenuate_bit(channel);
88b12a9a 1846 else
46ca84c4 1847 devpriv->i2c_cal_range_bits &= ~attenuate_bit(channel);
85c12b82
AD
1848 /*
1849 * update calibration/range i2c register only if necessary,
1850 * as it is very slow
1851 */
681d335a
HS
1852 if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
1853 uint8_t i2c_data = devpriv->i2c_cal_range_bits;
43358ed0 1854
88b12a9a 1855 i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
0a85b6f0 1856 sizeof(i2c_data));
88b12a9a
FMH
1857 }
1858
85c12b82
AD
1859 /*
1860 * 4020 manual asks that sample interval register to be set
46ca84c4
IA
1861 * before writing to convert register.
1862 * Using somewhat arbitrary setting of 4 master clock ticks
85c12b82
AD
1863 * = 0.1 usec
1864 */
46ca84c4
IA
1865 writew(0, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
1866 writew(2, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
88b12a9a
FMH
1867 }
1868
1869 for (n = 0; n < insn->n; n++) {
12f992ad 1870 /* clear adc buffer (inside loop for 4020 sake) */
681d335a 1871 writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG);
88b12a9a
FMH
1872
1873 /* trigger conversion, bits sent only matter for 4020 */
1874 writew(adc_convert_chan_4020_bits(CR_CHAN(insn->chanspec)),
681d335a 1875 devpriv->main_iobase + ADC_CONVERT_REG);
88b12a9a 1876
12f992ad 1877 /* wait for data */
96ed0850 1878 ret = comedi_timeout(dev, s, insn, cb_pcidas64_ai_eoc, 0);
22ca19d9 1879 if (ret)
96ed0850 1880 return ret;
96ed0850 1881
52762ad1 1882 if (board->layout == LAYOUT_4020)
9ebd1028 1883 data[n] = readl(dev->mmio + ADC_FIFO_REG) & 0xffff;
88b12a9a 1884 else
46ca84c4 1885 data[n] = readw(devpriv->main_iobase + PIPE1_READ_REG);
88b12a9a
FMH
1886 }
1887
1888 return n;
1889}
1890
0a85b6f0
MT
1891static int ai_config_calibration_source(struct comedi_device *dev,
1892 unsigned int *data)
88b12a9a 1893{
52762ad1 1894 const struct pcidas64_board *board = dev->board_ptr;
681d335a 1895 struct pcidas64_private *devpriv = dev->private;
790c5541 1896 unsigned int source = data[1];
88b12a9a
FMH
1897 int num_calibration_sources;
1898
52762ad1 1899 if (board->layout == LAYOUT_60XX)
88b12a9a
FMH
1900 num_calibration_sources = 16;
1901 else
1902 num_calibration_sources = 8;
1903 if (source >= num_calibration_sources) {
f41ad667 1904 dev_dbg(dev->class_dev, "invalid calibration source: %i\n",
6c6c227d 1905 source);
88b12a9a
FMH
1906 return -EINVAL;
1907 }
1908
681d335a 1909 devpriv->calibration_source = source;
88b12a9a
FMH
1910
1911 return 2;
1912}
1913
da91b269 1914static int ai_config_block_size(struct comedi_device *dev, unsigned int *data)
88b12a9a 1915{
52762ad1 1916 const struct pcidas64_board *board = dev->board_ptr;
88b12a9a 1917 int fifo_size;
52762ad1 1918 const struct hw_fifo_info *const fifo = board->ai_fifo;
88b12a9a
FMH
1919 unsigned int block_size, requested_block_size;
1920 int retval;
1921
1922 requested_block_size = data[1];
1923
1924 if (requested_block_size) {
46ca84c4
IA
1925 fifo_size = requested_block_size * fifo->num_segments /
1926 bytes_in_sample;
88b12a9a
FMH
1927
1928 retval = set_ai_fifo_size(dev, fifo_size);
1929 if (retval < 0)
1930 return retval;
88b12a9a
FMH
1931 }
1932
1933 block_size = ai_fifo_size(dev) / fifo->num_segments * bytes_in_sample;
1934
1935 data[1] = block_size;
1936
1937 return 2;
1938}
1939
0a85b6f0
MT
1940static int ai_config_master_clock_4020(struct comedi_device *dev,
1941 unsigned int *data)
88b12a9a 1942{
681d335a 1943 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
1944 unsigned int divisor = data[4];
1945 int retval = 0;
1946
1947 if (divisor < 2) {
1948 divisor = 2;
1949 retval = -EAGAIN;
1950 }
1951
1952 switch (data[1]) {
1953 case COMEDI_EV_SCAN_BEGIN:
681d335a
HS
1954 devpriv->ext_clock.divisor = divisor;
1955 devpriv->ext_clock.chanspec = data[2];
88b12a9a
FMH
1956 break;
1957 default:
1958 return -EINVAL;
88b12a9a
FMH
1959 }
1960
1961 data[4] = divisor;
1962
1963 return retval ? retval : 5;
1964}
1965
9ef4dea6 1966/* XXX could add support for 60xx series */
da91b269 1967static int ai_config_master_clock(struct comedi_device *dev, unsigned int *data)
88b12a9a 1968{
52762ad1 1969 const struct pcidas64_board *board = dev->board_ptr;
88b12a9a 1970
52762ad1 1971 switch (board->layout) {
88b12a9a
FMH
1972 case LAYOUT_4020:
1973 return ai_config_master_clock_4020(dev, data);
88b12a9a
FMH
1974 default:
1975 return -EINVAL;
88b12a9a
FMH
1976 }
1977
1978 return -EINVAL;
1979}
1980
da91b269 1981static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 1982 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
1983{
1984 int id = data[0];
1985
1986 switch (id) {
1987 case INSN_CONFIG_ALT_SOURCE:
1988 return ai_config_calibration_source(dev, data);
88b12a9a
FMH
1989 case INSN_CONFIG_BLOCK_SIZE:
1990 return ai_config_block_size(dev, data);
88b12a9a
FMH
1991 case INSN_CONFIG_TIMER_1:
1992 return ai_config_master_clock(dev, data);
88b12a9a
FMH
1993 default:
1994 return -EINVAL;
88b12a9a
FMH
1995 }
1996 return -EINVAL;
1997}
1998
85c12b82
AD
1999/*
2000 * Gets nearest achievable timing given master clock speed, does not
012e642c 2001 * take into account possible minimum/maximum divisor values. Used
85c12b82
AD
2002 * by other timing checking functions.
2003 */
012e642c
IA
2004static unsigned int get_divisor(unsigned int ns, unsigned int flags)
2005{
2006 unsigned int divisor;
2007
f772bd57
IA
2008 switch (flags & CMDF_ROUND_MASK) {
2009 case CMDF_ROUND_UP:
012e642c
IA
2010 divisor = (ns + TIMER_BASE - 1) / TIMER_BASE;
2011 break;
f772bd57 2012 case CMDF_ROUND_DOWN:
012e642c
IA
2013 divisor = ns / TIMER_BASE;
2014 break;
f772bd57 2015 case CMDF_ROUND_NEAREST:
012e642c 2016 default:
2ead7b32 2017 divisor = DIV_ROUND_CLOSEST(ns, TIMER_BASE);
012e642c
IA
2018 break;
2019 }
2020 return divisor;
2021}
2022
85c12b82
AD
2023/*
2024 * utility function that rounds desired timing to an achievable time, and
012e642c 2025 * sets cmd members appropriately.
f51ff7e4
AD
2026 * adc paces conversions from master clock by dividing by (x + 3) where x is
2027 * 24 bit number
012e642c
IA
2028 */
2029static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
2030{
52762ad1 2031 const struct pcidas64_board *board = dev->board_ptr;
1f5fc964
HS
2032 unsigned long long convert_divisor = 0;
2033 unsigned int scan_divisor;
012e642c
IA
2034 static const int min_convert_divisor = 3;
2035 static const int max_convert_divisor =
2036 max_counter_value + min_convert_divisor;
2037 static const int min_scan_divisor_4020 = 2;
2038 unsigned long long max_scan_divisor, min_scan_divisor;
2039
2040 if (cmd->convert_src == TRIG_TIMER) {
52762ad1 2041 if (board->layout == LAYOUT_4020) {
012e642c
IA
2042 cmd->convert_arg = 0;
2043 } else {
2044 convert_divisor = get_divisor(cmd->convert_arg,
2045 cmd->flags);
2046 if (convert_divisor > max_convert_divisor)
2047 convert_divisor = max_convert_divisor;
2048 if (convert_divisor < min_convert_divisor)
2049 convert_divisor = min_convert_divisor;
2050 cmd->convert_arg = convert_divisor * TIMER_BASE;
2051 }
2052 } else if (cmd->convert_src == TRIG_NOW) {
2053 cmd->convert_arg = 0;
2054 }
2055
2056 if (cmd->scan_begin_src == TRIG_TIMER) {
2057 scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags);
2058 if (cmd->convert_src == TRIG_TIMER) {
012e642c
IA
2059 min_scan_divisor = convert_divisor * cmd->chanlist_len;
2060 max_scan_divisor =
2061 (convert_divisor * cmd->chanlist_len - 1) +
2062 max_counter_value;
2063 } else {
2064 min_scan_divisor = min_scan_divisor_4020;
2065 max_scan_divisor = max_counter_value + min_scan_divisor;
2066 }
2067 if (scan_divisor > max_scan_divisor)
2068 scan_divisor = max_scan_divisor;
2069 if (scan_divisor < min_scan_divisor)
2070 scan_divisor = min_scan_divisor;
2071 cmd->scan_begin_arg = scan_divisor * TIMER_BASE;
2072 }
012e642c
IA
2073}
2074
e300e4fb
HS
2075static int cb_pcidas64_ai_check_chanlist(struct comedi_device *dev,
2076 struct comedi_subdevice *s,
2077 struct comedi_cmd *cmd)
2078{
3bc86feb 2079 const struct pcidas64_board *board = dev->board_ptr;
e300e4fb
HS
2080 unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
2081 int i;
2082
2083 for (i = 1; i < cmd->chanlist_len; i++) {
2084 unsigned int aref = CR_AREF(cmd->chanlist[i]);
2085
2086 if (aref != aref0) {
2087 dev_dbg(dev->class_dev,
2088 "all elements in chanlist must use the same analog reference\n");
2089 return -EINVAL;
2090 }
2091 }
2092
2093 if (board->layout == LAYOUT_4020) {
2094 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
2095
2096 for (i = 1; i < cmd->chanlist_len; i++) {
2097 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
2098
2099 if (chan != (chan0 + i)) {
2100 dev_dbg(dev->class_dev,
2101 "chanlist must use consecutive channels\n");
2102 return -EINVAL;
2103 }
2104 }
2105 if (cmd->chanlist_len == 3) {
2106 dev_dbg(dev->class_dev,
2107 "chanlist cannot be 3 channels long, use 1, 2, or 4 channels\n");
2108 return -EINVAL;
2109 }
2110 }
2111
2112 return 0;
2113}
2114
da91b269 2115static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 2116 struct comedi_cmd *cmd)
88b12a9a 2117{
52762ad1 2118 const struct pcidas64_board *board = dev->board_ptr;
88b12a9a 2119 int err = 0;
88b12a9a 2120 unsigned int tmp_arg, tmp_arg2;
88b12a9a
FMH
2121 unsigned int triggers;
2122
27020ffe 2123 /* Step 1 : check if triggers are trivially valid */
88b12a9a 2124
571cea09 2125 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
88b12a9a 2126
88b12a9a 2127 triggers = TRIG_TIMER;
52762ad1 2128 if (board->layout == LAYOUT_4020)
88b12a9a
FMH
2129 triggers |= TRIG_OTHER;
2130 else
2131 triggers |= TRIG_FOLLOW;
571cea09 2132 err |= comedi_check_trigger_src(&cmd->scan_begin_src, triggers);
88b12a9a 2133
88b12a9a 2134 triggers = TRIG_TIMER;
52762ad1 2135 if (board->layout == LAYOUT_4020)
88b12a9a
FMH
2136 triggers |= TRIG_NOW;
2137 else
2138 triggers |= TRIG_EXT;
571cea09
IA
2139 err |= comedi_check_trigger_src(&cmd->convert_src, triggers);
2140 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
2141 err |= comedi_check_trigger_src(&cmd->stop_src,
2142 TRIG_COUNT | TRIG_EXT | TRIG_NONE);
88b12a9a
FMH
2143
2144 if (err)
2145 return 1;
2146
27020ffe 2147 /* Step 2a : make sure trigger sources are unique */
88b12a9a 2148
571cea09
IA
2149 err |= comedi_check_trigger_is_unique(cmd->start_src);
2150 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
2151 err |= comedi_check_trigger_is_unique(cmd->convert_src);
2152 err |= comedi_check_trigger_is_unique(cmd->stop_src);
27020ffe
HS
2153
2154 /* Step 2b : and mutually compatible */
88b12a9a 2155
88b12a9a 2156 if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
27020ffe 2157 err |= -EINVAL;
88b12a9a
FMH
2158
2159 if (err)
2160 return 2;
2161
dba2939c 2162 /* Step 3: check if arguments are trivially valid */
88b12a9a 2163
020cb120
HS
2164 switch (cmd->start_src) {
2165 case TRIG_NOW:
571cea09 2166 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
020cb120
HS
2167 break;
2168 case TRIG_EXT:
2169 /*
2170 * start_arg is the CR_CHAN | CR_INVERT of the
2171 * external trigger.
2172 */
2173 break;
2174 }
2175
88b12a9a 2176 if (cmd->convert_src == TRIG_TIMER) {
52762ad1 2177 if (board->layout == LAYOUT_4020) {
571cea09
IA
2178 err |= comedi_check_trigger_arg_is(&cmd->convert_arg,
2179 0);
88b12a9a 2180 } else {
571cea09 2181 err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
52762ad1 2182 board->ai_speed);
571cea09
IA
2183 /*
2184 * if scans are timed faster than conversion rate
2185 * allows
2186 */
2187 if (cmd->scan_begin_src == TRIG_TIMER) {
2188 err |= comedi_check_trigger_arg_min(
dba2939c 2189 &cmd->scan_begin_arg,
46ca84c4 2190 cmd->convert_arg *
dba2939c 2191 cmd->chanlist_len);
571cea09 2192 }
88b12a9a
FMH
2193 }
2194 }
2195
571cea09
IA
2196 err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
2197 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
2198 cmd->chanlist_len);
88b12a9a
FMH
2199
2200 switch (cmd->stop_src) {
2201 case TRIG_EXT:
2202 break;
2203 case TRIG_COUNT:
571cea09 2204 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
88b12a9a
FMH
2205 break;
2206 case TRIG_NONE:
571cea09 2207 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
88b12a9a
FMH
2208 break;
2209 default:
2210 break;
2211 }
2212
2213 if (err)
2214 return 3;
2215
2216 /* step 4: fix up any arguments */
2217
2218 if (cmd->convert_src == TRIG_TIMER) {
2219 tmp_arg = cmd->convert_arg;
2220 tmp_arg2 = cmd->scan_begin_arg;
2221 check_adc_timing(dev, cmd);
2222 if (tmp_arg != cmd->convert_arg)
2223 err++;
2224 if (tmp_arg2 != cmd->scan_begin_arg)
2225 err++;
2226 }
2227
2228 if (err)
2229 return 4;
2230
e300e4fb
HS
2231 /* Step 5: check channel list if it exists */
2232 if (cmd->chanlist && cmd->chanlist_len > 0)
2233 err |= cb_pcidas64_ai_check_chanlist(dev, s, cmd);
88b12a9a
FMH
2234
2235 if (err)
2236 return 5;
2237
2238 return 0;
2239}
2240
da91b269 2241static int use_hw_sample_counter(struct comedi_cmd *cmd)
88b12a9a 2242{
9ef4dea6 2243/* disable for now until I work out a race */
88b12a9a
FMH
2244 return 0;
2245
2246 if (cmd->stop_src == TRIG_COUNT && cmd->stop_arg <= max_counter_value)
2247 return 1;
4ffeead3
HS
2248
2249 return 0;
88b12a9a
FMH
2250}
2251
0a85b6f0
MT
2252static void setup_sample_counters(struct comedi_device *dev,
2253 struct comedi_cmd *cmd)
88b12a9a 2254{
681d335a
HS
2255 struct pcidas64_private *devpriv = dev->private;
2256
12f992ad 2257 /* load hardware conversion counter */
88b12a9a
FMH
2258 if (use_hw_sample_counter(cmd)) {
2259 writew(cmd->stop_arg & 0xffff,
681d335a 2260 devpriv->main_iobase + ADC_COUNT_LOWER_REG);
88b12a9a 2261 writew((cmd->stop_arg >> 16) & 0xff,
681d335a 2262 devpriv->main_iobase + ADC_COUNT_UPPER_REG);
88b12a9a 2263 } else {
681d335a 2264 writew(1, devpriv->main_iobase + ADC_COUNT_LOWER_REG);
88b12a9a
FMH
2265 }
2266}
2267
da91b269 2268static inline unsigned int dma_transfer_size(struct comedi_device *dev)
88b12a9a 2269{
52762ad1 2270 const struct pcidas64_board *board = dev->board_ptr;
681d335a 2271 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2272 unsigned int num_samples;
2273
46ca84c4 2274 num_samples = devpriv->ai_fifo_segment_length *
52762ad1 2275 board->ai_fifo->sample_packing_ratio;
88b12a9a
FMH
2276 if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t))
2277 num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t);
2278
2279 return num_samples;
2280}
2281
da91b269 2282static uint32_t ai_convert_counter_6xxx(const struct comedi_device *dev,
0a85b6f0 2283 const struct comedi_cmd *cmd)
88b12a9a 2284{
12f992ad 2285 /* supposed to load counter with desired divisor minus 3 */
88b12a9a
FMH
2286 return cmd->convert_arg / TIMER_BASE - 3;
2287}
2288
0a85b6f0
MT
2289static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev,
2290 struct comedi_cmd *cmd)
88b12a9a
FMH
2291{
2292 uint32_t count;
46ca84c4 2293
12f992ad 2294 /* figure out how long we need to delay at end of scan */
88b12a9a
FMH
2295 switch (cmd->scan_begin_src) {
2296 case TRIG_TIMER:
2297 count = (cmd->scan_begin_arg -
46ca84c4
IA
2298 (cmd->convert_arg * (cmd->chanlist_len - 1))) /
2299 TIMER_BASE;
88b12a9a
FMH
2300 break;
2301 case TRIG_FOLLOW:
2302 count = cmd->convert_arg / TIMER_BASE;
2303 break;
2304 default:
2305 return 0;
88b12a9a
FMH
2306 }
2307 return count - 3;
2308}
2309
0a85b6f0
MT
2310static uint32_t ai_convert_counter_4020(struct comedi_device *dev,
2311 struct comedi_cmd *cmd)
88b12a9a 2312{
681d335a 2313 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2314 unsigned int divisor;
2315
2316 switch (cmd->scan_begin_src) {
2317 case TRIG_TIMER:
2318 divisor = cmd->scan_begin_arg / TIMER_BASE;
2319 break;
2320 case TRIG_OTHER:
681d335a 2321 divisor = devpriv->ext_clock.divisor;
88b12a9a 2322 break;
12f992ad 2323 default: /* should never happen */
e176d78c 2324 dev_err(dev->class_dev, "bug! failed to set ai pacing!\n");
88b12a9a
FMH
2325 divisor = 1000;
2326 break;
2327 }
2328
12f992ad 2329 /* supposed to load counter with desired divisor minus 2 for 4020 */
88b12a9a
FMH
2330 return divisor - 2;
2331}
2332
da91b269 2333static void select_master_clock_4020(struct comedi_device *dev,
0a85b6f0 2334 const struct comedi_cmd *cmd)
88b12a9a 2335{
681d335a
HS
2336 struct pcidas64_private *devpriv = dev->private;
2337
12f992ad 2338 /* select internal/external master clock */
681d335a 2339 devpriv->hw_config_bits &= ~MASTER_CLOCK_4020_MASK;
88b12a9a 2340 if (cmd->scan_begin_src == TRIG_OTHER) {
681d335a 2341 int chanspec = devpriv->ext_clock.chanspec;
88b12a9a
FMH
2342
2343 if (CR_CHAN(chanspec))
681d335a 2344 devpriv->hw_config_bits |= BNC_CLOCK_4020_BITS;
88b12a9a 2345 else
681d335a 2346 devpriv->hw_config_bits |= EXT_CLOCK_4020_BITS;
88b12a9a 2347 } else {
681d335a 2348 devpriv->hw_config_bits |= INTERNAL_CLOCK_4020_BITS;
88b12a9a 2349 }
681d335a
HS
2350 writew(devpriv->hw_config_bits,
2351 devpriv->main_iobase + HW_CONFIG_REG);
88b12a9a
FMH
2352}
2353
0a85b6f0
MT
2354static void select_master_clock(struct comedi_device *dev,
2355 const struct comedi_cmd *cmd)
88b12a9a 2356{
52762ad1 2357 const struct pcidas64_board *board = dev->board_ptr;
b07244ce 2358
52762ad1 2359 switch (board->layout) {
88b12a9a
FMH
2360 case LAYOUT_4020:
2361 select_master_clock_4020(dev, cmd);
2362 break;
2363 default:
2364 break;
2365 }
2366}
2367
0a85b6f0
MT
2368static inline void dma_start_sync(struct comedi_device *dev,
2369 unsigned int channel)
88b12a9a 2370{
681d335a 2371 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2372 unsigned long flags;
2373
12f992ad 2374 /* spinlock for plx dma control/status reg */
5f74ea14 2375 spin_lock_irqsave(&dev->spinlock, flags);
3dcf1b55 2376 writeb(PLX_DMACSR_ENABLE | PLX_DMACSR_START | PLX_DMACSR_CLEARINTR,
c644a11a 2377 devpriv->plx9080_iobase + PLX_REG_DMACSR(channel));
5f74ea14 2378 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
2379}
2380
da91b269 2381static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd)
88b12a9a 2382{
52762ad1 2383 const struct pcidas64_board *board = dev->board_ptr;
681d335a 2384 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2385 uint32_t convert_counter = 0, scan_counter = 0;
2386
2387 check_adc_timing(dev, cmd);
2388
2389 select_master_clock(dev, cmd);
2390
52762ad1 2391 if (board->layout == LAYOUT_4020) {
88b12a9a
FMH
2392 convert_counter = ai_convert_counter_4020(dev, cmd);
2393 } else {
2394 convert_counter = ai_convert_counter_6xxx(dev, cmd);
2395 scan_counter = ai_scan_counter_6xxx(dev, cmd);
2396 }
2397
12f992ad 2398 /* load lower 16 bits of convert interval */
88b12a9a 2399 writew(convert_counter & 0xffff,
681d335a 2400 devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
12f992ad 2401 /* load upper 8 bits of convert interval */
88b12a9a 2402 writew((convert_counter >> 16) & 0xff,
681d335a 2403 devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
12f992ad 2404 /* load lower 16 bits of scan delay */
88b12a9a 2405 writew(scan_counter & 0xffff,
681d335a 2406 devpriv->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG);
12f992ad 2407 /* load upper 8 bits of scan delay */
88b12a9a 2408 writew((scan_counter >> 16) & 0xff,
681d335a 2409 devpriv->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG);
88b12a9a
FMH
2410}
2411
da91b269 2412static int use_internal_queue_6xxx(const struct comedi_cmd *cmd)
88b12a9a
FMH
2413{
2414 int i;
46ca84c4 2415
88b12a9a
FMH
2416 for (i = 0; i + 1 < cmd->chanlist_len; i++) {
2417 if (CR_CHAN(cmd->chanlist[i + 1]) !=
0a85b6f0 2418 CR_CHAN(cmd->chanlist[i]) + 1)
88b12a9a
FMH
2419 return 0;
2420 if (CR_RANGE(cmd->chanlist[i + 1]) !=
0a85b6f0 2421 CR_RANGE(cmd->chanlist[i]))
88b12a9a
FMH
2422 return 0;
2423 if (CR_AREF(cmd->chanlist[i + 1]) != CR_AREF(cmd->chanlist[i]))
2424 return 0;
2425 }
2426 return 1;
2427}
2428
0a85b6f0
MT
2429static int setup_channel_queue(struct comedi_device *dev,
2430 const struct comedi_cmd *cmd)
88b12a9a 2431{
52762ad1 2432 const struct pcidas64_board *board = dev->board_ptr;
681d335a 2433 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2434 unsigned short bits;
2435 int i;
2436
52762ad1 2437 if (board->layout != LAYOUT_4020) {
88b12a9a 2438 if (use_internal_queue_6xxx(cmd)) {
681d335a
HS
2439 devpriv->hw_config_bits &= ~EXT_QUEUE_BIT;
2440 writew(devpriv->hw_config_bits,
2441 devpriv->main_iobase + HW_CONFIG_REG);
88b12a9a 2442 bits = 0;
12f992ad 2443 /* set channel */
88b12a9a 2444 bits |= adc_chan_bits(CR_CHAN(cmd->chanlist[0]));
12f992ad 2445 /* set gain */
88b12a9a 2446 bits |= ai_range_bits_6xxx(dev,
0a85b6f0 2447 CR_RANGE(cmd->chanlist[0]));
12f992ad 2448 /* set single-ended / differential */
88b12a9a 2449 bits |= se_diff_bit_6xxx(dev,
0a85b6f0
MT
2450 CR_AREF(cmd->chanlist[0]) ==
2451 AREF_DIFF);
88b12a9a
FMH
2452 if (CR_AREF(cmd->chanlist[0]) == AREF_COMMON)
2453 bits |= ADC_COMMON_BIT;
12f992ad 2454 /* set stop channel */
0a85b6f0
MT
2455 writew(adc_chan_bits
2456 (CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])),
681d335a 2457 devpriv->main_iobase + ADC_QUEUE_HIGH_REG);
12f992ad 2458 /* set start channel, and rest of settings */
88b12a9a 2459 writew(bits,
681d335a 2460 devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
88b12a9a 2461 } else {
12f992ad 2462 /* use external queue */
88b12a9a
FMH
2463 if (dev->write_subdev && dev->write_subdev->busy) {
2464 warn_external_queue(dev);
2465 return -EBUSY;
2466 }
681d335a
HS
2467 devpriv->hw_config_bits |= EXT_QUEUE_BIT;
2468 writew(devpriv->hw_config_bits,
2469 devpriv->main_iobase + HW_CONFIG_REG);
12f992ad 2470 /* clear DAC buffer to prevent weird interactions */
88b12a9a 2471 writew(0,
681d335a 2472 devpriv->main_iobase + DAC_BUFFER_CLEAR_REG);
12f992ad 2473 /* clear queue pointer */
681d335a 2474 writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
12f992ad 2475 /* load external queue */
88b12a9a
FMH
2476 for (i = 0; i < cmd->chanlist_len; i++) {
2477 bits = 0;
12f992ad 2478 /* set channel */
46ca84c4
IA
2479 bits |= adc_chan_bits(CR_CHAN(cmd->
2480 chanlist[i]));
12f992ad 2481 /* set gain */
88b12a9a 2482 bits |= ai_range_bits_6xxx(dev,
0a85b6f0
MT
2483 CR_RANGE(cmd->
2484 chanlist
2485 [i]));
12f992ad 2486 /* set single-ended / differential */
88b12a9a 2487 bits |= se_diff_bit_6xxx(dev,
0a85b6f0
MT
2488 CR_AREF(cmd->
2489 chanlist[i]) ==
2490 AREF_DIFF);
88b12a9a
FMH
2491 if (CR_AREF(cmd->chanlist[i]) == AREF_COMMON)
2492 bits |= ADC_COMMON_BIT;
12f992ad 2493 /* mark end of queue */
88b12a9a
FMH
2494 if (i == cmd->chanlist_len - 1)
2495 bits |= QUEUE_EOSCAN_BIT |
46ca84c4 2496 QUEUE_EOSEQ_BIT;
88b12a9a 2497 writew(bits,
681d335a 2498 devpriv->main_iobase +
0a85b6f0 2499 ADC_QUEUE_FIFO_REG);
88b12a9a 2500 }
85c12b82
AD
2501 /*
2502 * doing a queue clear is not specified in board docs,
2503 * but required for reliable operation
2504 */
681d335a 2505 writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
12f992ad 2506 /* prime queue holding register */
681d335a 2507 writew(0, devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
88b12a9a
FMH
2508 }
2509 } else {
46ca84c4 2510 unsigned short old_cal_range_bits = devpriv->i2c_cal_range_bits;
88b12a9a 2511
681d335a 2512 devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
9ef4dea6 2513 /* select BNC inputs */
681d335a 2514 devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4);
12f992ad 2515 /* select ranges */
88b12a9a
FMH
2516 for (i = 0; i < cmd->chanlist_len; i++) {
2517 unsigned int channel = CR_CHAN(cmd->chanlist[i]);
2518 unsigned int range = CR_RANGE(cmd->chanlist[i]);
2519
2520 if (range == 0)
681d335a 2521 devpriv->i2c_cal_range_bits |=
46ca84c4 2522 attenuate_bit(channel);
88b12a9a 2523 else
681d335a 2524 devpriv->i2c_cal_range_bits &=
46ca84c4 2525 ~attenuate_bit(channel);
88b12a9a 2526 }
85c12b82
AD
2527 /*
2528 * update calibration/range i2c register only if necessary,
2529 * as it is very slow
2530 */
681d335a
HS
2531 if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
2532 uint8_t i2c_data = devpriv->i2c_cal_range_bits;
43358ed0 2533
88b12a9a 2534 i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
0a85b6f0 2535 sizeof(i2c_data));
88b12a9a
FMH
2536 }
2537 }
2538 return 0;
2539}
2540
da91b269 2541static inline void load_first_dma_descriptor(struct comedi_device *dev,
0a85b6f0
MT
2542 unsigned int dma_channel,
2543 unsigned int descriptor_bits)
88b12a9a 2544{
681d335a
HS
2545 struct pcidas64_private *devpriv = dev->private;
2546
85c12b82
AD
2547 /*
2548 * The transfer size, pci address, and local address registers
88b12a9a
FMH
2549 * are supposedly unused during chained dma,
2550 * but I have found that left over values from last operation
2551 * occasionally cause problems with transfer of first dma
85c12b82
AD
2552 * block. Initializing them to zero seems to fix the problem.
2553 */
88b12a9a 2554 if (dma_channel) {
c644a11a
IA
2555 writel(0, devpriv->plx9080_iobase + PLX_REG_DMASIZ1);
2556 writel(0, devpriv->plx9080_iobase + PLX_REG_DMAPADR1);
2557 writel(0, devpriv->plx9080_iobase + PLX_REG_DMALADR1);
88b12a9a 2558 writel(descriptor_bits,
c644a11a 2559 devpriv->plx9080_iobase + PLX_REG_DMADPR1);
88b12a9a 2560 } else {
c644a11a
IA
2561 writel(0, devpriv->plx9080_iobase + PLX_REG_DMASIZ0);
2562 writel(0, devpriv->plx9080_iobase + PLX_REG_DMAPADR0);
2563 writel(0, devpriv->plx9080_iobase + PLX_REG_DMALADR0);
88b12a9a 2564 writel(descriptor_bits,
c644a11a 2565 devpriv->plx9080_iobase + PLX_REG_DMADPR0);
88b12a9a
FMH
2566 }
2567}
2568
da91b269 2569static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
88b12a9a 2570{
52762ad1 2571 const struct pcidas64_board *board = dev->board_ptr;
681d335a 2572 struct pcidas64_private *devpriv = dev->private;
d163679c 2573 struct comedi_async *async = s->async;
ea6d0d4c 2574 struct comedi_cmd *cmd = &async->cmd;
88b12a9a
FMH
2575 uint32_t bits;
2576 unsigned int i;
2577 unsigned long flags;
2578 int retval;
2579
2580 disable_ai_pacing(dev);
2581 abort_dma(dev, 1);
2582
2583 retval = setup_channel_queue(dev, cmd);
2584 if (retval < 0)
2585 return retval;
2586
12f992ad 2587 /* make sure internal calibration source is turned off */
681d335a 2588 writew(0, devpriv->main_iobase + CALIBRATION_REG);
88b12a9a
FMH
2589
2590 set_ai_pacing(dev, cmd);
2591
2592 setup_sample_counters(dev, cmd);
2593
2594 enable_ai_interrupts(dev, cmd);
2595
5f74ea14 2596 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a 2597 /* set mode, allow conversions through software gate */
681d335a
HS
2598 devpriv->adc_control1_bits |= ADC_SW_GATE_BIT;
2599 devpriv->adc_control1_bits &= ~ADC_DITHER_BIT;
52762ad1 2600 if (board->layout != LAYOUT_4020) {
681d335a 2601 devpriv->adc_control1_bits &= ~ADC_MODE_MASK;
88b12a9a 2602 if (cmd->convert_src == TRIG_EXT)
12f992ad 2603 /* good old mode 13 */
46ca84c4 2604 devpriv->adc_control1_bits |= adc_mode_bits(13);
88b12a9a 2605 else
12f992ad 2606 /* mode 8. What else could you need? */
46ca84c4 2607 devpriv->adc_control1_bits |= adc_mode_bits(8);
88b12a9a 2608 } else {
681d335a 2609 devpriv->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK;
88b12a9a 2610 if (cmd->chanlist_len == 4)
681d335a 2611 devpriv->adc_control1_bits |= FOUR_CHANNEL_4020_BITS;
88b12a9a 2612 else if (cmd->chanlist_len == 2)
681d335a
HS
2613 devpriv->adc_control1_bits |= TWO_CHANNEL_4020_BITS;
2614 devpriv->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK;
2615 devpriv->adc_control1_bits |=
46ca84c4 2616 adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0]));
681d335a
HS
2617 devpriv->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK;
2618 devpriv->adc_control1_bits |=
46ca84c4
IA
2619 adc_hi_chan_4020_bits(CR_CHAN(cmd->chanlist
2620 [cmd->chanlist_len - 1]));
88b12a9a 2621 }
681d335a
HS
2622 writew(devpriv->adc_control1_bits,
2623 devpriv->main_iobase + ADC_CONTROL1_REG);
5f74ea14 2624 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 2625
12f992ad 2626 /* clear adc buffer */
681d335a 2627 writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG);
88b12a9a 2628
0ad08e4b 2629 if ((cmd->flags & CMDF_WAKE_EOS) == 0 ||
52762ad1 2630 board->layout == LAYOUT_4020) {
681d335a 2631 devpriv->ai_dma_index = 0;
88b12a9a 2632
12f992ad 2633 /* set dma transfer size */
52762ad1 2634 for (i = 0; i < ai_dma_ring_count(board); i++)
681d335a 2635 devpriv->ai_dma_desc[i].transfer_size =
46ca84c4
IA
2636 cpu_to_le32(dma_transfer_size(dev) *
2637 sizeof(uint16_t));
88b12a9a 2638
12f992ad 2639 /* give location of first dma descriptor */
88b12a9a 2640 load_first_dma_descriptor(dev, 1,
681d335a 2641 devpriv->ai_dma_desc_bus_addr |
dde90d89
IA
2642 PLX_DMADPR_DESCPCI |
2643 PLX_DMADPR_TCINTR |
2644 PLX_DMADPR_XFERL2P);
88b12a9a
FMH
2645
2646 dma_start_sync(dev, 1);
2647 }
2648
52762ad1 2649 if (board->layout == LAYOUT_4020) {
88b12a9a
FMH
2650 /* set source for external triggers */
2651 bits = 0;
2652 if (cmd->start_src == TRIG_EXT && CR_CHAN(cmd->start_arg))
2653 bits |= EXT_START_TRIG_BNC_BIT;
2654 if (cmd->stop_src == TRIG_EXT && CR_CHAN(cmd->stop_arg))
2655 bits |= EXT_STOP_TRIG_BNC_BIT;
681d335a 2656 writew(bits, devpriv->main_iobase + DAQ_ATRIG_LOW_4020_REG);
88b12a9a
FMH
2657 }
2658
5f74ea14 2659 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a
FMH
2660
2661 /* enable pacing, triggering, etc */
2662 bits = ADC_ENABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT;
0ad08e4b 2663 if (cmd->flags & CMDF_WAKE_EOS)
88b12a9a 2664 bits |= ADC_DMA_DISABLE_BIT;
12f992ad 2665 /* set start trigger */
88b12a9a
FMH
2666 if (cmd->start_src == TRIG_EXT) {
2667 bits |= ADC_START_TRIG_EXT_BITS;
2668 if (cmd->start_arg & CR_INVERT)
2669 bits |= ADC_START_TRIG_FALLING_BIT;
6ac986d0 2670 } else if (cmd->start_src == TRIG_NOW) {
88b12a9a 2671 bits |= ADC_START_TRIG_SOFT_BITS;
6ac986d0 2672 }
88b12a9a
FMH
2673 if (use_hw_sample_counter(cmd))
2674 bits |= ADC_SAMPLE_COUNTER_EN_BIT;
681d335a 2675 writew(bits, devpriv->main_iobase + ADC_CONTROL0_REG);
88b12a9a 2676
681d335a 2677 devpriv->ai_cmd_running = 1;
88b12a9a 2678
5f74ea14 2679 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 2680
12f992ad 2681 /* start acquisition */
220edb91 2682 if (cmd->start_src == TRIG_NOW)
681d335a 2683 writew(0, devpriv->main_iobase + ADC_START_REG);
88b12a9a
FMH
2684
2685 return 0;
2686}
2687
9ef4dea6 2688/* read num_samples from 16 bit wide ai fifo */
da91b269 2689static void pio_drain_ai_fifo_16(struct comedi_device *dev)
88b12a9a 2690{
681d335a 2691 struct pcidas64_private *devpriv = dev->private;
34c43922 2692 struct comedi_subdevice *s = dev->read_subdev;
88b12a9a
FMH
2693 unsigned int i;
2694 uint16_t prepost_bits;
2695 int read_segment, read_index, write_segment, write_index;
2696 int num_samples;
2697
2698 do {
12f992ad 2699 /* get least significant 15 bits */
46ca84c4
IA
2700 read_index = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) &
2701 0x7fff;
2702 write_index = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) &
2703 0x7fff;
85c12b82
AD
2704 /*
2705 * Get most significant bits (grey code).
46ca84c4
IA
2706 * Different boards use different code so use a scheme
2707 * that doesn't depend on encoding. This read must
88b12a9a 2708 * occur after reading least significant 15 bits to avoid race
85c12b82
AD
2709 * with fifo switching to next segment.
2710 */
681d335a 2711 prepost_bits = readw(devpriv->main_iobase + PREPOST_REG);
88b12a9a 2712
85c12b82
AD
2713 /*
2714 * if read and write pointers are not on the same fifo segment,
2715 * read to the end of the read segment
2716 */
88b12a9a
FMH
2717 read_segment = adc_upper_read_ptr_code(prepost_bits);
2718 write_segment = adc_upper_write_ptr_code(prepost_bits);
2719
88b12a9a
FMH
2720 if (read_segment != write_segment)
2721 num_samples =
46ca84c4 2722 devpriv->ai_fifo_segment_length - read_index;
88b12a9a
FMH
2723 else
2724 num_samples = write_index - read_index;
88b12a9a 2725 if (num_samples < 0) {
f41ad667
IA
2726 dev_err(dev->class_dev,
2727 "cb_pcidas64: bug! num_samples < 0\n");
88b12a9a
FMH
2728 break;
2729 }
2730
ccedb440
HS
2731 num_samples = comedi_nsamples_left(s, num_samples);
2732 if (num_samples == 0)
2733 break;
2734
88b12a9a 2735 for (i = 0; i < num_samples; i++) {
7ba38a01
HS
2736 unsigned short val;
2737
2738 val = readw(devpriv->main_iobase + ADC_FIFO_REG);
2739 comedi_buf_write_samples(s, &val, 1);
88b12a9a
FMH
2740 }
2741
2742 } while (read_segment != write_segment);
2743}
2744
85c12b82
AD
2745/*
2746 * Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of
46ca84c4
IA
2747 * pointers. The pci-4020 hardware only supports dma transfers (it only
2748 * supports the use of pio for draining the last remaining points from the
2749 * fifo when a data acquisition operation has completed).
88b12a9a 2750 */
da91b269 2751static void pio_drain_ai_fifo_32(struct comedi_device *dev)
88b12a9a 2752{
681d335a 2753 struct pcidas64_private *devpriv = dev->private;
34c43922 2754 struct comedi_subdevice *s = dev->read_subdev;
ccedb440 2755 unsigned int nsamples;
88b12a9a 2756 unsigned int i;
88b12a9a
FMH
2757 uint32_t fifo_data;
2758 int write_code =
46ca84c4 2759 readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
88b12a9a 2760 int read_code =
46ca84c4 2761 readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
88b12a9a 2762
ccedb440
HS
2763 nsamples = comedi_nsamples_left(s, 100000);
2764 for (i = 0; read_code != write_code && i < nsamples;) {
7ba38a01
HS
2765 unsigned short val;
2766
9ebd1028 2767 fifo_data = readl(dev->mmio + ADC_FIFO_REG);
7ba38a01
HS
2768 val = fifo_data & 0xffff;
2769 comedi_buf_write_samples(s, &val, 1);
88b12a9a 2770 i++;
ccedb440 2771 if (i < nsamples) {
7ba38a01
HS
2772 val = (fifo_data >> 16) & 0xffff;
2773 comedi_buf_write_samples(s, &val, 1);
88b12a9a
FMH
2774 i++;
2775 }
46ca84c4
IA
2776 read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) &
2777 0x7fff;
88b12a9a 2778 }
88b12a9a
FMH
2779}
2780
9ef4dea6 2781/* empty fifo */
da91b269 2782static void pio_drain_ai_fifo(struct comedi_device *dev)
88b12a9a 2783{
52762ad1 2784 const struct pcidas64_board *board = dev->board_ptr;
b07244ce 2785
52762ad1 2786 if (board->layout == LAYOUT_4020)
88b12a9a 2787 pio_drain_ai_fifo_32(dev);
90cae794 2788 else
88b12a9a
FMH
2789 pio_drain_ai_fifo_16(dev);
2790}
2791
da91b269 2792static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
88b12a9a 2793{
52762ad1 2794 const struct pcidas64_board *board = dev->board_ptr;
681d335a 2795 struct pcidas64_private *devpriv = dev->private;
ccedb440 2796 struct comedi_subdevice *s = dev->read_subdev;
88b12a9a
FMH
2797 uint32_t next_transfer_addr;
2798 int j;
2799 int num_samples = 0;
f31d0008 2800 void __iomem *pci_addr_reg;
88b12a9a 2801
c644a11a 2802 pci_addr_reg = devpriv->plx9080_iobase + PLX_REG_DMAPADR(channel);
88b12a9a 2803
12f992ad 2804 /* loop until we have read all the full buffers */
88b12a9a 2805 for (j = 0, next_transfer_addr = readl(pci_addr_reg);
0a85b6f0 2806 (next_transfer_addr <
46ca84c4
IA
2807 devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] ||
2808 next_transfer_addr >=
681d335a 2809 devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] +
52762ad1 2810 DMA_BUFFER_SIZE) && j < ai_dma_ring_count(board); j++) {
12f992ad 2811 /* transfer data from dma buffer to comedi buffer */
ccedb440
HS
2812 num_samples = comedi_nsamples_left(s, dma_transfer_size(dev));
2813 comedi_buf_write_samples(s,
7ba38a01
HS
2814 devpriv->ai_buffer[devpriv->ai_dma_index],
2815 num_samples);
46ca84c4 2816 devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) %
52762ad1 2817 ai_dma_ring_count(board);
88b12a9a 2818 }
85c12b82
AD
2819 /*
2820 * XXX check for dma ring buffer overrun
2821 * (use end-of-chain bit to mark last unused buffer)
2822 */
88b12a9a
FMH
2823}
2824
f31d0008
GKH
2825static void handle_ai_interrupt(struct comedi_device *dev,
2826 unsigned short status,
2827 unsigned int plx_status)
88b12a9a 2828{
52762ad1 2829 const struct pcidas64_board *board = dev->board_ptr;
681d335a 2830 struct pcidas64_private *devpriv = dev->private;
34c43922 2831 struct comedi_subdevice *s = dev->read_subdev;
d163679c 2832 struct comedi_async *async = s->async;
ea6d0d4c 2833 struct comedi_cmd *cmd = &async->cmd;
88b12a9a
FMH
2834 uint8_t dma1_status;
2835 unsigned long flags;
2836
12f992ad 2837 /* check for fifo overrun */
88b12a9a 2838 if (status & ADC_OVERRUN_BIT) {
e176d78c 2839 dev_err(dev->class_dev, "fifo overrun\n");
3e6cb74f 2840 async->events |= COMEDI_CB_ERROR;
88b12a9a 2841 }
12f992ad 2842 /* spin lock makes sure no one else changes plx dma control reg */
5f74ea14 2843 spin_lock_irqsave(&dev->spinlock, flags);
c644a11a 2844 dma1_status = readb(devpriv->plx9080_iobase + PLX_REG_DMACSR1);
12f992ad 2845 if (plx_status & PLX_INTCSR_DMA1IA) { /* dma chan 1 interrupt */
3dcf1b55 2846 writeb((dma1_status & PLX_DMACSR_ENABLE) | PLX_DMACSR_CLEARINTR,
c644a11a 2847 devpriv->plx9080_iobase + PLX_REG_DMACSR1);
88b12a9a 2848
3dcf1b55 2849 if (dma1_status & PLX_DMACSR_ENABLE)
88b12a9a 2850 drain_dma_buffers(dev, 1);
88b12a9a 2851 }
5f74ea14 2852 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 2853
12f992ad 2854 /* drain fifo with pio */
88b12a9a 2855 if ((status & ADC_DONE_BIT) ||
0ad08e4b 2856 ((cmd->flags & CMDF_WAKE_EOS) &&
0a85b6f0 2857 (status & ADC_INTR_PENDING_BIT) &&
52762ad1 2858 (board->layout != LAYOUT_4020))) {
5f74ea14 2859 spin_lock_irqsave(&dev->spinlock, flags);
681d335a 2860 if (devpriv->ai_cmd_running) {
5f74ea14 2861 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 2862 pio_drain_ai_fifo(dev);
6ac986d0 2863 } else {
5f74ea14 2864 spin_unlock_irqrestore(&dev->spinlock, flags);
6ac986d0 2865 }
88b12a9a 2866 }
12f992ad 2867 /* if we are have all the data, then quit */
ccedb440
HS
2868 if ((cmd->stop_src == TRIG_COUNT &&
2869 async->scans_done >= cmd->stop_arg) ||
2870 (cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT)))
88b12a9a 2871 async->events |= COMEDI_CB_EOA;
88b12a9a 2872
62fc6407 2873 comedi_handle_events(dev, s);
88b12a9a
FMH
2874}
2875
da91b269 2876static inline unsigned int prev_ao_dma_index(struct comedi_device *dev)
88b12a9a 2877{
681d335a 2878 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2879 unsigned int buffer_index;
2880
681d335a 2881 if (devpriv->ao_dma_index == 0)
88b12a9a
FMH
2882 buffer_index = AO_DMA_RING_COUNT - 1;
2883 else
681d335a 2884 buffer_index = devpriv->ao_dma_index - 1;
88b12a9a
FMH
2885 return buffer_index;
2886}
2887
da91b269 2888static int last_ao_dma_load_completed(struct comedi_device *dev)
88b12a9a 2889{
681d335a 2890 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2891 unsigned int buffer_index;
2892 unsigned int transfer_address;
2893 unsigned short dma_status;
2894
2895 buffer_index = prev_ao_dma_index(dev);
c644a11a 2896 dma_status = readb(devpriv->plx9080_iobase + PLX_REG_DMACSR0);
3dcf1b55 2897 if ((dma_status & PLX_DMACSR_DONE) == 0)
88b12a9a
FMH
2898 return 0;
2899
2900 transfer_address =
c644a11a 2901 readl(devpriv->plx9080_iobase + PLX_REG_DMAPADR0);
681d335a 2902 if (transfer_address != devpriv->ao_buffer_bus_addr[buffer_index])
88b12a9a
FMH
2903 return 0;
2904
2905 return 1;
2906}
2907
da91b269 2908static inline int ao_dma_needs_restart(struct comedi_device *dev,
0a85b6f0 2909 unsigned short dma_status)
88b12a9a 2910{
3dcf1b55
IA
2911 if ((dma_status & PLX_DMACSR_DONE) == 0 ||
2912 (dma_status & PLX_DMACSR_ENABLE) == 0)
88b12a9a
FMH
2913 return 0;
2914 if (last_ao_dma_load_completed(dev))
2915 return 0;
2916
2917 return 1;
2918}
2919
da91b269 2920static void restart_ao_dma(struct comedi_device *dev)
88b12a9a 2921{
681d335a 2922 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2923 unsigned int dma_desc_bits;
2924
c644a11a 2925 dma_desc_bits = readl(devpriv->plx9080_iobase + PLX_REG_DMADPR0);
dde90d89 2926 dma_desc_bits &= ~PLX_DMADPR_CHAINEND;
88b12a9a
FMH
2927 load_first_dma_descriptor(dev, 0, dma_desc_bits);
2928
2929 dma_start_sync(dev, 0);
2930}
2931
7bd7d905
HS
2932static unsigned int cb_pcidas64_ao_fill_buffer(struct comedi_device *dev,
2933 struct comedi_subdevice *s,
2934 unsigned short *dest,
2935 unsigned int max_bytes)
2936{
c39e050d 2937 unsigned int nsamples = comedi_bytes_to_samples(s, max_bytes);
7bd7d905
HS
2938 unsigned int actual_bytes;
2939
0be887b9 2940 nsamples = comedi_nsamples_left(s, nsamples);
7bd7d905 2941 actual_bytes = comedi_buf_read_samples(s, dest, nsamples);
7bd7d905 2942
0be887b9 2943 return comedi_bytes_to_samples(s, actual_bytes);
7bd7d905
HS
2944}
2945
dd379fa2
IA
2946static unsigned int load_ao_dma_buffer(struct comedi_device *dev,
2947 const struct comedi_cmd *cmd)
2948{
2949 struct pcidas64_private *devpriv = dev->private;
7bd7d905
HS
2950 struct comedi_subdevice *s = dev->write_subdev;
2951 unsigned int buffer_index = devpriv->ao_dma_index;
2952 unsigned int prev_buffer_index = prev_ao_dma_index(dev);
2953 unsigned int nsamples;
2954 unsigned int nbytes;
dd379fa2
IA
2955 unsigned int next_bits;
2956
7bd7d905
HS
2957 nsamples = cb_pcidas64_ao_fill_buffer(dev, s,
2958 devpriv->ao_buffer[buffer_index],
2959 DMA_BUFFER_SIZE);
2960 if (nsamples == 0)
dd379fa2
IA
2961 return 0;
2962
c39e050d 2963 nbytes = comedi_samples_to_bytes(s, nsamples);
7bd7d905 2964 devpriv->ao_dma_desc[buffer_index].transfer_size = cpu_to_le32(nbytes);
dd379fa2
IA
2965 /* set end of chain bit so we catch underruns */
2966 next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next);
dde90d89 2967 next_bits |= PLX_DMADPR_CHAINEND;
dd379fa2 2968 devpriv->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits);
85c12b82
AD
2969 /*
2970 * clear end of chain bit on previous buffer now that we have set it
2971 * for the last buffer
2972 */
dd379fa2 2973 next_bits = le32_to_cpu(devpriv->ao_dma_desc[prev_buffer_index].next);
dde90d89 2974 next_bits &= ~PLX_DMADPR_CHAINEND;
dd379fa2
IA
2975 devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits);
2976
2977 devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT;
dd379fa2 2978
7bd7d905 2979 return nbytes;
dd379fa2
IA
2980}
2981
2982static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
2983{
2984 struct pcidas64_private *devpriv = dev->private;
2985 unsigned int num_bytes;
2986 unsigned int next_transfer_addr;
c644a11a 2987 void __iomem *pci_addr_reg = devpriv->plx9080_iobase + PLX_REG_DMAPADR0;
dd379fa2
IA
2988 unsigned int buffer_index;
2989
2990 do {
2991 buffer_index = devpriv->ao_dma_index;
2992 /* don't overwrite data that hasn't been transferred yet */
2993 next_transfer_addr = readl(pci_addr_reg);
2994 if (next_transfer_addr >=
2995 devpriv->ao_buffer_bus_addr[buffer_index] &&
2996 next_transfer_addr <
2997 devpriv->ao_buffer_bus_addr[buffer_index] +
2998 DMA_BUFFER_SIZE)
2999 return;
3000 num_bytes = load_ao_dma_buffer(dev, cmd);
3001 } while (num_bytes >= DMA_BUFFER_SIZE);
3002}
3003
0a85b6f0
MT
3004static void handle_ao_interrupt(struct comedi_device *dev,
3005 unsigned short status, unsigned int plx_status)
88b12a9a 3006{
681d335a 3007 struct pcidas64_private *devpriv = dev->private;
34c43922 3008 struct comedi_subdevice *s = dev->write_subdev;
d163679c 3009 struct comedi_async *async;
ea6d0d4c 3010 struct comedi_cmd *cmd;
88b12a9a
FMH
3011 uint8_t dma0_status;
3012 unsigned long flags;
3013
3014 /* board might not support ao, in which case write_subdev is NULL */
854472c2 3015 if (!s)
88b12a9a
FMH
3016 return;
3017 async = s->async;
3018 cmd = &async->cmd;
3019
12f992ad 3020 /* spin lock makes sure no one else changes plx dma control reg */
5f74ea14 3021 spin_lock_irqsave(&dev->spinlock, flags);
c644a11a 3022 dma0_status = readb(devpriv->plx9080_iobase + PLX_REG_DMACSR0);
9dc53852 3023 if (plx_status & PLX_INTCSR_DMA0IA) { /* dma chan 0 interrupt */
3dcf1b55
IA
3024 if ((dma0_status & PLX_DMACSR_ENABLE) &&
3025 !(dma0_status & PLX_DMACSR_DONE)) {
3026 writeb(PLX_DMACSR_ENABLE | PLX_DMACSR_CLEARINTR,
c644a11a
IA
3027 devpriv->plx9080_iobase + PLX_REG_DMACSR0);
3028 } else {
3dcf1b55 3029 writeb(PLX_DMACSR_CLEARINTR,
c644a11a
IA
3030 devpriv->plx9080_iobase + PLX_REG_DMACSR0);
3031 }
5f74ea14 3032 spin_unlock_irqrestore(&dev->spinlock, flags);
3dcf1b55 3033 if (dma0_status & PLX_DMACSR_ENABLE) {
88b12a9a
FMH
3034 load_ao_dma(dev, cmd);
3035 /* try to recover from dma end-of-chain event */
3036 if (ao_dma_needs_restart(dev, dma0_status))
3037 restart_ao_dma(dev);
3038 }
46ca84c4 3039 } else {
5f74ea14 3040 spin_unlock_irqrestore(&dev->spinlock, flags);
46ca84c4 3041 }
88b12a9a
FMH
3042
3043 if ((status & DAC_DONE_BIT)) {
0be887b9
HS
3044 if ((cmd->stop_src == TRIG_COUNT &&
3045 async->scans_done >= cmd->stop_arg) ||
3046 last_ao_dma_load_completed(dev))
3047 async->events |= COMEDI_CB_EOA;
3048 else
88b12a9a 3049 async->events |= COMEDI_CB_ERROR;
88b12a9a 3050 }
62fc6407 3051 comedi_handle_events(dev, s);
88b12a9a
FMH
3052}
3053
70265d24 3054static irqreturn_t handle_interrupt(int irq, void *d)
88b12a9a 3055{
71b5f4f1 3056 struct comedi_device *dev = d;
681d335a 3057 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3058 unsigned short status;
3059 uint32_t plx_status;
3060 uint32_t plx_bits;
3061
c644a11a 3062 plx_status = readl(devpriv->plx9080_iobase + PLX_REG_INTCSR);
681d335a 3063 status = readw(devpriv->main_iobase + HW_STATUS_REG);
88b12a9a 3064
85c12b82
AD
3065 /*
3066 * an interrupt before all the postconfig stuff gets done could
88b12a9a 3067 * cause a NULL dereference if we continue through the
85c12b82
AD
3068 * interrupt handler
3069 */
220edb91 3070 if (!dev->attached)
88b12a9a 3071 return IRQ_HANDLED;
220edb91 3072
88b12a9a
FMH
3073 handle_ai_interrupt(dev, status, plx_status);
3074 handle_ao_interrupt(dev, status, plx_status);
3075
9dc53852
IA
3076 /* clear possible plx9080 interrupt sources */
3077 if (plx_status & PLX_INTCSR_LDBIA) {
3078 /* clear local doorbell interrupt */
c644a11a
IA
3079 plx_bits = readl(devpriv->plx9080_iobase + PLX_REG_L2PDBELL);
3080 writel(plx_bits, devpriv->plx9080_iobase + PLX_REG_L2PDBELL);
88b12a9a
FMH
3081 }
3082
88b12a9a
FMH
3083 return IRQ_HANDLED;
3084}
3085
da91b269 3086static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
88b12a9a 3087{
681d335a 3088 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3089 unsigned long flags;
3090
5f74ea14 3091 spin_lock_irqsave(&dev->spinlock, flags);
681d335a 3092 if (devpriv->ai_cmd_running == 0) {
5f74ea14 3093 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
3094 return 0;
3095 }
681d335a 3096 devpriv->ai_cmd_running = 0;
5f74ea14 3097 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
3098
3099 disable_ai_pacing(dev);
3100
3101 abort_dma(dev, 1);
3102
88b12a9a
FMH
3103 return 0;
3104}
3105
da91b269 3106static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3107 struct comedi_insn *insn, unsigned int *data)
88b12a9a 3108{
52762ad1 3109 const struct pcidas64_board *board = dev->board_ptr;
681d335a 3110 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3111 int chan = CR_CHAN(insn->chanspec);
3112 int range = CR_RANGE(insn->chanspec);
3113
12f992ad 3114 /* do some initializing */
681d335a 3115 writew(0, devpriv->main_iobase + DAC_CONTROL0_REG);
88b12a9a 3116
12f992ad 3117 /* set range */
681d335a
HS
3118 set_dac_range_bits(dev, &devpriv->dac_control1_bits, chan, range);
3119 writew(devpriv->dac_control1_bits,
3120 devpriv->main_iobase + DAC_CONTROL1_REG);
88b12a9a 3121
12f992ad 3122 /* write to channel */
52762ad1 3123 if (board->layout == LAYOUT_4020) {
88b12a9a 3124 writew(data[0] & 0xff,
681d335a 3125 devpriv->main_iobase + dac_lsb_4020_reg(chan));
88b12a9a 3126 writew((data[0] >> 8) & 0xf,
681d335a 3127 devpriv->main_iobase + dac_msb_4020_reg(chan));
88b12a9a 3128 } else {
681d335a 3129 writew(data[0], devpriv->main_iobase + dac_convert_reg(chan));
88b12a9a
FMH
3130 }
3131
12f992ad 3132 /* remember output value */
f88f75fe 3133 s->readback[chan] = data[0];
88b12a9a
FMH
3134
3135 return 1;
3136}
3137
0a85b6f0
MT
3138static void set_dac_control0_reg(struct comedi_device *dev,
3139 const struct comedi_cmd *cmd)
88b12a9a 3140{
681d335a 3141 struct pcidas64_private *devpriv = dev->private;
88b12a9a 3142 unsigned int bits = DAC_ENABLE_BIT | WAVEFORM_GATE_LEVEL_BIT |
46ca84c4 3143 WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT;
88b12a9a
FMH
3144
3145 if (cmd->start_src == TRIG_EXT) {
3146 bits |= WAVEFORM_TRIG_EXT_BITS;
3147 if (cmd->start_arg & CR_INVERT)
3148 bits |= WAVEFORM_TRIG_FALLING_BIT;
3149 } else {
3150 bits |= WAVEFORM_TRIG_SOFT_BITS;
3151 }
3152 if (cmd->scan_begin_src == TRIG_EXT) {
3153 bits |= DAC_EXT_UPDATE_ENABLE_BIT;
3154 if (cmd->scan_begin_arg & CR_INVERT)
3155 bits |= DAC_EXT_UPDATE_FALLING_BIT;
3156 }
681d335a 3157 writew(bits, devpriv->main_iobase + DAC_CONTROL0_REG);
88b12a9a
FMH
3158}
3159
0a85b6f0
MT
3160static void set_dac_control1_reg(struct comedi_device *dev,
3161 const struct comedi_cmd *cmd)
88b12a9a 3162{
681d335a 3163 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3164 int i;
3165
3166 for (i = 0; i < cmd->chanlist_len; i++) {
3167 int channel, range;
3168
3169 channel = CR_CHAN(cmd->chanlist[i]);
3170 range = CR_RANGE(cmd->chanlist[i]);
681d335a 3171 set_dac_range_bits(dev, &devpriv->dac_control1_bits, channel,
0a85b6f0 3172 range);
88b12a9a 3173 }
681d335a
HS
3174 devpriv->dac_control1_bits |= DAC_SW_GATE_BIT;
3175 writew(devpriv->dac_control1_bits,
3176 devpriv->main_iobase + DAC_CONTROL1_REG);
88b12a9a
FMH
3177}
3178
0a85b6f0
MT
3179static void set_dac_select_reg(struct comedi_device *dev,
3180 const struct comedi_cmd *cmd)
88b12a9a 3181{
681d335a 3182 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3183 uint16_t bits;
3184 unsigned int first_channel, last_channel;
3185
3186 first_channel = CR_CHAN(cmd->chanlist[0]);
3187 last_channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
3188 if (last_channel < first_channel)
e176d78c
HS
3189 dev_err(dev->class_dev,
3190 "bug! last ao channel < first ao channel\n");
88b12a9a
FMH
3191
3192 bits = (first_channel & 0x7) | (last_channel & 0x7) << 3;
3193
681d335a 3194 writew(bits, devpriv->main_iobase + DAC_SELECT_REG);
88b12a9a
FMH
3195}
3196
012e642c
IA
3197static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags)
3198{
3199 return get_divisor(ns, flags) - 2;
3200}
3201
0a85b6f0
MT
3202static void set_dac_interval_regs(struct comedi_device *dev,
3203 const struct comedi_cmd *cmd)
88b12a9a 3204{
681d335a 3205 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3206 unsigned int divisor;
3207
3208 if (cmd->scan_begin_src != TRIG_TIMER)
3209 return;
3210
3211 divisor = get_ao_divisor(cmd->scan_begin_arg, cmd->flags);
3212 if (divisor > max_counter_value) {
e176d78c 3213 dev_err(dev->class_dev, "bug! ao divisor too big\n");
88b12a9a
FMH
3214 divisor = max_counter_value;
3215 }
3216 writew(divisor & 0xffff,
681d335a 3217 devpriv->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG);
88b12a9a 3218 writew((divisor >> 16) & 0xff,
681d335a 3219 devpriv->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG);
88b12a9a
FMH
3220}
3221
da91b269 3222static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
88b12a9a 3223{
681d335a 3224 struct pcidas64_private *devpriv = dev->private;
7bd7d905
HS
3225 struct comedi_subdevice *s = dev->write_subdev;
3226 unsigned int nsamples;
3227 unsigned int nbytes;
88b12a9a
FMH
3228 int i;
3229
85c12b82
AD
3230 /*
3231 * clear queue pointer too, since external queue has
3232 * weird interactions with ao fifo
3233 */
681d335a
HS
3234 writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
3235 writew(0, devpriv->main_iobase + DAC_BUFFER_CLEAR_REG);
88b12a9a 3236
7bd7d905
HS
3237 nsamples = cb_pcidas64_ao_fill_buffer(dev, s,
3238 devpriv->ao_bounce_buffer,
3239 DAC_FIFO_SIZE);
3240 if (nsamples == 0)
3241 return -1;
3242
3243 for (i = 0; i < nsamples; i++) {
681d335a
HS
3244 writew(devpriv->ao_bounce_buffer[i],
3245 devpriv->main_iobase + DAC_FIFO_REG);
88b12a9a 3246 }
7bd7d905 3247
0be887b9
HS
3248 if (cmd->stop_src == TRIG_COUNT &&
3249 s->async->scans_done >= cmd->stop_arg)
88b12a9a 3250 return 0;
7bd7d905
HS
3251
3252 nbytes = load_ao_dma_buffer(dev, cmd);
3253 if (nbytes == 0)
88b12a9a 3254 return -1;
88b12a9a
FMH
3255 load_ao_dma(dev, cmd);
3256
3257 dma_start_sync(dev, 0);
3258
3259 return 0;
3260}
3261
f5f3a2c6
HS
3262static inline int external_ai_queue_in_use(struct comedi_device *dev,
3263 struct comedi_subdevice *s,
3264 struct comedi_cmd *cmd)
88b12a9a 3265{
52762ad1 3266 const struct pcidas64_board *board = dev->board_ptr;
b07244ce 3267
f5f3a2c6 3268 if (s->busy)
88b12a9a 3269 return 0;
52762ad1 3270 if (board->layout == LAYOUT_4020)
88b12a9a 3271 return 0;
f5f3a2c6 3272 else if (use_internal_queue_6xxx(cmd))
88b12a9a
FMH
3273 return 0;
3274 return 1;
3275}
3276
012e642c
IA
3277static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
3278 unsigned int trig_num)
3279{
3280 struct pcidas64_private *devpriv = dev->private;
3281 struct comedi_cmd *cmd = &s->async->cmd;
3282 int retval;
3283
020cb120 3284 if (trig_num != cmd->start_arg)
012e642c
IA
3285 return -EINVAL;
3286
3287 retval = prep_ao_dma(dev, cmd);
3288 if (retval < 0)
3289 return -EPIPE;
3290
3291 set_dac_control0_reg(dev, cmd);
3292
3293 if (cmd->start_src == TRIG_INT)
3294 writew(0, devpriv->main_iobase + DAC_START_REG);
3295
3296 s->async->inttrig = NULL;
3297
3298 return 0;
3299}
3300
da91b269 3301static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
88b12a9a 3302{
681d335a 3303 struct pcidas64_private *devpriv = dev->private;
ea6d0d4c 3304 struct comedi_cmd *cmd = &s->async->cmd;
88b12a9a 3305
f5f3a2c6 3306 if (external_ai_queue_in_use(dev, s, cmd)) {
88b12a9a
FMH
3307 warn_external_queue(dev);
3308 return -EBUSY;
3309 }
3310 /* disable analog output system during setup */
681d335a 3311 writew(0x0, devpriv->main_iobase + DAC_CONTROL0_REG);
88b12a9a 3312
681d335a 3313 devpriv->ao_dma_index = 0;
88b12a9a
FMH
3314
3315 set_dac_select_reg(dev, cmd);
3316 set_dac_interval_regs(dev, cmd);
681d335a 3317 load_first_dma_descriptor(dev, 0, devpriv->ao_dma_desc_bus_addr |
dde90d89 3318 PLX_DMADPR_DESCPCI | PLX_DMADPR_TCINTR);
88b12a9a
FMH
3319
3320 set_dac_control1_reg(dev, cmd);
3321 s->async->inttrig = ao_inttrig;
3322
3323 return 0;
3324}
3325
e300e4fb
HS
3326static int cb_pcidas64_ao_check_chanlist(struct comedi_device *dev,
3327 struct comedi_subdevice *s,
3328 struct comedi_cmd *cmd)
3329{
3330 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
3331 int i;
3332
3333 for (i = 1; i < cmd->chanlist_len; i++) {
3334 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
3335
3336 if (chan != (chan0 + i)) {
3337 dev_dbg(dev->class_dev,
3338 "chanlist must use consecutive channels\n");
3339 return -EINVAL;
3340 }
3341 }
3342
3343 return 0;
3344}
3345
da91b269 3346static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3347 struct comedi_cmd *cmd)
88b12a9a 3348{
52762ad1 3349 const struct pcidas64_board *board = dev->board_ptr;
88b12a9a 3350 int err = 0;
88b12a9a 3351 unsigned int tmp_arg;
88b12a9a 3352
27020ffe 3353 /* Step 1 : check if triggers are trivially valid */
88b12a9a 3354
571cea09
IA
3355 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT);
3356 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
3357 TRIG_TIMER | TRIG_EXT);
3358 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
3359 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
3360 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
88b12a9a
FMH
3361
3362 if (err)
3363 return 1;
3364
27020ffe 3365 /* Step 2a : make sure trigger sources are unique */
88b12a9a 3366
571cea09
IA
3367 err |= comedi_check_trigger_is_unique(cmd->start_src);
3368 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
27020ffe
HS
3369
3370 /* Step 2b : and mutually compatible */
88b12a9a 3371
88b12a9a 3372 if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
27020ffe 3373 err |= -EINVAL;
88b12a9a 3374 if (cmd->stop_src != TRIG_COUNT &&
0a85b6f0 3375 cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
27020ffe 3376 err |= -EINVAL;
88b12a9a
FMH
3377
3378 if (err)
3379 return 2;
3380
dba2939c 3381 /* Step 3: check if arguments are trivially valid */
88b12a9a 3382
571cea09 3383 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
020cb120 3384
88b12a9a 3385 if (cmd->scan_begin_src == TRIG_TIMER) {
571cea09 3386 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
52762ad1 3387 board->ao_scan_speed);
dba2939c
HS
3388 if (get_ao_divisor(cmd->scan_begin_arg, cmd->flags) >
3389 max_counter_value) {
46ca84c4
IA
3390 cmd->scan_begin_arg = (max_counter_value + 2) *
3391 TIMER_BASE;
dba2939c 3392 err |= -EINVAL;
88b12a9a
FMH
3393 }
3394 }
3395
571cea09
IA
3396 err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
3397 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
3398 cmd->chanlist_len);
88b12a9a
FMH
3399
3400 if (err)
3401 return 3;
3402
3403 /* step 4: fix up any arguments */
3404
3405 if (cmd->scan_begin_src == TRIG_TIMER) {
3406 tmp_arg = cmd->scan_begin_arg;
46ca84c4
IA
3407 cmd->scan_begin_arg = get_divisor(cmd->scan_begin_arg,
3408 cmd->flags) * TIMER_BASE;
88b12a9a
FMH
3409 if (tmp_arg != cmd->scan_begin_arg)
3410 err++;
3411 }
3412
3413 if (err)
3414 return 4;
3415
e300e4fb
HS
3416 /* Step 5: check channel list if it exists */
3417 if (cmd->chanlist && cmd->chanlist_len > 0)
3418 err |= cb_pcidas64_ao_check_chanlist(dev, s, cmd);
88b12a9a
FMH
3419
3420 if (err)
3421 return 5;
3422
3423 return 0;
3424}
3425
da91b269 3426static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
88b12a9a 3427{
681d335a
HS
3428 struct pcidas64_private *devpriv = dev->private;
3429
3430 writew(0x0, devpriv->main_iobase + DAC_CONTROL0_REG);
88b12a9a
FMH
3431 abort_dma(dev, 0);
3432 return 0;
3433}
3434
09d6dd74 3435static int dio_callback_4020(struct comedi_device *dev,
da261e1d 3436 int dir, int port, int data, unsigned long iobase)
88b12a9a 3437{
da261e1d 3438 struct pcidas64_private *devpriv = dev->private;
43358ed0 3439
88b12a9a 3440 if (dir) {
da261e1d 3441 writew(data, devpriv->main_iobase + iobase + 2 * port);
88b12a9a 3442 return 0;
88b12a9a 3443 }
da261e1d 3444 return readw(devpriv->main_iobase + iobase + 2 * port);
88b12a9a
FMH
3445}
3446
da91b269 3447static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3448 struct comedi_insn *insn, unsigned int *data)
88b12a9a 3449{
790c5541 3450 unsigned int bits;
88b12a9a 3451
9ebd1028 3452 bits = readb(dev->mmio + DI_REG);
88b12a9a
FMH
3453 bits &= 0xf;
3454 data[1] = bits;
3455 data[0] = 0;
3456
a2714e3e 3457 return insn->n;
88b12a9a
FMH
3458}
3459
97f4289a
HS
3460static int do_wbits(struct comedi_device *dev,
3461 struct comedi_subdevice *s,
3462 struct comedi_insn *insn,
3463 unsigned int *data)
88b12a9a 3464{
97f4289a 3465 if (comedi_dio_update_state(s, data))
9ebd1028 3466 writeb(s->state, dev->mmio + DO_REG);
88b12a9a
FMH
3467
3468 data[1] = s->state;
3469
a2714e3e 3470 return insn->n;
88b12a9a
FMH
3471}
3472
0a85b6f0
MT
3473static int dio_60xx_config_insn(struct comedi_device *dev,
3474 struct comedi_subdevice *s,
ddf62f2c
HS
3475 struct comedi_insn *insn,
3476 unsigned int *data)
88b12a9a 3477{
ddf62f2c 3478 int ret;
88b12a9a 3479
ddf62f2c
HS
3480 ret = comedi_dio_insn_config(dev, s, insn, data, 0);
3481 if (ret)
3482 return ret;
88b12a9a 3483
9ebd1028 3484 writeb(s->io_bits, dev->mmio + DIO_DIRECTION_60XX_REG);
88b12a9a 3485
ddf62f2c 3486 return insn->n;
88b12a9a
FMH
3487}
3488
97f4289a
HS
3489static int dio_60xx_wbits(struct comedi_device *dev,
3490 struct comedi_subdevice *s,
3491 struct comedi_insn *insn,
3492 unsigned int *data)
88b12a9a 3493{
9ebd1028
HS
3494 if (comedi_dio_update_state(s, data))
3495 writeb(s->state, dev->mmio + DIO_DATA_60XX_REG);
88b12a9a 3496
9ebd1028 3497 data[1] = readb(dev->mmio + DIO_DATA_60XX_REG);
88b12a9a 3498
a2714e3e 3499 return insn->n;
88b12a9a
FMH
3500}
3501
85c12b82
AD
3502/*
3503 * pci-6025 8800 caldac:
012e642c
IA
3504 * address 0 == dac channel 0 offset
3505 * address 1 == dac channel 0 gain
3506 * address 2 == dac channel 1 offset
3507 * address 3 == dac channel 1 gain
3508 * address 4 == fine adc offset
3509 * address 5 == coarse adc offset
3510 * address 6 == coarse adc gain
3511 * address 7 == fine adc gain
3512 */
85c12b82
AD
3513/*
3514 * pci-6402/16 uses all 8 channels for dac:
012e642c
IA
3515 * address 0 == dac channel 0 fine gain
3516 * address 1 == dac channel 0 coarse gain
3517 * address 2 == dac channel 0 coarse offset
3518 * address 3 == dac channel 1 coarse offset
3519 * address 4 == dac channel 1 fine gain
3520 * address 5 == dac channel 1 coarse gain
3521 * address 6 == dac channel 0 fine offset
3522 * address 7 == dac channel 1 fine offset
85c12b82 3523 */
012e642c
IA
3524
3525static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
3526 uint8_t value)
3527{
3528 struct pcidas64_private *devpriv = dev->private;
3529 static const int num_caldac_channels = 8;
3530 static const int bitstream_length = 11;
3531 unsigned int bitstream = ((address & 0x7) << 8) | value;
3532 unsigned int bit, register_bits;
3533 static const int caldac_8800_udelay = 1;
3534
3535 if (address >= num_caldac_channels) {
e176d78c 3536 dev_err(dev->class_dev, "illegal caldac channel\n");
012e642c
IA
3537 return -1;
3538 }
3539 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
3540 register_bits = 0;
3541 if (bitstream & bit)
3542 register_bits |= SERIAL_DATA_IN_BIT;
3543 udelay(caldac_8800_udelay);
3544 writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
3545 register_bits |= SERIAL_CLOCK_BIT;
3546 udelay(caldac_8800_udelay);
3547 writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
3548 }
3549 udelay(caldac_8800_udelay);
3550 writew(SELECT_8800_BIT, devpriv->main_iobase + CALIBRATION_REG);
3551 udelay(caldac_8800_udelay);
3552 writew(0, devpriv->main_iobase + CALIBRATION_REG);
3553 udelay(caldac_8800_udelay);
3554 return 0;
3555}
3556
3557/* 4020 caldacs */
3558static int caldac_i2c_write(struct comedi_device *dev,
3559 unsigned int caldac_channel, unsigned int value)
3560{
3561 uint8_t serial_bytes[3];
3562 uint8_t i2c_addr;
3563 enum pointer_bits {
12f992ad 3564 /* manual has gain and offset bits switched */
012e642c
IA
3565 OFFSET_0_2 = 0x1,
3566 GAIN_0_2 = 0x2,
3567 OFFSET_1_3 = 0x4,
3568 GAIN_1_3 = 0x8,
3569 };
3570 enum data_bits {
3571 NOT_CLEAR_REGISTERS = 0x20,
3572 };
3573
3574 switch (caldac_channel) {
12f992ad 3575 case 0: /* chan 0 offset */
012e642c
IA
3576 i2c_addr = CALDAC0_I2C_ADDR;
3577 serial_bytes[0] = OFFSET_0_2;
3578 break;
12f992ad 3579 case 1: /* chan 1 offset */
012e642c
IA
3580 i2c_addr = CALDAC0_I2C_ADDR;
3581 serial_bytes[0] = OFFSET_1_3;
3582 break;
12f992ad 3583 case 2: /* chan 2 offset */
012e642c
IA
3584 i2c_addr = CALDAC1_I2C_ADDR;
3585 serial_bytes[0] = OFFSET_0_2;
3586 break;
12f992ad 3587 case 3: /* chan 3 offset */
012e642c
IA
3588 i2c_addr = CALDAC1_I2C_ADDR;
3589 serial_bytes[0] = OFFSET_1_3;
3590 break;
12f992ad 3591 case 4: /* chan 0 gain */
012e642c
IA
3592 i2c_addr = CALDAC0_I2C_ADDR;
3593 serial_bytes[0] = GAIN_0_2;
3594 break;
12f992ad 3595 case 5: /* chan 1 gain */
012e642c
IA
3596 i2c_addr = CALDAC0_I2C_ADDR;
3597 serial_bytes[0] = GAIN_1_3;
3598 break;
12f992ad 3599 case 6: /* chan 2 gain */
012e642c
IA
3600 i2c_addr = CALDAC1_I2C_ADDR;
3601 serial_bytes[0] = GAIN_0_2;
3602 break;
12f992ad 3603 case 7: /* chan 3 gain */
012e642c
IA
3604 i2c_addr = CALDAC1_I2C_ADDR;
3605 serial_bytes[0] = GAIN_1_3;
3606 break;
3607 default:
e176d78c 3608 dev_err(dev->class_dev, "invalid caldac channel\n");
012e642c 3609 return -1;
012e642c
IA
3610 }
3611 serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf);
3612 serial_bytes[2] = value & 0xff;
3613 i2c_write(dev, i2c_addr, serial_bytes, 3);
3614 return 0;
3615}
3616
da91b269 3617static void caldac_write(struct comedi_device *dev, unsigned int channel,
0a85b6f0 3618 unsigned int value)
88b12a9a 3619{
52762ad1 3620 const struct pcidas64_board *board = dev->board_ptr;
88b12a9a 3621
52762ad1 3622 switch (board->layout) {
88b12a9a
FMH
3623 case LAYOUT_60XX:
3624 case LAYOUT_64XX:
3625 caldac_8800_write(dev, channel, value);
3626 break;
3627 case LAYOUT_4020:
3628 caldac_i2c_write(dev, channel, value);
3629 break;
3630 default:
3631 break;
3632 }
3633}
3634
5e2de5e7
HS
3635static int cb_pcidas64_calib_insn_write(struct comedi_device *dev,
3636 struct comedi_subdevice *s,
3637 struct comedi_insn *insn,
3638 unsigned int *data)
88b12a9a 3639{
5e2de5e7 3640 unsigned int chan = CR_CHAN(insn->chanspec);
88b12a9a 3641
5e2de5e7
HS
3642 /*
3643 * Programming the calib device is slow. Only write the
3644 * last data value if the value has changed.
3645 */
3646 if (insn->n) {
3647 unsigned int val = data[insn->n - 1];
88b12a9a 3648
5e2de5e7
HS
3649 if (s->readback[chan] != val) {
3650 caldac_write(dev, chan, val);
3651 s->readback[chan] = val;
3652 }
3653 }
88b12a9a 3654
5e2de5e7 3655 return insn->n;
88b12a9a
FMH
3656}
3657
da91b269 3658static void ad8402_write(struct comedi_device *dev, unsigned int channel,
0a85b6f0 3659 unsigned int value)
88b12a9a 3660{
681d335a 3661 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3662 static const int bitstream_length = 10;
3663 unsigned int bit, register_bits;
3664 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
5f74ea14 3665 static const int ad8402_udelay = 1;
88b12a9a 3666
88b12a9a 3667 register_bits = SELECT_8402_64XX_BIT;
5f74ea14 3668 udelay(ad8402_udelay);
681d335a 3669 writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
88b12a9a
FMH
3670
3671 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
3672 if (bitstream & bit)
3673 register_bits |= SERIAL_DATA_IN_BIT;
3674 else
3675 register_bits &= ~SERIAL_DATA_IN_BIT;
5f74ea14 3676 udelay(ad8402_udelay);
681d335a 3677 writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
5f74ea14 3678 udelay(ad8402_udelay);
88b12a9a 3679 writew(register_bits | SERIAL_CLOCK_BIT,
681d335a 3680 devpriv->main_iobase + CALIBRATION_REG);
88b12a9a
FMH
3681 }
3682
5f74ea14 3683 udelay(ad8402_udelay);
681d335a 3684 writew(0, devpriv->main_iobase + CALIBRATION_REG);
88b12a9a
FMH
3685}
3686
3687/* for pci-das6402/16, channel 0 is analog input gain and channel 1 is offset */
dc658fdc
HS
3688static int cb_pcidas64_ad8402_insn_write(struct comedi_device *dev,
3689 struct comedi_subdevice *s,
3690 struct comedi_insn *insn,
3691 unsigned int *data)
88b12a9a 3692{
dc658fdc 3693 unsigned int chan = CR_CHAN(insn->chanspec);
88b12a9a 3694
dc658fdc
HS
3695 /*
3696 * Programming the calib device is slow. Only write the
3697 * last data value if the value has changed.
3698 */
3699 if (insn->n) {
3700 unsigned int val = data[insn->n - 1];
88b12a9a 3701
dc658fdc
HS
3702 if (s->readback[chan] != val) {
3703 ad8402_write(dev, chan, val);
3704 s->readback[chan] = val;
3705 }
3706 }
88b12a9a 3707
dc658fdc 3708 return insn->n;
88b12a9a
FMH
3709}
3710
da91b269 3711static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address)
88b12a9a 3712{
681d335a 3713 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3714 static const int bitstream_length = 11;
3715 static const int read_command = 0x6;
3716 unsigned int bitstream = (read_command << 8) | address;
3717 unsigned int bit;
f31d0008 3718 void __iomem * const plx_control_addr =
c644a11a 3719 devpriv->plx9080_iobase + PLX_REG_CNTRL;
88b12a9a
FMH
3720 uint16_t value;
3721 static const int value_length = 16;
5f74ea14 3722 static const int eeprom_udelay = 1;
88b12a9a 3723
5f74ea14 3724 udelay(eeprom_udelay);
a3228bc8 3725 devpriv->plx_control_bits &= ~PLX_CNTRL_EESK & ~PLX_CNTRL_EECS;
12f992ad 3726 /* make sure we don't send anything to the i2c bus on 4020 */
a3228bc8 3727 devpriv->plx_control_bits |= PLX_CNTRL_USERO;
681d335a 3728 writel(devpriv->plx_control_bits, plx_control_addr);
12f992ad 3729 /* activate serial eeprom */
5f74ea14 3730 udelay(eeprom_udelay);
a3228bc8 3731 devpriv->plx_control_bits |= PLX_CNTRL_EECS;
681d335a 3732 writel(devpriv->plx_control_bits, plx_control_addr);
88b12a9a 3733
12f992ad 3734 /* write read command and desired memory address */
88b12a9a 3735 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
12f992ad 3736 /* set bit to be written */
5f74ea14 3737 udelay(eeprom_udelay);
88b12a9a 3738 if (bitstream & bit)
a3228bc8 3739 devpriv->plx_control_bits |= PLX_CNTRL_EEWB;
88b12a9a 3740 else
a3228bc8 3741 devpriv->plx_control_bits &= ~PLX_CNTRL_EEWB;
681d335a 3742 writel(devpriv->plx_control_bits, plx_control_addr);
12f992ad 3743 /* clock in bit */
5f74ea14 3744 udelay(eeprom_udelay);
a3228bc8 3745 devpriv->plx_control_bits |= PLX_CNTRL_EESK;
681d335a 3746 writel(devpriv->plx_control_bits, plx_control_addr);
5f74ea14 3747 udelay(eeprom_udelay);
a3228bc8 3748 devpriv->plx_control_bits &= ~PLX_CNTRL_EESK;
681d335a 3749 writel(devpriv->plx_control_bits, plx_control_addr);
88b12a9a 3750 }
12f992ad 3751 /* read back value from eeprom memory location */
88b12a9a
FMH
3752 value = 0;
3753 for (bit = 1 << (value_length - 1); bit; bit >>= 1) {
12f992ad 3754 /* clock out bit */
5f74ea14 3755 udelay(eeprom_udelay);
a3228bc8 3756 devpriv->plx_control_bits |= PLX_CNTRL_EESK;
681d335a 3757 writel(devpriv->plx_control_bits, plx_control_addr);
5f74ea14 3758 udelay(eeprom_udelay);
a3228bc8 3759 devpriv->plx_control_bits &= ~PLX_CNTRL_EESK;
681d335a 3760 writel(devpriv->plx_control_bits, plx_control_addr);
5f74ea14 3761 udelay(eeprom_udelay);
a3228bc8 3762 if (readl(plx_control_addr) & PLX_CNTRL_EERB)
88b12a9a
FMH
3763 value |= bit;
3764 }
3765
12f992ad 3766 /* deactivate eeprom serial input */
5f74ea14 3767 udelay(eeprom_udelay);
a3228bc8 3768 devpriv->plx_control_bits &= ~PLX_CNTRL_EECS;
681d335a 3769 writel(devpriv->plx_control_bits, plx_control_addr);
88b12a9a
FMH
3770
3771 return value;
3772}
3773
0a85b6f0
MT
3774static int eeprom_read_insn(struct comedi_device *dev,
3775 struct comedi_subdevice *s,
3776 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
3777{
3778 data[0] = read_eeprom(dev, CR_CHAN(insn->chanspec));
3779
3780 return 1;
3781}
3782
12f992ad 3783/* Allocate and initialize the subdevice structures. */
9c7a00f5
IA
3784static int setup_subdevices(struct comedi_device *dev)
3785{
52762ad1 3786 const struct pcidas64_board *board = dev->board_ptr;
9c7a00f5
IA
3787 struct pcidas64_private *devpriv = dev->private;
3788 struct comedi_subdevice *s;
9c7a00f5
IA
3789 int i;
3790 int ret;
3791
3792 ret = comedi_alloc_subdevices(dev, 10);
3793 if (ret)
3794 return ret;
3795
3796 s = &dev->subdevices[0];
3797 /* analog input subdevice */
3798 dev->read_subdev = s;
3799 s->type = COMEDI_SUBD_AI;
3800 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ;
52762ad1 3801 if (board->layout == LAYOUT_60XX)
9c7a00f5 3802 s->subdev_flags |= SDF_COMMON | SDF_DIFF;
52762ad1 3803 else if (board->layout == LAYOUT_64XX)
9c7a00f5
IA
3804 s->subdev_flags |= SDF_DIFF;
3805 /* XXX Number of inputs in differential mode is ignored */
52762ad1 3806 s->n_chan = board->ai_se_chans;
9c7a00f5 3807 s->len_chanlist = 0x2000;
52762ad1
HS
3808 s->maxdata = (1 << board->ai_bits) - 1;
3809 s->range_table = board->ai_range_table;
9c7a00f5
IA
3810 s->insn_read = ai_rinsn;
3811 s->insn_config = ai_config_insn;
3812 s->do_cmd = ai_cmd;
3813 s->do_cmdtest = ai_cmdtest;
3814 s->cancel = ai_cancel;
52762ad1 3815 if (board->layout == LAYOUT_4020) {
9c7a00f5 3816 uint8_t data;
85c12b82
AD
3817 /*
3818 * set adc to read from inputs
3819 * (not internal calibration sources)
3820 */
9c7a00f5 3821 devpriv->i2c_cal_range_bits = adc_src_4020_bits(4);
12f992ad 3822 /* set channels to +-5 volt input ranges */
9c7a00f5
IA
3823 for (i = 0; i < s->n_chan; i++)
3824 devpriv->i2c_cal_range_bits |= attenuate_bit(i);
3825 data = devpriv->i2c_cal_range_bits;
3826 i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data));
3827 }
3828
3829 /* analog output subdevice */
3830 s = &dev->subdevices[1];
52762ad1 3831 if (board->ao_nchan) {
9c7a00f5
IA
3832 s->type = COMEDI_SUBD_AO;
3833 s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
3834 SDF_GROUND | SDF_CMD_WRITE;
52762ad1
HS
3835 s->n_chan = board->ao_nchan;
3836 s->maxdata = (1 << board->ao_bits) - 1;
3837 s->range_table = board->ao_range_table;
9c7a00f5 3838 s->insn_write = ao_winsn;
f88f75fe
HS
3839
3840 ret = comedi_alloc_subdev_readback(s);
3841 if (ret)
3842 return ret;
3843
52762ad1 3844 if (ao_cmd_is_supported(board)) {
9c7a00f5
IA
3845 dev->write_subdev = s;
3846 s->do_cmdtest = ao_cmdtest;
3847 s->do_cmd = ao_cmd;
52762ad1 3848 s->len_chanlist = board->ao_nchan;
9c7a00f5
IA
3849 s->cancel = ao_cancel;
3850 }
3851 } else {
3852 s->type = COMEDI_SUBD_UNUSED;
3853 }
3854
12f992ad 3855 /* digital input */
9c7a00f5 3856 s = &dev->subdevices[2];
52762ad1 3857 if (board->layout == LAYOUT_64XX) {
9c7a00f5
IA
3858 s->type = COMEDI_SUBD_DI;
3859 s->subdev_flags = SDF_READABLE;
3860 s->n_chan = 4;
3861 s->maxdata = 1;
3862 s->range_table = &range_digital;
3863 s->insn_bits = di_rbits;
6ac986d0 3864 } else {
9c7a00f5 3865 s->type = COMEDI_SUBD_UNUSED;
6ac986d0 3866 }
9c7a00f5 3867
12f992ad 3868 /* digital output */
52762ad1 3869 if (board->layout == LAYOUT_64XX) {
9c7a00f5
IA
3870 s = &dev->subdevices[3];
3871 s->type = COMEDI_SUBD_DO;
453fd2b3 3872 s->subdev_flags = SDF_WRITABLE;
9c7a00f5
IA
3873 s->n_chan = 4;
3874 s->maxdata = 1;
3875 s->range_table = &range_digital;
3876 s->insn_bits = do_wbits;
6ac986d0 3877 } else {
9c7a00f5 3878 s->type = COMEDI_SUBD_UNUSED;
6ac986d0 3879 }
9c7a00f5
IA
3880
3881 /* 8255 */
3882 s = &dev->subdevices[4];
52762ad1
HS
3883 if (board->has_8255) {
3884 if (board->layout == LAYOUT_4020) {
e6439a45 3885 ret = subdev_8255_init(dev, s, dio_callback_4020,
da261e1d 3886 I8255_4020_REG);
9c7a00f5 3887 } else {
5c19084b
HS
3888 ret = subdev_8255_mm_init(dev, s, NULL,
3889 DIO_8255_OFFSET);
9c7a00f5 3890 }
e6439a45
HS
3891 if (ret)
3892 return ret;
3893 } else {
9c7a00f5 3894 s->type = COMEDI_SUBD_UNUSED;
e6439a45 3895 }
9c7a00f5 3896
12f992ad 3897 /* 8 channel dio for 60xx */
9c7a00f5 3898 s = &dev->subdevices[5];
52762ad1 3899 if (board->layout == LAYOUT_60XX) {
9c7a00f5
IA
3900 s->type = COMEDI_SUBD_DIO;
3901 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
3902 s->n_chan = 8;
3903 s->maxdata = 1;
3904 s->range_table = &range_digital;
3905 s->insn_config = dio_60xx_config_insn;
3906 s->insn_bits = dio_60xx_wbits;
6ac986d0 3907 } else {
9c7a00f5 3908 s->type = COMEDI_SUBD_UNUSED;
6ac986d0 3909 }
9c7a00f5 3910
12f992ad 3911 /* caldac */
9c7a00f5
IA
3912 s = &dev->subdevices[6];
3913 s->type = COMEDI_SUBD_CALIB;
3914 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
3915 s->n_chan = 8;
52762ad1 3916 if (board->layout == LAYOUT_4020)
9c7a00f5
IA
3917 s->maxdata = 0xfff;
3918 else
3919 s->maxdata = 0xff;
5e2de5e7 3920 s->insn_write = cb_pcidas64_calib_insn_write;
37318bdb
HS
3921
3922 ret = comedi_alloc_subdev_readback(s);
3923 if (ret)
3924 return ret;
3925
3926 for (i = 0; i < s->n_chan; i++) {
9c7a00f5 3927 caldac_write(dev, i, s->maxdata / 2);
37318bdb
HS
3928 s->readback[i] = s->maxdata / 2;
3929 }
9c7a00f5 3930
12f992ad 3931 /* 2 channel ad8402 potentiometer */
9c7a00f5 3932 s = &dev->subdevices[7];
52762ad1 3933 if (board->layout == LAYOUT_64XX) {
9c7a00f5
IA
3934 s->type = COMEDI_SUBD_CALIB;
3935 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
3936 s->n_chan = 2;
9c7a00f5 3937 s->maxdata = 0xff;
dc658fdc 3938 s->insn_write = cb_pcidas64_ad8402_insn_write;
fe1184e4
HS
3939
3940 ret = comedi_alloc_subdev_readback(s);
3941 if (ret)
3942 return ret;
3943
3944 for (i = 0; i < s->n_chan; i++) {
9c7a00f5 3945 ad8402_write(dev, i, s->maxdata / 2);
fe1184e4
HS
3946 s->readback[i] = s->maxdata / 2;
3947 }
6ac986d0 3948 } else {
9c7a00f5 3949 s->type = COMEDI_SUBD_UNUSED;
6ac986d0 3950 }
9c7a00f5
IA
3951
3952 /* serial EEPROM, if present */
3953 s = &dev->subdevices[8];
a3228bc8
IA
3954 if (readl(devpriv->plx9080_iobase + PLX_REG_CNTRL) &
3955 PLX_CNTRL_EEPRESENT) {
9c7a00f5
IA
3956 s->type = COMEDI_SUBD_MEMORY;
3957 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
3958 s->n_chan = 128;
3959 s->maxdata = 0xffff;
3960 s->insn_read = eeprom_read_insn;
6ac986d0 3961 } else {
9c7a00f5 3962 s->type = COMEDI_SUBD_UNUSED;
6ac986d0 3963 }
9c7a00f5 3964
12f992ad 3965 /* user counter subd XXX */
9c7a00f5
IA
3966 s = &dev->subdevices[9];
3967 s->type = COMEDI_SUBD_UNUSED;
3968
3969 return 0;
3970}
3971
a690b7e5 3972static int auto_attach(struct comedi_device *dev,
463740d4 3973 unsigned long context)
a299d881 3974{
a299d881 3975 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
52762ad1 3976 const struct pcidas64_board *board = NULL;
463740d4 3977 struct pcidas64_private *devpriv;
a299d881
IA
3978 uint32_t local_range, local_decode;
3979 int retval;
3980
463740d4 3981 if (context < ARRAY_SIZE(pcidas64_boards))
52762ad1
HS
3982 board = &pcidas64_boards[context];
3983 if (!board)
463740d4 3984 return -ENODEV;
52762ad1 3985 dev->board_ptr = board;
a299d881 3986
0bdab509 3987 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
a299d881
IA
3988 if (!devpriv)
3989 return -ENOMEM;
a299d881 3990
818f569f
HS
3991 retval = comedi_pci_enable(dev);
3992 if (retval)
3993 return retval;
a299d881
IA
3994 pci_set_master(pcidev);
3995
3996 /* Initialize dev->board_name */
52762ad1 3997 dev->board_name = board->name;
a299d881 3998
81d985a1
HS
3999 devpriv->main_phys_iobase = pci_resource_start(pcidev, 2);
4000 devpriv->dio_counter_phys_iobase = pci_resource_start(pcidev, 3);
a299d881 4001
c71b2e52
HS
4002 devpriv->plx9080_iobase = pci_ioremap_bar(pcidev, 0);
4003 devpriv->main_iobase = pci_ioremap_bar(pcidev, 2);
9ebd1028 4004 dev->mmio = pci_ioremap_bar(pcidev, 3);
a299d881 4005
9ebd1028 4006 if (!devpriv->plx9080_iobase || !devpriv->main_iobase || !dev->mmio) {
a299d881
IA
4007 dev_warn(dev->class_dev, "failed to remap io memory\n");
4008 return -ENOMEM;
4009 }
4010
12f992ad 4011 /* figure out what local addresses are */
c644a11a 4012 local_range = readl(devpriv->plx9080_iobase + PLX_REG_LAS0RR) &
be13e14e 4013 PLX_LASRR_MEM_MASK;
c644a11a 4014 local_decode = readl(devpriv->plx9080_iobase + PLX_REG_LAS0BA) &
5eaa593d 4015 local_range & PLX_LASBA_MEM_MASK;
a299d881
IA
4016 devpriv->local0_iobase = ((uint32_t)devpriv->main_phys_iobase &
4017 ~local_range) | local_decode;
c644a11a 4018 local_range = readl(devpriv->plx9080_iobase + PLX_REG_LAS1RR) &
be13e14e 4019 PLX_LASRR_MEM_MASK;
c644a11a 4020 local_decode = readl(devpriv->plx9080_iobase + PLX_REG_LAS1BA) &
5eaa593d 4021 local_range & PLX_LASBA_MEM_MASK;
a299d881
IA
4022 devpriv->local1_iobase = ((uint32_t)devpriv->dio_counter_phys_iobase &
4023 ~local_range) | local_decode;
4024
a299d881
IA
4025 retval = alloc_and_init_dma_members(dev);
4026 if (retval < 0)
4027 return retval;
4028
4029 devpriv->hw_revision =
4030 hw_revision(dev, readw(devpriv->main_iobase + HW_STATUS_REG));
4031 dev_dbg(dev->class_dev, "stc hardware revision %i\n",
4032 devpriv->hw_revision);
4033 init_plx9080(dev);
4034 init_stc_registers(dev);
71e06874
HS
4035
4036 retval = request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
4037 dev->board_name, dev);
4038 if (retval) {
a299d881
IA
4039 dev_dbg(dev->class_dev, "unable to allocate irq %u\n",
4040 pcidev->irq);
71e06874 4041 return retval;
a299d881
IA
4042 }
4043 dev->irq = pcidev->irq;
4044 dev_dbg(dev->class_dev, "irq %u\n", dev->irq);
4045
4046 retval = setup_subdevices(dev);
4047 if (retval < 0)
4048 return retval;
4049
4050 return 0;
4051}
4052
4053static void detach(struct comedi_device *dev)
4054{
a299d881 4055 struct pcidas64_private *devpriv = dev->private;
a299d881
IA
4056
4057 if (dev->irq)
4058 free_irq(dev->irq, dev);
4059 if (devpriv) {
f9804323
HS
4060 if (devpriv->plx9080_iobase) {
4061 disable_plx_interrupts(dev);
4062 iounmap(devpriv->plx9080_iobase);
a299d881 4063 }
f9804323
HS
4064 if (devpriv->main_iobase)
4065 iounmap(devpriv->main_iobase);
4066 if (dev->mmio)
4067 iounmap(dev->mmio);
a299d881 4068 }
7f072f54 4069 comedi_pci_disable(dev);
f9804323 4070 cb_pcidas64_free_dma(dev);
a299d881
IA
4071}
4072
bdc7cc50
HS
4073static struct comedi_driver cb_pcidas64_driver = {
4074 .driver_name = "cb_pcidas64",
4075 .module = THIS_MODULE,
b91524ee 4076 .auto_attach = auto_attach,
bdc7cc50
HS
4077 .detach = detach,
4078};
4079
a690b7e5 4080static int cb_pcidas64_pci_probe(struct pci_dev *dev,
b8f4ac23 4081 const struct pci_device_id *id)
bdc7cc50 4082{
b8f4ac23
HS
4083 return comedi_pci_auto_config(dev, &cb_pcidas64_driver,
4084 id->driver_data);
bdc7cc50
HS
4085}
4086
41e043fc 4087static const struct pci_device_id cb_pcidas64_pci_table[] = {
463740d4
HS
4088 { PCI_VDEVICE(CB, 0x001d), BOARD_PCIDAS6402_16 },
4089 { PCI_VDEVICE(CB, 0x001e), BOARD_PCIDAS6402_12 },
4090 { PCI_VDEVICE(CB, 0x0035), BOARD_PCIDAS64_M1_16 },
4091 { PCI_VDEVICE(CB, 0x0036), BOARD_PCIDAS64_M2_16 },
4092 { PCI_VDEVICE(CB, 0x0037), BOARD_PCIDAS64_M3_16 },
4093 { PCI_VDEVICE(CB, 0x0052), BOARD_PCIDAS4020_12 },
4094 { PCI_VDEVICE(CB, 0x005d), BOARD_PCIDAS6023 },
4095 { PCI_VDEVICE(CB, 0x005e), BOARD_PCIDAS6025 },
4096 { PCI_VDEVICE(CB, 0x005f), BOARD_PCIDAS6030 },
4097 { PCI_VDEVICE(CB, 0x0060), BOARD_PCIDAS6031 },
4098 { PCI_VDEVICE(CB, 0x0061), BOARD_PCIDAS6032 },
4099 { PCI_VDEVICE(CB, 0x0062), BOARD_PCIDAS6033 },
4100 { PCI_VDEVICE(CB, 0x0063), BOARD_PCIDAS6034 },
4101 { PCI_VDEVICE(CB, 0x0064), BOARD_PCIDAS6035 },
4102 { PCI_VDEVICE(CB, 0x0065), BOARD_PCIDAS6040 },
4103 { PCI_VDEVICE(CB, 0x0066), BOARD_PCIDAS6052 },
4104 { PCI_VDEVICE(CB, 0x0067), BOARD_PCIDAS6070 },
4105 { PCI_VDEVICE(CB, 0x0068), BOARD_PCIDAS6071 },
4106 { PCI_VDEVICE(CB, 0x006f), BOARD_PCIDAS6036 },
4107 { PCI_VDEVICE(CB, 0x0078), BOARD_PCIDAS6013 },
4108 { PCI_VDEVICE(CB, 0x0079), BOARD_PCIDAS6014 },
bdc7cc50
HS
4109 { 0 }
4110};
4111MODULE_DEVICE_TABLE(pci, cb_pcidas64_pci_table);
4112
4113static struct pci_driver cb_pcidas64_pci_driver = {
4114 .name = "cb_pcidas64",
4115 .id_table = cb_pcidas64_pci_table,
4116 .probe = cb_pcidas64_pci_probe,
9901a4d7 4117 .remove = comedi_pci_auto_unconfig,
bdc7cc50
HS
4118};
4119module_comedi_pci_driver(cb_pcidas64_driver, cb_pcidas64_pci_driver);
4120
90f703d3
AT
4121MODULE_AUTHOR("Comedi http://www.comedi.org");
4122MODULE_DESCRIPTION("Comedi low-level driver");
4123MODULE_LICENSE("GPL");
This page took 1.393616 seconds and 5 git commands to generate.