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