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