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