1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * me4000.c
4 * Source code for the Meilhaus ME-4000 board family.
5 *
6 * COMEDI - Linux Control and Measurement Device Interface
7 * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
8 */
9
10/*
11 * Driver: me4000
12 * Description: Meilhaus ME-4000 series boards
13 * Devices: [Meilhaus] ME-4650 (me4000), ME-4670i, ME-4680, ME-4680i,
14 *	    ME-4680is
15 * Author: gg (Guenter Gebhardt <g.gebhardt@meilhaus.com>)
16 * Updated: Mon, 18 Mar 2002 15:34:01 -0800
17 * Status: untested
18 *
19 * Supports:
20 *	- Analog Input
21 *	- Analog Output
22 *	- Digital I/O
23 *	- Counter
24 *
25 * Configuration Options: not applicable, uses PCI auto config
26 *
27 * The firmware required by these boards is available in the
28 * comedi_nonfree_firmware tarball available from
29 * https://www.comedi.org.
30 */
31
32#include <linux/module.h>
33#include <linux/delay.h>
34#include <linux/interrupt.h>
35#include <linux/comedi/comedi_pci.h>
36#include <linux/comedi/comedi_8254.h>
37
38#include "plx9052.h"
39
40#define ME4000_FIRMWARE		"me4000_firmware.bin"
41
42/*
43 * ME4000 Register map and bit defines
44 */
45#define ME4000_AO_CHAN(x)			((x) * 0x18)
46
47#define ME4000_AO_CTRL_REG(x)			(0x00 + ME4000_AO_CHAN(x))
48#define ME4000_AO_CTRL_MODE_0			BIT(0)
49#define ME4000_AO_CTRL_MODE_1			BIT(1)
50#define ME4000_AO_CTRL_STOP			BIT(2)
51#define ME4000_AO_CTRL_ENABLE_FIFO		BIT(3)
52#define ME4000_AO_CTRL_ENABLE_EX_TRIG		BIT(4)
53#define ME4000_AO_CTRL_EX_TRIG_EDGE		BIT(5)
54#define ME4000_AO_CTRL_IMMEDIATE_STOP		BIT(7)
55#define ME4000_AO_CTRL_ENABLE_DO		BIT(8)
56#define ME4000_AO_CTRL_ENABLE_IRQ		BIT(9)
57#define ME4000_AO_CTRL_RESET_IRQ		BIT(10)
58#define ME4000_AO_STATUS_REG(x)			(0x04 + ME4000_AO_CHAN(x))
59#define ME4000_AO_STATUS_FSM			BIT(0)
60#define ME4000_AO_STATUS_FF			BIT(1)
61#define ME4000_AO_STATUS_HF			BIT(2)
62#define ME4000_AO_STATUS_EF			BIT(3)
63#define ME4000_AO_FIFO_REG(x)			(0x08 + ME4000_AO_CHAN(x))
64#define ME4000_AO_SINGLE_REG(x)			(0x0c + ME4000_AO_CHAN(x))
65#define ME4000_AO_TIMER_REG(x)			(0x10 + ME4000_AO_CHAN(x))
66#define ME4000_AI_CTRL_REG			0x74
67#define ME4000_AI_STATUS_REG			0x74
68#define ME4000_AI_CTRL_MODE_0			BIT(0)
69#define ME4000_AI_CTRL_MODE_1			BIT(1)
70#define ME4000_AI_CTRL_MODE_2			BIT(2)
71#define ME4000_AI_CTRL_SAMPLE_HOLD		BIT(3)
72#define ME4000_AI_CTRL_IMMEDIATE_STOP		BIT(4)
73#define ME4000_AI_CTRL_STOP			BIT(5)
74#define ME4000_AI_CTRL_CHANNEL_FIFO		BIT(6)
75#define ME4000_AI_CTRL_DATA_FIFO		BIT(7)
76#define ME4000_AI_CTRL_FULLSCALE		BIT(8)
77#define ME4000_AI_CTRL_OFFSET			BIT(9)
78#define ME4000_AI_CTRL_EX_TRIG_ANALOG		BIT(10)
79#define ME4000_AI_CTRL_EX_TRIG			BIT(11)
80#define ME4000_AI_CTRL_EX_TRIG_FALLING		BIT(12)
81#define ME4000_AI_CTRL_EX_IRQ			BIT(13)
82#define ME4000_AI_CTRL_EX_IRQ_RESET		BIT(14)
83#define ME4000_AI_CTRL_LE_IRQ			BIT(15)
84#define ME4000_AI_CTRL_LE_IRQ_RESET		BIT(16)
85#define ME4000_AI_CTRL_HF_IRQ			BIT(17)
86#define ME4000_AI_CTRL_HF_IRQ_RESET		BIT(18)
87#define ME4000_AI_CTRL_SC_IRQ			BIT(19)
88#define ME4000_AI_CTRL_SC_IRQ_RESET		BIT(20)
89#define ME4000_AI_CTRL_SC_RELOAD		BIT(21)
90#define ME4000_AI_STATUS_EF_CHANNEL		BIT(22)
91#define ME4000_AI_STATUS_HF_CHANNEL		BIT(23)
92#define ME4000_AI_STATUS_FF_CHANNEL		BIT(24)
93#define ME4000_AI_STATUS_EF_DATA		BIT(25)
94#define ME4000_AI_STATUS_HF_DATA		BIT(26)
95#define ME4000_AI_STATUS_FF_DATA		BIT(27)
96#define ME4000_AI_STATUS_LE			BIT(28)
97#define ME4000_AI_STATUS_FSM			BIT(29)
98#define ME4000_AI_CTRL_EX_TRIG_BOTH		BIT(31)
99#define ME4000_AI_CHANNEL_LIST_REG		0x78
100#define ME4000_AI_LIST_INPUT_DIFFERENTIAL	BIT(5)
101#define ME4000_AI_LIST_RANGE(x)			((3 - ((x) & 3)) << 6)
102#define ME4000_AI_LIST_LAST_ENTRY		BIT(8)
103#define ME4000_AI_DATA_REG			0x7c
104#define ME4000_AI_CHAN_TIMER_REG		0x80
105#define ME4000_AI_CHAN_PRE_TIMER_REG		0x84
106#define ME4000_AI_SCAN_TIMER_LOW_REG		0x88
107#define ME4000_AI_SCAN_TIMER_HIGH_REG		0x8c
108#define ME4000_AI_SCAN_PRE_TIMER_LOW_REG	0x90
109#define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG	0x94
110#define ME4000_AI_START_REG			0x98
111#define ME4000_IRQ_STATUS_REG			0x9c
112#define ME4000_IRQ_STATUS_EX			BIT(0)
113#define ME4000_IRQ_STATUS_LE			BIT(1)
114#define ME4000_IRQ_STATUS_AI_HF			BIT(2)
115#define ME4000_IRQ_STATUS_AO_0_HF		BIT(3)
116#define ME4000_IRQ_STATUS_AO_1_HF		BIT(4)
117#define ME4000_IRQ_STATUS_AO_2_HF		BIT(5)
118#define ME4000_IRQ_STATUS_AO_3_HF		BIT(6)
119#define ME4000_IRQ_STATUS_SC			BIT(7)
120#define ME4000_DIO_PORT_0_REG			0xa0
121#define ME4000_DIO_PORT_1_REG			0xa4
122#define ME4000_DIO_PORT_2_REG			0xa8
123#define ME4000_DIO_PORT_3_REG			0xac
124#define ME4000_DIO_DIR_REG			0xb0
125#define ME4000_AO_LOADSETREG_XX			0xb4
126#define ME4000_DIO_CTRL_REG			0xb8
127#define ME4000_DIO_CTRL_MODE_0			BIT(0)
128#define ME4000_DIO_CTRL_MODE_1			BIT(1)
129#define ME4000_DIO_CTRL_MODE_2			BIT(2)
130#define ME4000_DIO_CTRL_MODE_3			BIT(3)
131#define ME4000_DIO_CTRL_MODE_4			BIT(4)
132#define ME4000_DIO_CTRL_MODE_5			BIT(5)
133#define ME4000_DIO_CTRL_MODE_6			BIT(6)
134#define ME4000_DIO_CTRL_MODE_7			BIT(7)
135#define ME4000_DIO_CTRL_FUNCTION_0		BIT(8)
136#define ME4000_DIO_CTRL_FUNCTION_1		BIT(9)
137#define ME4000_DIO_CTRL_FIFO_HIGH_0		BIT(10)
138#define ME4000_DIO_CTRL_FIFO_HIGH_1		BIT(11)
139#define ME4000_DIO_CTRL_FIFO_HIGH_2		BIT(12)
140#define ME4000_DIO_CTRL_FIFO_HIGH_3		BIT(13)
141#define ME4000_AO_DEMUX_ADJUST_REG		0xbc
142#define ME4000_AO_DEMUX_ADJUST_VALUE		0x4c
143#define ME4000_AI_SAMPLE_COUNTER_REG		0xc0
144
145#define ME4000_AI_FIFO_COUNT			2048
146
147#define ME4000_AI_MIN_TICKS			66
148#define ME4000_AI_MIN_SAMPLE_TIME		2000
149
150#define ME4000_AI_CHANNEL_LIST_COUNT		1024
151
152struct me4000_private {
153	unsigned long plx_regbase;
154	unsigned int ai_ctrl_mode;
155	unsigned int ai_init_ticks;
156	unsigned int ai_scan_ticks;
157	unsigned int ai_chan_ticks;
158};
159
160enum me4000_boardid {
161	BOARD_ME4650,
162	BOARD_ME4660,
163	BOARD_ME4660I,
164	BOARD_ME4660S,
165	BOARD_ME4660IS,
166	BOARD_ME4670,
167	BOARD_ME4670I,
168	BOARD_ME4670S,
169	BOARD_ME4670IS,
170	BOARD_ME4680,
171	BOARD_ME4680I,
172	BOARD_ME4680S,
173	BOARD_ME4680IS,
174};
175
176struct me4000_board {
177	const char *name;
178	int ai_nchan;
179	unsigned int can_do_diff_ai:1;
180	unsigned int can_do_sh_ai:1;	/* sample & hold (8 channels) */
181	unsigned int ex_trig_analog:1;
182	unsigned int has_ao:1;
183	unsigned int has_ao_fifo:1;
184	unsigned int has_counter:1;
185};
186
187static const struct me4000_board me4000_boards[] = {
188	[BOARD_ME4650] = {
189		.name		= "ME-4650",
190		.ai_nchan	= 16,
191	},
192	[BOARD_ME4660] = {
193		.name		= "ME-4660",
194		.ai_nchan	= 32,
195		.can_do_diff_ai	= 1,
196		.has_counter	= 1,
197	},
198	[BOARD_ME4660I] = {
199		.name		= "ME-4660i",
200		.ai_nchan	= 32,
201		.can_do_diff_ai	= 1,
202		.has_counter	= 1,
203	},
204	[BOARD_ME4660S] = {
205		.name		= "ME-4660s",
206		.ai_nchan	= 32,
207		.can_do_diff_ai	= 1,
208		.can_do_sh_ai	= 1,
209		.has_counter	= 1,
210	},
211	[BOARD_ME4660IS] = {
212		.name		= "ME-4660is",
213		.ai_nchan	= 32,
214		.can_do_diff_ai	= 1,
215		.can_do_sh_ai	= 1,
216		.has_counter	= 1,
217	},
218	[BOARD_ME4670] = {
219		.name		= "ME-4670",
220		.ai_nchan	= 32,
221		.can_do_diff_ai	= 1,
222		.ex_trig_analog	= 1,
223		.has_ao		= 1,
224		.has_counter	= 1,
225	},
226	[BOARD_ME4670I] = {
227		.name		= "ME-4670i",
228		.ai_nchan	= 32,
229		.can_do_diff_ai	= 1,
230		.ex_trig_analog	= 1,
231		.has_ao		= 1,
232		.has_counter	= 1,
233	},
234	[BOARD_ME4670S] = {
235		.name		= "ME-4670s",
236		.ai_nchan	= 32,
237		.can_do_diff_ai	= 1,
238		.can_do_sh_ai	= 1,
239		.ex_trig_analog	= 1,
240		.has_ao		= 1,
241		.has_counter	= 1,
242	},
243	[BOARD_ME4670IS] = {
244		.name		= "ME-4670is",
245		.ai_nchan	= 32,
246		.can_do_diff_ai	= 1,
247		.can_do_sh_ai	= 1,
248		.ex_trig_analog	= 1,
249		.has_ao		= 1,
250		.has_counter	= 1,
251	},
252	[BOARD_ME4680] = {
253		.name		= "ME-4680",
254		.ai_nchan	= 32,
255		.can_do_diff_ai	= 1,
256		.ex_trig_analog	= 1,
257		.has_ao		= 1,
258		.has_ao_fifo	= 1,
259		.has_counter	= 1,
260	},
261	[BOARD_ME4680I] = {
262		.name		= "ME-4680i",
263		.ai_nchan	= 32,
264		.can_do_diff_ai	= 1,
265		.ex_trig_analog	= 1,
266		.has_ao		= 1,
267		.has_ao_fifo	= 1,
268		.has_counter	= 1,
269	},
270	[BOARD_ME4680S] = {
271		.name		= "ME-4680s",
272		.ai_nchan	= 32,
273		.can_do_diff_ai	= 1,
274		.can_do_sh_ai	= 1,
275		.ex_trig_analog	= 1,
276		.has_ao		= 1,
277		.has_ao_fifo	= 1,
278		.has_counter	= 1,
279	},
280	[BOARD_ME4680IS] = {
281		.name		= "ME-4680is",
282		.ai_nchan	= 32,
283		.can_do_diff_ai	= 1,
284		.can_do_sh_ai	= 1,
285		.ex_trig_analog	= 1,
286		.has_ao		= 1,
287		.has_ao_fifo	= 1,
288		.has_counter	= 1,
289	},
290};
291
292/*
293 * NOTE: the ranges here are inverted compared to the values
294 * written to the ME4000_AI_CHANNEL_LIST_REG,
295 *
296 * The ME4000_AI_LIST_RANGE() macro handles the inversion.
297 */
298static const struct comedi_lrange me4000_ai_range = {
299	4, {
300		UNI_RANGE(2.5),
301		UNI_RANGE(10),
302		BIP_RANGE(2.5),
303		BIP_RANGE(10)
304	}
305};
306
307static int me4000_xilinx_download(struct comedi_device *dev,
308				  const u8 *data, size_t size,
309				  unsigned long context)
310{
311	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
312	struct me4000_private *devpriv = dev->private;
313	unsigned long xilinx_iobase = pci_resource_start(pcidev, 5);
314	unsigned int file_length;
315	unsigned int val;
316	unsigned int i;
317
318	if (!xilinx_iobase)
319		return -ENODEV;
320
321	/*
322	 * Set PLX local interrupt 2 polarity to high.
323	 * Interrupt is thrown by init pin of xilinx.
324	 */
325	outl(PLX9052_INTCSR_LI2POL, devpriv->plx_regbase + PLX9052_INTCSR);
326
327	/* Set /CS and /WRITE of the Xilinx */
328	val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
329	val |= PLX9052_CNTRL_UIO2_DATA;
330	outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
331
332	/* Init Xilinx with CS1 */
333	inb(xilinx_iobase + 0xC8);
334
335	/* Wait until /INIT pin is set */
336	usleep_range(20, 1000);
337	val = inl(devpriv->plx_regbase + PLX9052_INTCSR);
338	if (!(val & PLX9052_INTCSR_LI2STAT)) {
339		dev_err(dev->class_dev, "Can't init Xilinx\n");
340		return -EIO;
341	}
342
343	/* Reset /CS and /WRITE of the Xilinx */
344	val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
345	val &= ~PLX9052_CNTRL_UIO2_DATA;
346	outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
347
348	/* Download Xilinx firmware */
349	file_length = (((unsigned int)data[0] & 0xff) << 24) +
350		      (((unsigned int)data[1] & 0xff) << 16) +
351		      (((unsigned int)data[2] & 0xff) << 8) +
352		      ((unsigned int)data[3] & 0xff);
353	usleep_range(10, 1000);
354
355	for (i = 0; i < file_length; i++) {
356		outb(data[16 + i], xilinx_iobase);
357		usleep_range(10, 1000);
358
359		/* Check if BUSY flag is low */
360		val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
361		if (val & PLX9052_CNTRL_UIO1_DATA) {
362			dev_err(dev->class_dev,
363				"Xilinx is still busy (i = %d)\n", i);
364			return -EIO;
365		}
366	}
367
368	/* If done flag is high download was successful */
369	val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
370	if (!(val & PLX9052_CNTRL_UIO0_DATA)) {
371		dev_err(dev->class_dev, "DONE flag is not set\n");
372		dev_err(dev->class_dev, "Download not successful\n");
373		return -EIO;
374	}
375
376	/* Set /CS and /WRITE */
377	val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
378	val |= PLX9052_CNTRL_UIO2_DATA;
379	outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
380
381	return 0;
382}
383
384static void me4000_ai_reset(struct comedi_device *dev)
385{
386	unsigned int ctrl;
387
388	/* Stop any running conversion */
389	ctrl = inl(dev->iobase + ME4000_AI_CTRL_REG);
390	ctrl |= ME4000_AI_CTRL_STOP | ME4000_AI_CTRL_IMMEDIATE_STOP;
391	outl(ctrl, dev->iobase + ME4000_AI_CTRL_REG);
392
393	/* Clear the control register */
394	outl(0x0, dev->iobase + ME4000_AI_CTRL_REG);
395}
396
397static void me4000_reset(struct comedi_device *dev)
398{
399	struct me4000_private *devpriv = dev->private;
400	unsigned int val;
401	int chan;
402
403	/* Disable interrupts on the PLX */
404	outl(0, devpriv->plx_regbase + PLX9052_INTCSR);
405
406	/* Software reset the PLX */
407	val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
408	val |= PLX9052_CNTRL_PCI_RESET;
409	outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
410	val &= ~PLX9052_CNTRL_PCI_RESET;
411	outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
412
413	/* 0x8000 to the DACs means an output voltage of 0V */
414	for (chan = 0; chan < 4; chan++)
415		outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan));
416
417	me4000_ai_reset(dev);
418
419	/* Set both stop bits in the analog output control register */
420	val = ME4000_AO_CTRL_IMMEDIATE_STOP | ME4000_AO_CTRL_STOP;
421	for (chan = 0; chan < 4; chan++)
422		outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan));
423
424	/* Set the adustment register for AO demux */
425	outl(ME4000_AO_DEMUX_ADJUST_VALUE,
426	     dev->iobase + ME4000_AO_DEMUX_ADJUST_REG);
427
428	/*
429	 * Set digital I/O direction for port 0
430	 * to output on isolated versions
431	 */
432	if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1))
433		outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG);
434}
435
436static unsigned int me4000_ai_get_sample(struct comedi_device *dev,
437					 struct comedi_subdevice *s)
438{
439	unsigned int val;
440
441	/* read two's complement value and munge to offset binary */
442	val = inl(dev->iobase + ME4000_AI_DATA_REG);
443	return comedi_offset_munge(s, val);
444}
445
446static int me4000_ai_eoc(struct comedi_device *dev,
447			 struct comedi_subdevice *s,
448			 struct comedi_insn *insn,
449			 unsigned long context)
450{
451	unsigned int status;
452
453	status = inl(dev->iobase + ME4000_AI_STATUS_REG);
454	if (status & ME4000_AI_STATUS_EF_DATA)
455		return 0;
456	return -EBUSY;
457}
458
459static int me4000_ai_insn_read(struct comedi_device *dev,
460			       struct comedi_subdevice *s,
461			       struct comedi_insn *insn,
462			       unsigned int *data)
463{
464	unsigned int chan = CR_CHAN(insn->chanspec);
465	unsigned int range = CR_RANGE(insn->chanspec);
466	unsigned int aref = CR_AREF(insn->chanspec);
467	unsigned int entry;
468	int ret = 0;
469	int i;
470
471	entry = chan | ME4000_AI_LIST_RANGE(range);
472	if (aref == AREF_DIFF) {
473		if (!(s->subdev_flags & SDF_DIFF)) {
474			dev_err(dev->class_dev,
475				"Differential inputs are not available\n");
476			return -EINVAL;
477		}
478
479		if (!comedi_range_is_bipolar(s, range)) {
480			dev_err(dev->class_dev,
481				"Range must be bipolar when aref = diff\n");
482			return -EINVAL;
483		}
484
485		if (chan >= (s->n_chan / 2)) {
486			dev_err(dev->class_dev,
487				"Analog input is not available\n");
488			return -EINVAL;
489		}
490		entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
491	}
492
493	entry |= ME4000_AI_LIST_LAST_ENTRY;
494
495	/* Enable channel list and data fifo for single acquisition mode */
496	outl(ME4000_AI_CTRL_CHANNEL_FIFO | ME4000_AI_CTRL_DATA_FIFO,
497	     dev->iobase + ME4000_AI_CTRL_REG);
498
499	/* Generate channel list entry */
500	outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
501
502	/* Set the timer to maximum sample rate */
503	outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
504	outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
505
506	for (i = 0; i < insn->n; i++) {
507		unsigned int val;
508
509		/* start conversion by dummy read */
510		inl(dev->iobase + ME4000_AI_START_REG);
511
512		ret = comedi_timeout(dev, s, insn, me4000_ai_eoc, 0);
513		if (ret)
514			break;
515
516		val = me4000_ai_get_sample(dev, s);
517		data[i] = comedi_offset_munge(s, val);
518	}
519
520	me4000_ai_reset(dev);
521
522	return ret ? ret : insn->n;
523}
524
525static int me4000_ai_cancel(struct comedi_device *dev,
526			    struct comedi_subdevice *s)
527{
528	me4000_ai_reset(dev);
529
530	return 0;
531}
532
533static int me4000_ai_check_chanlist(struct comedi_device *dev,
534				    struct comedi_subdevice *s,
535				    struct comedi_cmd *cmd)
536{
537	unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
538	int i;
539
540	for (i = 0; i < cmd->chanlist_len; i++) {
541		unsigned int chan = CR_CHAN(cmd->chanlist[i]);
542		unsigned int range = CR_RANGE(cmd->chanlist[i]);
543		unsigned int aref = CR_AREF(cmd->chanlist[i]);
544
545		if (aref != aref0) {
546			dev_dbg(dev->class_dev,
547				"Mode is not equal for all entries\n");
548			return -EINVAL;
549		}
550
551		if (aref == AREF_DIFF) {
552			if (!(s->subdev_flags & SDF_DIFF)) {
553				dev_err(dev->class_dev,
554					"Differential inputs are not available\n");
555				return -EINVAL;
556			}
557
558			if (chan >= (s->n_chan / 2)) {
559				dev_dbg(dev->class_dev,
560					"Channel number to high\n");
561				return -EINVAL;
562			}
563
564			if (!comedi_range_is_bipolar(s, range)) {
565				dev_dbg(dev->class_dev,
566					"Bipolar is not selected in differential mode\n");
567				return -EINVAL;
568			}
569		}
570	}
571
572	return 0;
573}
574
575static void me4000_ai_round_cmd_args(struct comedi_device *dev,
576				     struct comedi_subdevice *s,
577				     struct comedi_cmd *cmd)
578{
579	struct me4000_private *devpriv = dev->private;
580	int rest;
581
582	devpriv->ai_init_ticks = 0;
583	devpriv->ai_scan_ticks = 0;
584	devpriv->ai_chan_ticks = 0;
585
586	if (cmd->start_arg) {
587		devpriv->ai_init_ticks = (cmd->start_arg * 33) / 1000;
588		rest = (cmd->start_arg * 33) % 1000;
589
590		if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
591			if (rest > 33)
592				devpriv->ai_init_ticks++;
593		} else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
594			if (rest)
595				devpriv->ai_init_ticks++;
596		}
597	}
598
599	if (cmd->scan_begin_arg) {
600		devpriv->ai_scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
601		rest = (cmd->scan_begin_arg * 33) % 1000;
602
603		if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
604			if (rest > 33)
605				devpriv->ai_scan_ticks++;
606		} else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
607			if (rest)
608				devpriv->ai_scan_ticks++;
609		}
610	}
611
612	if (cmd->convert_arg) {
613		devpriv->ai_chan_ticks = (cmd->convert_arg * 33) / 1000;
614		rest = (cmd->convert_arg * 33) % 1000;
615
616		if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
617			if (rest > 33)
618				devpriv->ai_chan_ticks++;
619		} else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
620			if (rest)
621				devpriv->ai_chan_ticks++;
622		}
623	}
624}
625
626static void me4000_ai_write_chanlist(struct comedi_device *dev,
627				     struct comedi_subdevice *s,
628				     struct comedi_cmd *cmd)
629{
630	int i;
631
632	for (i = 0; i < cmd->chanlist_len; i++) {
633		unsigned int chan = CR_CHAN(cmd->chanlist[i]);
634		unsigned int range = CR_RANGE(cmd->chanlist[i]);
635		unsigned int aref = CR_AREF(cmd->chanlist[i]);
636		unsigned int entry;
637
638		entry = chan | ME4000_AI_LIST_RANGE(range);
639
640		if (aref == AREF_DIFF)
641			entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
642
643		if (i == (cmd->chanlist_len - 1))
644			entry |= ME4000_AI_LIST_LAST_ENTRY;
645
646		outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
647	}
648}
649
650static int me4000_ai_do_cmd(struct comedi_device *dev,
651			    struct comedi_subdevice *s)
652{
653	struct me4000_private *devpriv = dev->private;
654	struct comedi_cmd *cmd = &s->async->cmd;
655	unsigned int ctrl;
656
657	/* Write timer arguments */
658	outl(devpriv->ai_init_ticks - 1,
659	     dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG);
660	outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG);
661
662	if (devpriv->ai_scan_ticks) {
663		outl(devpriv->ai_scan_ticks - 1,
664		     dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG);
665		outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG);
666	}
667
668	outl(devpriv->ai_chan_ticks - 1,
669	     dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
670	outl(devpriv->ai_chan_ticks - 1,
671	     dev->iobase + ME4000_AI_CHAN_TIMER_REG);
672
673	/* Start sources */
674	ctrl = devpriv->ai_ctrl_mode |
675	       ME4000_AI_CTRL_CHANNEL_FIFO |
676	       ME4000_AI_CTRL_DATA_FIFO;
677
678	/* Stop triggers */
679	if (cmd->stop_src == TRIG_COUNT) {
680		outl(cmd->chanlist_len * cmd->stop_arg,
681		     dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
682		ctrl |= ME4000_AI_CTRL_SC_IRQ;
683	} else if (cmd->stop_src == TRIG_NONE &&
684		   cmd->scan_end_src == TRIG_COUNT) {
685		outl(cmd->scan_end_arg,
686		     dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
687		ctrl |= ME4000_AI_CTRL_SC_IRQ;
688	}
689	ctrl |= ME4000_AI_CTRL_HF_IRQ;
690
691	/* Write the setup to the control register */
692	outl(ctrl, dev->iobase + ME4000_AI_CTRL_REG);
693
694	/* Write the channel list */
695	me4000_ai_write_chanlist(dev, s, cmd);
696
697	/* Start acquistion by dummy read */
698	inl(dev->iobase + ME4000_AI_START_REG);
699
700	return 0;
701}
702
703static int me4000_ai_do_cmd_test(struct comedi_device *dev,
704				 struct comedi_subdevice *s,
705				 struct comedi_cmd *cmd)
706{
707	struct me4000_private *devpriv = dev->private;
708	int err = 0;
709
710	/* Step 1 : check if triggers are trivially valid */
711
712	err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
713	err |= comedi_check_trigger_src(&cmd->scan_begin_src,
714					TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
715	err |= comedi_check_trigger_src(&cmd->convert_src,
716					TRIG_TIMER | TRIG_EXT);
717	err |= comedi_check_trigger_src(&cmd->scan_end_src,
718					TRIG_NONE | TRIG_COUNT);
719	err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE | TRIG_COUNT);
720
721	if (err)
722		return 1;
723
724	/* Step 2a : make sure trigger sources are unique */
725
726	err |= comedi_check_trigger_is_unique(cmd->start_src);
727	err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
728	err |= comedi_check_trigger_is_unique(cmd->convert_src);
729	err |= comedi_check_trigger_is_unique(cmd->scan_end_src);
730	err |= comedi_check_trigger_is_unique(cmd->stop_src);
731
732	/* Step 2b : and mutually compatible */
733
734	if (cmd->start_src == TRIG_NOW &&
735	    cmd->scan_begin_src == TRIG_TIMER &&
736	    cmd->convert_src == TRIG_TIMER) {
737		devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0;
738	} else if (cmd->start_src == TRIG_NOW &&
739		   cmd->scan_begin_src == TRIG_FOLLOW &&
740		   cmd->convert_src == TRIG_TIMER) {
741		devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0;
742	} else if (cmd->start_src == TRIG_EXT &&
743		   cmd->scan_begin_src == TRIG_TIMER &&
744		   cmd->convert_src == TRIG_TIMER) {
745		devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_1;
746	} else if (cmd->start_src == TRIG_EXT &&
747		   cmd->scan_begin_src == TRIG_FOLLOW &&
748		   cmd->convert_src == TRIG_TIMER) {
749		devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_1;
750	} else if (cmd->start_src == TRIG_EXT &&
751		   cmd->scan_begin_src == TRIG_EXT &&
752		   cmd->convert_src == TRIG_TIMER) {
753		devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_2;
754	} else if (cmd->start_src == TRIG_EXT &&
755		   cmd->scan_begin_src == TRIG_EXT &&
756		   cmd->convert_src == TRIG_EXT) {
757		devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0 |
758					ME4000_AI_CTRL_MODE_1;
759	} else {
760		err |= -EINVAL;
761	}
762
763	if (err)
764		return 2;
765
766	/* Step 3: check if arguments are trivially valid */
767
768	err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
769
770	if (cmd->chanlist_len < 1) {
771		cmd->chanlist_len = 1;
772		err |= -EINVAL;
773	}
774
775	/* Round the timer arguments */
776	me4000_ai_round_cmd_args(dev, s, cmd);
777
778	if (devpriv->ai_init_ticks < 66) {
779		cmd->start_arg = 2000;
780		err |= -EINVAL;
781	}
782	if (devpriv->ai_scan_ticks && devpriv->ai_scan_ticks < 67) {
783		cmd->scan_begin_arg = 2031;
784		err |= -EINVAL;
785	}
786	if (devpriv->ai_chan_ticks < 66) {
787		cmd->convert_arg = 2000;
788		err |= -EINVAL;
789	}
790
791	if (cmd->stop_src == TRIG_COUNT)
792		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
793	else	/* TRIG_NONE */
794		err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
795
796	if (err)
797		return 3;
798
799	/*
800	 * Stage 4. Check for argument conflicts.
801	 */
802	if (cmd->start_src == TRIG_NOW &&
803	    cmd->scan_begin_src == TRIG_TIMER &&
804	    cmd->convert_src == TRIG_TIMER) {
805		/* Check timer arguments */
806		if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
807			dev_err(dev->class_dev, "Invalid start arg\n");
808			cmd->start_arg = 2000;	/*  66 ticks at least */
809			err++;
810		}
811		if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
812			dev_err(dev->class_dev, "Invalid convert arg\n");
813			cmd->convert_arg = 2000;	/*  66 ticks at least */
814			err++;
815		}
816		if (devpriv->ai_scan_ticks <=
817		    cmd->chanlist_len * devpriv->ai_chan_ticks) {
818			dev_err(dev->class_dev, "Invalid scan end arg\n");
819
820			/*  At least one tick more */
821			cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
822			err++;
823		}
824	} else if (cmd->start_src == TRIG_NOW &&
825		   cmd->scan_begin_src == TRIG_FOLLOW &&
826		   cmd->convert_src == TRIG_TIMER) {
827		/* Check timer arguments */
828		if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
829			dev_err(dev->class_dev, "Invalid start arg\n");
830			cmd->start_arg = 2000;	/*  66 ticks at least */
831			err++;
832		}
833		if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
834			dev_err(dev->class_dev, "Invalid convert arg\n");
835			cmd->convert_arg = 2000;	/*  66 ticks at least */
836			err++;
837		}
838	} else if (cmd->start_src == TRIG_EXT &&
839		   cmd->scan_begin_src == TRIG_TIMER &&
840		   cmd->convert_src == TRIG_TIMER) {
841		/* Check timer arguments */
842		if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
843			dev_err(dev->class_dev, "Invalid start arg\n");
844			cmd->start_arg = 2000;	/*  66 ticks at least */
845			err++;
846		}
847		if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
848			dev_err(dev->class_dev, "Invalid convert arg\n");
849			cmd->convert_arg = 2000;	/*  66 ticks at least */
850			err++;
851		}
852		if (devpriv->ai_scan_ticks <=
853		    cmd->chanlist_len * devpriv->ai_chan_ticks) {
854			dev_err(dev->class_dev, "Invalid scan end arg\n");
855
856			/*  At least one tick more */
857			cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
858			err++;
859		}
860	} else if (cmd->start_src == TRIG_EXT &&
861		   cmd->scan_begin_src == TRIG_FOLLOW &&
862		   cmd->convert_src == TRIG_TIMER) {
863		/* Check timer arguments */
864		if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
865			dev_err(dev->class_dev, "Invalid start arg\n");
866			cmd->start_arg = 2000;	/*  66 ticks at least */
867			err++;
868		}
869		if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
870			dev_err(dev->class_dev, "Invalid convert arg\n");
871			cmd->convert_arg = 2000;	/*  66 ticks at least */
872			err++;
873		}
874	} else if (cmd->start_src == TRIG_EXT &&
875		   cmd->scan_begin_src == TRIG_EXT &&
876		   cmd->convert_src == TRIG_TIMER) {
877		/* Check timer arguments */
878		if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
879			dev_err(dev->class_dev, "Invalid start arg\n");
880			cmd->start_arg = 2000;	/*  66 ticks at least */
881			err++;
882		}
883		if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
884			dev_err(dev->class_dev, "Invalid convert arg\n");
885			cmd->convert_arg = 2000;	/*  66 ticks at least */
886			err++;
887		}
888	} else if (cmd->start_src == TRIG_EXT &&
889		   cmd->scan_begin_src == TRIG_EXT &&
890		   cmd->convert_src == TRIG_EXT) {
891		/* Check timer arguments */
892		if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
893			dev_err(dev->class_dev, "Invalid start arg\n");
894			cmd->start_arg = 2000;	/*  66 ticks at least */
895			err++;
896		}
897	}
898	if (cmd->scan_end_src == TRIG_COUNT) {
899		if (cmd->scan_end_arg == 0) {
900			dev_err(dev->class_dev, "Invalid scan end arg\n");
901			cmd->scan_end_arg = 1;
902			err++;
903		}
904	}
905
906	if (err)
907		return 4;
908
909	/* Step 5: check channel list if it exists */
910	if (cmd->chanlist && cmd->chanlist_len > 0)
911		err |= me4000_ai_check_chanlist(dev, s, cmd);
912
913	if (err)
914		return 5;
915
916	return 0;
917}
918
919static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
920{
921	unsigned int tmp;
922	struct comedi_device *dev = dev_id;
923	struct comedi_subdevice *s = dev->read_subdev;
924	int i;
925	int c = 0;
926	unsigned short lval;
927
928	if (!dev->attached)
929		return IRQ_NONE;
930
931	if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
932	    ME4000_IRQ_STATUS_AI_HF) {
933		/* Read status register to find out what happened */
934		tmp = inl(dev->iobase + ME4000_AI_STATUS_REG);
935
936		if (!(tmp & ME4000_AI_STATUS_FF_DATA) &&
937		    !(tmp & ME4000_AI_STATUS_HF_DATA) &&
938		    (tmp & ME4000_AI_STATUS_EF_DATA)) {
939			dev_err(dev->class_dev, "FIFO overflow\n");
940			s->async->events |= COMEDI_CB_ERROR;
941			c = ME4000_AI_FIFO_COUNT;
942		} else if ((tmp & ME4000_AI_STATUS_FF_DATA) &&
943			   !(tmp & ME4000_AI_STATUS_HF_DATA) &&
944			   (tmp & ME4000_AI_STATUS_EF_DATA)) {
945			c = ME4000_AI_FIFO_COUNT / 2;
946		} else {
947			dev_err(dev->class_dev, "Undefined FIFO state\n");
948			s->async->events |= COMEDI_CB_ERROR;
949			c = 0;
950		}
951
952		for (i = 0; i < c; i++) {
953			lval = me4000_ai_get_sample(dev, s);
954			if (!comedi_buf_write_samples(s, &lval, 1))
955				break;
956		}
957
958		/* Work is done, so reset the interrupt */
959		tmp |= ME4000_AI_CTRL_HF_IRQ_RESET;
960		outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
961		tmp &= ~ME4000_AI_CTRL_HF_IRQ_RESET;
962		outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
963	}
964
965	if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
966	    ME4000_IRQ_STATUS_SC) {
967		/* Acquisition is complete */
968		s->async->events |= COMEDI_CB_EOA;
969
970		/* Poll data until fifo empty */
971		while (inl(dev->iobase + ME4000_AI_STATUS_REG) &
972		       ME4000_AI_STATUS_EF_DATA) {
973			lval = me4000_ai_get_sample(dev, s);
974			if (!comedi_buf_write_samples(s, &lval, 1))
975				break;
976		}
977
978		/* Work is done, so reset the interrupt */
979		tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
980		tmp |= ME4000_AI_CTRL_SC_IRQ_RESET;
981		outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
982		tmp &= ~ME4000_AI_CTRL_SC_IRQ_RESET;
983		outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
984	}
985
986	comedi_handle_events(dev, s);
987
988	return IRQ_HANDLED;
989}
990
991static int me4000_ao_insn_write(struct comedi_device *dev,
992				struct comedi_subdevice *s,
993				struct comedi_insn *insn,
994				unsigned int *data)
995{
996	unsigned int chan = CR_CHAN(insn->chanspec);
997	unsigned int tmp;
998
999	/* Stop any running conversion */
1000	tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan));
1001	tmp |= ME4000_AO_CTRL_IMMEDIATE_STOP;
1002	outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan));
1003
1004	/* Clear control register and set to single mode */
1005	outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan));
1006
1007	/* Write data value */
1008	outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan));
1009
1010	/* Store in the mirror */
1011	s->readback[chan] = data[0];
1012
1013	return 1;
1014}
1015
1016static int me4000_dio_insn_bits(struct comedi_device *dev,
1017				struct comedi_subdevice *s,
1018				struct comedi_insn *insn,
1019				unsigned int *data)
1020{
1021	if (comedi_dio_update_state(s, data)) {
1022		outl((s->state >> 0) & 0xFF,
1023		     dev->iobase + ME4000_DIO_PORT_0_REG);
1024		outl((s->state >> 8) & 0xFF,
1025		     dev->iobase + ME4000_DIO_PORT_1_REG);
1026		outl((s->state >> 16) & 0xFF,
1027		     dev->iobase + ME4000_DIO_PORT_2_REG);
1028		outl((s->state >> 24) & 0xFF,
1029		     dev->iobase + ME4000_DIO_PORT_3_REG);
1030	}
1031
1032	data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
1033		  ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
1034		  ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
1035		  ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24);
1036
1037	return insn->n;
1038}
1039
1040static int me4000_dio_insn_config(struct comedi_device *dev,
1041				  struct comedi_subdevice *s,
1042				  struct comedi_insn *insn,
1043				  unsigned int *data)
1044{
1045	unsigned int chan = CR_CHAN(insn->chanspec);
1046	unsigned int mask;
1047	unsigned int tmp;
1048	int ret;
1049
1050	if (chan < 8)
1051		mask = 0x000000ff;
1052	else if (chan < 16)
1053		mask = 0x0000ff00;
1054	else if (chan < 24)
1055		mask = 0x00ff0000;
1056	else
1057		mask = 0xff000000;
1058
1059	ret = comedi_dio_insn_config(dev, s, insn, data, mask);
1060	if (ret)
1061		return ret;
1062
1063	tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
1064	tmp &= ~(ME4000_DIO_CTRL_MODE_0 | ME4000_DIO_CTRL_MODE_1 |
1065		 ME4000_DIO_CTRL_MODE_2 | ME4000_DIO_CTRL_MODE_3 |
1066		 ME4000_DIO_CTRL_MODE_4 | ME4000_DIO_CTRL_MODE_5 |
1067		 ME4000_DIO_CTRL_MODE_6 | ME4000_DIO_CTRL_MODE_7);
1068	if (s->io_bits & 0x000000ff)
1069		tmp |= ME4000_DIO_CTRL_MODE_0;
1070	if (s->io_bits & 0x0000ff00)
1071		tmp |= ME4000_DIO_CTRL_MODE_2;
1072	if (s->io_bits & 0x00ff0000)
1073		tmp |= ME4000_DIO_CTRL_MODE_4;
1074	if (s->io_bits & 0xff000000)
1075		tmp |= ME4000_DIO_CTRL_MODE_6;
1076
1077	/*
1078	 * Check for optoisolated ME-4000 version.
1079	 * If one the first port is a fixed output
1080	 * port and the second is a fixed input port.
1081	 */
1082	if (inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1083		s->io_bits |= 0x000000ff;
1084		s->io_bits &= ~0x0000ff00;
1085		tmp |= ME4000_DIO_CTRL_MODE_0;
1086		tmp &= ~(ME4000_DIO_CTRL_MODE_2 | ME4000_DIO_CTRL_MODE_3);
1087	}
1088
1089	outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
1090
1091	return insn->n;
1092}
1093
1094static int me4000_auto_attach(struct comedi_device *dev,
1095			      unsigned long context)
1096{
1097	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1098	const struct me4000_board *board = NULL;
1099	struct me4000_private *devpriv;
1100	struct comedi_subdevice *s;
1101	int result;
1102
1103	if (context < ARRAY_SIZE(me4000_boards))
1104		board = &me4000_boards[context];
1105	if (!board)
1106		return -ENODEV;
1107	dev->board_ptr = board;
1108	dev->board_name = board->name;
1109
1110	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1111	if (!devpriv)
1112		return -ENOMEM;
1113
1114	result = comedi_pci_enable(dev);
1115	if (result)
1116		return result;
1117
1118	devpriv->plx_regbase = pci_resource_start(pcidev, 1);
1119	dev->iobase = pci_resource_start(pcidev, 2);
1120	if (!devpriv->plx_regbase || !dev->iobase)
1121		return -ENODEV;
1122
1123	result = comedi_load_firmware(dev, &pcidev->dev, ME4000_FIRMWARE,
1124				      me4000_xilinx_download, 0);
1125	if (result < 0)
1126		return result;
1127
1128	me4000_reset(dev);
1129
1130	if (pcidev->irq > 0) {
1131		result = request_irq(pcidev->irq, me4000_ai_isr, IRQF_SHARED,
1132				     dev->board_name, dev);
1133		if (result == 0) {
1134			dev->irq = pcidev->irq;
1135
1136			/* Enable interrupts on the PLX */
1137			outl(PLX9052_INTCSR_LI1ENAB | PLX9052_INTCSR_LI1POL |
1138			     PLX9052_INTCSR_PCIENAB,
1139			     devpriv->plx_regbase + PLX9052_INTCSR);
1140		}
1141	}
1142
1143	result = comedi_alloc_subdevices(dev, 4);
1144	if (result)
1145		return result;
1146
1147	/* Analog Input subdevice */
1148	s = &dev->subdevices[0];
1149	s->type		= COMEDI_SUBD_AI;
1150	s->subdev_flags	= SDF_READABLE | SDF_COMMON | SDF_GROUND;
1151	if (board->can_do_diff_ai)
1152		s->subdev_flags	|= SDF_DIFF;
1153	s->n_chan	= board->ai_nchan;
1154	s->maxdata	= 0xffff;
1155	s->len_chanlist	= ME4000_AI_CHANNEL_LIST_COUNT;
1156	s->range_table	= &me4000_ai_range;
1157	s->insn_read	= me4000_ai_insn_read;
1158
1159	if (dev->irq) {
1160		dev->read_subdev = s;
1161		s->subdev_flags	|= SDF_CMD_READ;
1162		s->cancel	= me4000_ai_cancel;
1163		s->do_cmdtest	= me4000_ai_do_cmd_test;
1164		s->do_cmd	= me4000_ai_do_cmd;
1165	}
1166
1167	/* Analog Output subdevice */
1168	s = &dev->subdevices[1];
1169	if (board->has_ao) {
1170		s->type		= COMEDI_SUBD_AO;
1171		s->subdev_flags	= SDF_WRITABLE | SDF_COMMON | SDF_GROUND;
1172		s->n_chan	= 4;
1173		s->maxdata	= 0xffff;
1174		s->range_table	= &range_bipolar10;
1175		s->insn_write	= me4000_ao_insn_write;
1176
1177		result = comedi_alloc_subdev_readback(s);
1178		if (result)
1179			return result;
1180	} else {
1181		s->type		= COMEDI_SUBD_UNUSED;
1182	}
1183
1184	/* Digital I/O subdevice */
1185	s = &dev->subdevices[2];
1186	s->type		= COMEDI_SUBD_DIO;
1187	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE;
1188	s->n_chan	= 32;
1189	s->maxdata	= 1;
1190	s->range_table	= &range_digital;
1191	s->insn_bits	= me4000_dio_insn_bits;
1192	s->insn_config	= me4000_dio_insn_config;
1193
1194	/*
1195	 * Check for optoisolated ME-4000 version. If one the first
1196	 * port is a fixed output port and the second is a fixed input port.
1197	 */
1198	if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1199		s->io_bits |= 0xFF;
1200		outl(ME4000_DIO_CTRL_MODE_0,
1201		     dev->iobase + ME4000_DIO_DIR_REG);
1202	}
1203
1204	/* Counter subdevice (8254) */
1205	s = &dev->subdevices[3];
1206	if (board->has_counter) {
1207		unsigned long timer_base = pci_resource_start(pcidev, 3);
1208
1209		if (!timer_base)
1210			return -ENODEV;
1211
1212		dev->pacer = comedi_8254_io_alloc(timer_base, 0, I8254_IO8, 0);
1213		if (IS_ERR(dev->pacer))
1214			return PTR_ERR(dev->pacer);
1215
1216		comedi_8254_subdevice_init(s, dev->pacer);
1217	} else {
1218		s->type = COMEDI_SUBD_UNUSED;
1219	}
1220
1221	return 0;
1222}
1223
1224static void me4000_detach(struct comedi_device *dev)
1225{
1226	if (dev->irq) {
1227		struct me4000_private *devpriv = dev->private;
1228
1229		/* Disable interrupts on the PLX */
1230		outl(0, devpriv->plx_regbase + PLX9052_INTCSR);
1231	}
1232	comedi_pci_detach(dev);
1233}
1234
1235static struct comedi_driver me4000_driver = {
1236	.driver_name	= "me4000",
1237	.module		= THIS_MODULE,
1238	.auto_attach	= me4000_auto_attach,
1239	.detach		= me4000_detach,
1240};
1241
1242static int me4000_pci_probe(struct pci_dev *dev,
1243			    const struct pci_device_id *id)
1244{
1245	return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data);
1246}
1247
1248static const struct pci_device_id me4000_pci_table[] = {
1249	{ PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 },
1250	{ PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 },
1251	{ PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I },
1252	{ PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S },
1253	{ PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS },
1254	{ PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 },
1255	{ PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I },
1256	{ PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S },
1257	{ PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS },
1258	{ PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 },
1259	{ PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I },
1260	{ PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S },
1261	{ PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS },
1262	{ 0 }
1263};
1264MODULE_DEVICE_TABLE(pci, me4000_pci_table);
1265
1266static struct pci_driver me4000_pci_driver = {
1267	.name		= "me4000",
1268	.id_table	= me4000_pci_table,
1269	.probe		= me4000_pci_probe,
1270	.remove		= comedi_pci_auto_unconfig,
1271};
1272module_comedi_pci_driver(me4000_driver, me4000_pci_driver);
1273
1274MODULE_AUTHOR("Comedi https://www.comedi.org");
1275MODULE_DESCRIPTION("Comedi driver for Meilhaus ME-4000 series boards");
1276MODULE_LICENSE("GPL");
1277MODULE_FIRMWARE(ME4000_FIRMWARE);
1278