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