me4000.c revision 9ced1de69125b60f40127eddaa3be2a92bb0a1df
1/*
2   comedi/drivers/me4000.c
3   Source code for the Meilhaus ME-4000 board family.
4
5   COMEDI - Linux Control and Measurement Device Interface
6   Copyright (C) 2000 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   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 */
23/*
24Driver: me4000
25Description: Meilhaus ME-4000 series boards
26Devices: [Meilhaus] ME-4650 (me4000), ME-4670i, ME-4680, ME-4680i, ME-4680is
27Author: gg (Guenter Gebhardt <g.gebhardt@meilhaus.com>)
28Updated: Mon, 18 Mar 2002 15:34:01 -0800
29Status: broken (no support for loading firmware)
30
31Supports:
32
33    - Analog Input
34    - Analog Output
35    - Digital I/O
36    - Counter
37
38Configuration Options:
39
40    [0] - PCI bus number (optional)
41    [1] - PCI slot number (optional)
42
43    If bus/slot is not specified, the first available PCI
44    device will be used.
45
46The firmware required by these boards is available in the
47comedi_nonfree_firmware tarball available from
48http://www.comedi.org.  However, the driver's support for
49loading the firmware through comedi_config is currently
50broken.
51
52 */
53
54#include "../comedidev.h"
55
56#include <linux/delay.h>
57#include <linux/list.h>
58#include <linux/spinlock.h>
59
60#include "comedi_pci.h"
61#include "me4000.h"
62#if 0
63/* file removed due to GPL incompatibility */
64#include "me4000_fw.h"
65#endif
66
67/*=============================================================================
68  PCI device table.
69  This is used by modprobe to translate PCI IDs to drivers.
70  ===========================================================================*/
71
72static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
73	{PCI_VENDOR_ID_MEILHAUS, 0x4650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
74
75	{PCI_VENDOR_ID_MEILHAUS, 0x4660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
76	{PCI_VENDOR_ID_MEILHAUS, 0x4661, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
77	{PCI_VENDOR_ID_MEILHAUS, 0x4662, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
78	{PCI_VENDOR_ID_MEILHAUS, 0x4663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
79
80	{PCI_VENDOR_ID_MEILHAUS, 0x4670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
81	{PCI_VENDOR_ID_MEILHAUS, 0x4671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
82	{PCI_VENDOR_ID_MEILHAUS, 0x4672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
83	{PCI_VENDOR_ID_MEILHAUS, 0x4673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
84
85	{PCI_VENDOR_ID_MEILHAUS, 0x4680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
86	{PCI_VENDOR_ID_MEILHAUS, 0x4681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
87	{PCI_VENDOR_ID_MEILHAUS, 0x4682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
88	{PCI_VENDOR_ID_MEILHAUS, 0x4683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
89
90	{0}
91};
92
93MODULE_DEVICE_TABLE(pci, me4000_pci_table);
94
95static const me4000_board_t me4000_boards[] = {
96	{"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0}},
97
98	{"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3}},
99	{"ME-4660i", 0x4661, {0, 0}, {32, 0, 16, 0}, {4}, {3}},
100	{"ME-4660s", 0x4662, {0, 0}, {32, 8, 16, 0}, {4}, {3}},
101	{"ME-4660is", 0x4663, {0, 0}, {32, 8, 16, 0}, {4}, {3}},
102
103	{"ME-4670", 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
104	{"ME-4670i", 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
105	{"ME-4670s", 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
106	{"ME-4670is", 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
107
108	{"ME-4680", 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
109	{"ME-4680i", 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
110	{"ME-4680s", 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
111	{"ME-4680is", 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
112
113	{0},
114};
115
116#define ME4000_BOARD_VERSIONS (sizeof(me4000_boards) / sizeof(me4000_board_t) - 1)
117
118/*-----------------------------------------------------------------------------
119  Comedi function prototypes
120  ---------------------------------------------------------------------------*/
121static int me4000_attach(struct comedi_device *dev, comedi_devconfig *it);
122static int me4000_detach(struct comedi_device *dev);
123static struct comedi_driver driver_me4000 = {
124      driver_name:"me4000",
125      module : THIS_MODULE,
126      attach : me4000_attach,
127      detach : me4000_detach,
128};
129
130/*-----------------------------------------------------------------------------
131  Meilhaus function prototypes
132  ---------------------------------------------------------------------------*/
133static int me4000_probe(struct comedi_device *dev, comedi_devconfig *it);
134static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p);
135static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p);
136static int init_ao_context(struct comedi_device *dev);
137static int init_ai_context(struct comedi_device *dev);
138static int init_dio_context(struct comedi_device *dev);
139static int init_cnt_context(struct comedi_device *dev);
140static int xilinx_download(struct comedi_device *dev);
141static int reset_board(struct comedi_device *dev);
142
143static int me4000_dio_insn_bits(struct comedi_device *dev,
144	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
145
146static int me4000_dio_insn_config(struct comedi_device *dev,
147	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
148
149static int cnt_reset(struct comedi_device *dev, unsigned int channel);
150
151static int cnt_config(struct comedi_device *dev,
152	unsigned int channel, unsigned int mode);
153
154static int me4000_cnt_insn_config(struct comedi_device *dev,
155	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
156
157static int me4000_cnt_insn_write(struct comedi_device *dev,
158	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
159
160static int me4000_cnt_insn_read(struct comedi_device *dev,
161	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
162
163static int me4000_ai_insn_read(struct comedi_device *dev,
164	struct comedi_subdevice *subdevice, comedi_insn *insn, unsigned int *data);
165
166static int me4000_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
167
168static int ai_check_chanlist(struct comedi_device *dev,
169	struct comedi_subdevice *s, comedi_cmd *cmd);
170
171static int ai_round_cmd_args(struct comedi_device *dev,
172	struct comedi_subdevice *s,
173	comedi_cmd *cmd,
174	unsigned int *init_ticks,
175	unsigned int *scan_ticks, unsigned int *chan_ticks);
176
177static int ai_prepare(struct comedi_device *dev,
178	struct comedi_subdevice *s,
179	comedi_cmd *cmd,
180	unsigned int init_ticks,
181	unsigned int scan_ticks, unsigned int chan_ticks);
182
183static int ai_write_chanlist(struct comedi_device *dev,
184	struct comedi_subdevice *s, comedi_cmd *cmd);
185
186static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG);
187
188static int me4000_ai_do_cmd_test(struct comedi_device *dev,
189	struct comedi_subdevice *s, comedi_cmd *cmd);
190
191static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
192
193static int me4000_ao_insn_write(struct comedi_device *dev,
194	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
195
196static int me4000_ao_insn_read(struct comedi_device *dev,
197	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
198
199/*-----------------------------------------------------------------------------
200  Meilhaus inline functions
201  ---------------------------------------------------------------------------*/
202
203static inline void me4000_outb(struct comedi_device *dev, unsigned char value,
204	unsigned long port)
205{
206	PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
207	outb(value, port);
208}
209
210static inline void me4000_outl(struct comedi_device *dev, unsigned long value,
211	unsigned long port)
212{
213	PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
214	outl(value, port);
215}
216
217static inline unsigned long me4000_inl(struct comedi_device *dev, unsigned long port)
218{
219	unsigned long value;
220	value = inl(port);
221	PORT_PDEBUG("<-- 0x%08lX port 0x%04lX\n", value, port);
222	return value;
223}
224
225static inline unsigned char me4000_inb(struct comedi_device *dev, unsigned long port)
226{
227	unsigned char value;
228	value = inb(port);
229	PORT_PDEBUG("<-- 0x%08X port 0x%04lX\n", value, port);
230	return value;
231}
232
233static const struct comedi_lrange me4000_ai_range = {
234	4,
235	{
236			UNI_RANGE(2.5),
237			UNI_RANGE(10),
238			BIP_RANGE(2.5),
239			BIP_RANGE(10),
240		}
241};
242
243static const struct comedi_lrange me4000_ao_range = {
244	1,
245	{
246			BIP_RANGE(10),
247		}
248};
249
250static int me4000_attach(struct comedi_device *dev, comedi_devconfig *it)
251{
252	struct comedi_subdevice *s;
253	int result;
254
255	CALL_PDEBUG("In me4000_attach()\n");
256
257	result = me4000_probe(dev, it);
258	if (result)
259		return result;
260
261	/*
262	 * Allocate the subdevice structures.  alloc_subdevice() is a
263	 * convenient macro defined in comedidev.h.  It relies on
264	 * n_subdevices being set correctly.
265	 */
266	if (alloc_subdevices(dev, 4) < 0)
267		return -ENOMEM;
268
269    /*=========================================================================
270      Analog input subdevice
271      ========================================================================*/
272
273	s = dev->subdevices + 0;
274
275	if (thisboard->ai.count) {
276		s->type = COMEDI_SUBD_AI;
277		s->subdev_flags =
278			SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
279		s->n_chan = thisboard->ai.count;
280		s->maxdata = 0xFFFF;	/*  16 bit ADC */
281		s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
282		s->range_table = &me4000_ai_range;
283		s->insn_read = me4000_ai_insn_read;
284
285		if (info->irq > 0) {
286			if (comedi_request_irq(info->irq, me4000_ai_isr,
287					IRQF_SHARED, "ME-4000", dev)) {
288				printk("comedi%d: me4000: me4000_attach(): Unable to allocate irq\n", dev->minor);
289			} else {
290				dev->read_subdev = s;
291				s->subdev_flags |= SDF_CMD_READ;
292				s->cancel = me4000_ai_cancel;
293				s->do_cmdtest = me4000_ai_do_cmd_test;
294				s->do_cmd = me4000_ai_do_cmd;
295			}
296		} else {
297			printk(KERN_WARNING
298				"comedi%d: me4000: me4000_attach(): No interrupt available\n",
299				dev->minor);
300		}
301	} else {
302		s->type = COMEDI_SUBD_UNUSED;
303	}
304
305    /*=========================================================================
306      Analog output subdevice
307      ========================================================================*/
308
309	s = dev->subdevices + 1;
310
311	if (thisboard->ao.count) {
312		s->type = COMEDI_SUBD_AO;
313		s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
314		s->n_chan = thisboard->ao.count;
315		s->maxdata = 0xFFFF;	/*  16 bit DAC */
316		s->range_table = &me4000_ao_range;
317		s->insn_write = me4000_ao_insn_write;
318		s->insn_read = me4000_ao_insn_read;
319	} else {
320		s->type = COMEDI_SUBD_UNUSED;
321	}
322
323    /*=========================================================================
324      Digital I/O subdevice
325      ========================================================================*/
326
327	s = dev->subdevices + 2;
328
329	if (thisboard->dio.count) {
330		s->type = COMEDI_SUBD_DIO;
331		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
332		s->n_chan = thisboard->dio.count * 8;
333		s->maxdata = 1;
334		s->range_table = &range_digital;
335		s->insn_bits = me4000_dio_insn_bits;
336		s->insn_config = me4000_dio_insn_config;
337	} else {
338		s->type = COMEDI_SUBD_UNUSED;
339	}
340
341	/*
342	 * Check for optoisolated ME-4000 version. If one the first
343	 * port is a fixed output port and the second is a fixed input port.
344	 */
345	if (!me4000_inl(dev, info->dio_context.dir_reg)) {
346		s->io_bits |= 0xFF;
347		me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0,
348			info->dio_context.dir_reg);
349	}
350
351    /*=========================================================================
352      Counter subdevice
353      ========================================================================*/
354
355	s = dev->subdevices + 3;
356
357	if (thisboard->cnt.count) {
358		s->type = COMEDI_SUBD_COUNTER;
359		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
360		s->n_chan = thisboard->cnt.count;
361		s->maxdata = 0xFFFF;	/*  16 bit counters */
362		s->insn_read = me4000_cnt_insn_read;
363		s->insn_write = me4000_cnt_insn_write;
364		s->insn_config = me4000_cnt_insn_config;
365	} else {
366		s->type = COMEDI_SUBD_UNUSED;
367	}
368
369	return 0;
370}
371
372static int me4000_probe(struct comedi_device *dev, comedi_devconfig *it)
373{
374	struct pci_dev *pci_device;
375	int result, i;
376	me4000_board_t *board;
377
378	CALL_PDEBUG("In me4000_probe()\n");
379
380	/* Allocate private memory */
381	if (alloc_private(dev, sizeof(me4000_info_t)) < 0)
382		return -ENOMEM;
383
384	/*
385	 * Probe the device to determine what device in the series it is.
386	 */
387	for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
388		pci_device != NULL;
389		pci_device =
390		pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
391		if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) {
392			for (i = 0; i < ME4000_BOARD_VERSIONS; i++) {
393				if (me4000_boards[i].device_id ==
394					pci_device->device) {
395					/* Was a particular bus/slot requested? */
396					if ((it->options[0] != 0)
397						|| (it->options[1] != 0)) {
398						/* Are we on the wrong bus/slot? */
399						if (pci_device->bus->number !=
400							it->options[0]
401							|| PCI_SLOT(pci_device->
402								devfn) !=
403							it->options[1]) {
404							continue;
405						}
406					}
407					dev->board_ptr = me4000_boards + i;
408					board = (me4000_board_t *) dev->
409						board_ptr;
410					info->pci_dev_p = pci_device;
411					goto found;
412				}
413			}
414		}
415	}
416
417	printk(KERN_ERR
418		"comedi%d: me4000: me4000_probe(): No supported board found (req. bus/slot : %d/%d)\n",
419		dev->minor, it->options[0], it->options[1]);
420	return -ENODEV;
421
422      found:
423
424	printk(KERN_INFO
425		"comedi%d: me4000: me4000_probe(): Found %s at PCI bus %d, slot %d\n",
426		dev->minor, me4000_boards[i].name, pci_device->bus->number,
427		PCI_SLOT(pci_device->devfn));
428
429	/* Set data in device structure */
430	dev->board_name = board->name;
431
432	/* Enable PCI device and request regions */
433	result = comedi_pci_enable(pci_device, dev->board_name);
434	if (result) {
435		printk(KERN_ERR
436			"comedi%d: me4000: me4000_probe(): Cannot enable PCI device and request I/O regions\n",
437			dev->minor);
438		return result;
439	}
440
441	/* Get the PCI base registers */
442	result = get_registers(dev, pci_device);
443	if (result) {
444		printk(KERN_ERR
445			"comedi%d: me4000: me4000_probe(): Cannot get registers\n",
446			dev->minor);
447		return result;
448	}
449	/* Initialize board info */
450	result = init_board_info(dev, pci_device);
451	if (result) {
452		printk(KERN_ERR
453			"comedi%d: me4000: me4000_probe(): Cannot init baord info\n",
454			dev->minor);
455		return result;
456	}
457
458	/* Init analog output context */
459	result = init_ao_context(dev);
460	if (result) {
461		printk(KERN_ERR
462			"comedi%d: me4000: me4000_probe(): Cannot init ao context\n",
463			dev->minor);
464		return result;
465	}
466
467	/* Init analog input context */
468	result = init_ai_context(dev);
469	if (result) {
470		printk(KERN_ERR
471			"comedi%d: me4000: me4000_probe(): Cannot init ai context\n",
472			dev->minor);
473		return result;
474	}
475
476	/* Init digital I/O context */
477	result = init_dio_context(dev);
478	if (result) {
479		printk(KERN_ERR
480			"comedi%d: me4000: me4000_probe(): Cannot init dio context\n",
481			dev->minor);
482		return result;
483	}
484
485	/* Init counter context */
486	result = init_cnt_context(dev);
487	if (result) {
488		printk(KERN_ERR
489			"comedi%d: me4000: me4000_probe(): Cannot init cnt context\n",
490			dev->minor);
491		return result;
492	}
493
494	/* Download the xilinx firmware */
495	result = xilinx_download(dev);
496	if (result) {
497		printk(KERN_ERR
498			"comedi%d: me4000: me4000_probe(): Can't download firmware\n",
499			dev->minor);
500		return result;
501	}
502
503	/* Make a hardware reset */
504	result = reset_board(dev);
505	if (result) {
506		printk(KERN_ERR
507			"comedi%d: me4000: me4000_probe(): Can't reset board\n",
508			dev->minor);
509		return result;
510	}
511
512	return 0;
513}
514
515static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p)
516{
517
518	CALL_PDEBUG("In get_registers()\n");
519
520    /*--------------------------- plx regbase ---------------------------------*/
521
522	info->plx_regbase = pci_resource_start(pci_dev_p, 1);
523	if (info->plx_regbase == 0) {
524		printk(KERN_ERR
525			"comedi%d: me4000: get_registers(): PCI base address 1 is not available\n",
526			dev->minor);
527		return -ENODEV;
528	}
529	info->plx_regbase_size = pci_resource_len(pci_dev_p, 1);
530
531    /*--------------------------- me4000 regbase ------------------------------*/
532
533	info->me4000_regbase = pci_resource_start(pci_dev_p, 2);
534	if (info->me4000_regbase == 0) {
535		printk(KERN_ERR
536			"comedi%d: me4000: get_registers(): PCI base address 2 is not available\n",
537			dev->minor);
538		return -ENODEV;
539	}
540	info->me4000_regbase_size = pci_resource_len(pci_dev_p, 2);
541
542    /*--------------------------- timer regbase ------------------------------*/
543
544	info->timer_regbase = pci_resource_start(pci_dev_p, 3);
545	if (info->timer_regbase == 0) {
546		printk(KERN_ERR
547			"comedi%d: me4000: get_registers(): PCI base address 3 is not available\n",
548			dev->minor);
549		return -ENODEV;
550	}
551	info->timer_regbase_size = pci_resource_len(pci_dev_p, 3);
552
553    /*--------------------------- program regbase ------------------------------*/
554
555	info->program_regbase = pci_resource_start(pci_dev_p, 5);
556	if (info->program_regbase == 0) {
557		printk(KERN_ERR
558			"comedi%d: me4000: get_registers(): PCI base address 5 is not available\n",
559			dev->minor);
560		return -ENODEV;
561	}
562	info->program_regbase_size = pci_resource_len(pci_dev_p, 5);
563
564	return 0;
565}
566
567static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p)
568{
569	int result;
570
571	CALL_PDEBUG("In init_board_info()\n");
572
573	/* Init spin locks */
574	/* spin_lock_init(&info->preload_lock); */
575	/* spin_lock_init(&info->ai_ctrl_lock); */
576
577	/* Get the serial number */
578	result = pci_read_config_dword(pci_dev_p, 0x2C, &info->serial_no);
579	if (result != PCIBIOS_SUCCESSFUL)
580		return result;
581
582	/* Get the hardware revision */
583	result = pci_read_config_byte(pci_dev_p, 0x08, &info->hw_revision);
584	if (result != PCIBIOS_SUCCESSFUL)
585		return result;
586
587	/* Get the vendor id */
588	info->vendor_id = pci_dev_p->vendor;
589
590	/* Get the device id */
591	info->device_id = pci_dev_p->device;
592
593	/* Get the irq assigned to the board */
594	info->irq = pci_dev_p->irq;
595
596	return 0;
597}
598
599static int init_ao_context(struct comedi_device *dev)
600{
601	int i;
602
603	CALL_PDEBUG("In init_ao_context()\n");
604
605	for (i = 0; i < thisboard->ao.count; i++) {
606		/* spin_lock_init(&info->ao_context[i].use_lock); */
607		info->ao_context[i].irq = info->irq;
608
609		switch (i) {
610		case 0:
611			info->ao_context[i].ctrl_reg =
612				info->me4000_regbase + ME4000_AO_00_CTRL_REG;
613			info->ao_context[i].status_reg =
614				info->me4000_regbase + ME4000_AO_00_STATUS_REG;
615			info->ao_context[i].fifo_reg =
616				info->me4000_regbase + ME4000_AO_00_FIFO_REG;
617			info->ao_context[i].single_reg =
618				info->me4000_regbase + ME4000_AO_00_SINGLE_REG;
619			info->ao_context[i].timer_reg =
620				info->me4000_regbase + ME4000_AO_00_TIMER_REG;
621			info->ao_context[i].irq_status_reg =
622				info->me4000_regbase + ME4000_IRQ_STATUS_REG;
623			info->ao_context[i].preload_reg =
624				info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
625			break;
626		case 1:
627			info->ao_context[i].ctrl_reg =
628				info->me4000_regbase + ME4000_AO_01_CTRL_REG;
629			info->ao_context[i].status_reg =
630				info->me4000_regbase + ME4000_AO_01_STATUS_REG;
631			info->ao_context[i].fifo_reg =
632				info->me4000_regbase + ME4000_AO_01_FIFO_REG;
633			info->ao_context[i].single_reg =
634				info->me4000_regbase + ME4000_AO_01_SINGLE_REG;
635			info->ao_context[i].timer_reg =
636				info->me4000_regbase + ME4000_AO_01_TIMER_REG;
637			info->ao_context[i].irq_status_reg =
638				info->me4000_regbase + ME4000_IRQ_STATUS_REG;
639			info->ao_context[i].preload_reg =
640				info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
641			break;
642		case 2:
643			info->ao_context[i].ctrl_reg =
644				info->me4000_regbase + ME4000_AO_02_CTRL_REG;
645			info->ao_context[i].status_reg =
646				info->me4000_regbase + ME4000_AO_02_STATUS_REG;
647			info->ao_context[i].fifo_reg =
648				info->me4000_regbase + ME4000_AO_02_FIFO_REG;
649			info->ao_context[i].single_reg =
650				info->me4000_regbase + ME4000_AO_02_SINGLE_REG;
651			info->ao_context[i].timer_reg =
652				info->me4000_regbase + ME4000_AO_02_TIMER_REG;
653			info->ao_context[i].irq_status_reg =
654				info->me4000_regbase + ME4000_IRQ_STATUS_REG;
655			info->ao_context[i].preload_reg =
656				info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
657			break;
658		case 3:
659			info->ao_context[i].ctrl_reg =
660				info->me4000_regbase + ME4000_AO_03_CTRL_REG;
661			info->ao_context[i].status_reg =
662				info->me4000_regbase + ME4000_AO_03_STATUS_REG;
663			info->ao_context[i].fifo_reg =
664				info->me4000_regbase + ME4000_AO_03_FIFO_REG;
665			info->ao_context[i].single_reg =
666				info->me4000_regbase + ME4000_AO_03_SINGLE_REG;
667			info->ao_context[i].timer_reg =
668				info->me4000_regbase + ME4000_AO_03_TIMER_REG;
669			info->ao_context[i].irq_status_reg =
670				info->me4000_regbase + ME4000_IRQ_STATUS_REG;
671			info->ao_context[i].preload_reg =
672				info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
673			break;
674		default:
675			break;
676		}
677	}
678
679	return 0;
680}
681
682static int init_ai_context(struct comedi_device *dev)
683{
684
685	CALL_PDEBUG("In init_ai_context()\n");
686
687	info->ai_context.irq = info->irq;
688
689	info->ai_context.ctrl_reg = info->me4000_regbase + ME4000_AI_CTRL_REG;
690	info->ai_context.status_reg =
691		info->me4000_regbase + ME4000_AI_STATUS_REG;
692	info->ai_context.channel_list_reg =
693		info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG;
694	info->ai_context.data_reg = info->me4000_regbase + ME4000_AI_DATA_REG;
695	info->ai_context.chan_timer_reg =
696		info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG;
697	info->ai_context.chan_pre_timer_reg =
698		info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG;
699	info->ai_context.scan_timer_low_reg =
700		info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG;
701	info->ai_context.scan_timer_high_reg =
702		info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG;
703	info->ai_context.scan_pre_timer_low_reg =
704		info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG;
705	info->ai_context.scan_pre_timer_high_reg =
706		info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG;
707	info->ai_context.start_reg = info->me4000_regbase + ME4000_AI_START_REG;
708	info->ai_context.irq_status_reg =
709		info->me4000_regbase + ME4000_IRQ_STATUS_REG;
710	info->ai_context.sample_counter_reg =
711		info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG;
712
713	return 0;
714}
715
716static int init_dio_context(struct comedi_device *dev)
717{
718
719	CALL_PDEBUG("In init_dio_context()\n");
720
721	info->dio_context.dir_reg = info->me4000_regbase + ME4000_DIO_DIR_REG;
722	info->dio_context.ctrl_reg = info->me4000_regbase + ME4000_DIO_CTRL_REG;
723	info->dio_context.port_0_reg =
724		info->me4000_regbase + ME4000_DIO_PORT_0_REG;
725	info->dio_context.port_1_reg =
726		info->me4000_regbase + ME4000_DIO_PORT_1_REG;
727	info->dio_context.port_2_reg =
728		info->me4000_regbase + ME4000_DIO_PORT_2_REG;
729	info->dio_context.port_3_reg =
730		info->me4000_regbase + ME4000_DIO_PORT_3_REG;
731
732	return 0;
733}
734
735static int init_cnt_context(struct comedi_device *dev)
736{
737
738	CALL_PDEBUG("In init_cnt_context()\n");
739
740	info->cnt_context.ctrl_reg = info->timer_regbase + ME4000_CNT_CTRL_REG;
741	info->cnt_context.counter_0_reg =
742		info->timer_regbase + ME4000_CNT_COUNTER_0_REG;
743	info->cnt_context.counter_1_reg =
744		info->timer_regbase + ME4000_CNT_COUNTER_1_REG;
745	info->cnt_context.counter_2_reg =
746		info->timer_regbase + ME4000_CNT_COUNTER_2_REG;
747
748	return 0;
749}
750
751#define FIRMWARE_NOT_AVAILABLE 1
752#if FIRMWARE_NOT_AVAILABLE
753extern unsigned char *xilinx_firm;
754#endif
755
756static int xilinx_download(struct comedi_device *dev)
757{
758	u32 value = 0;
759	wait_queue_head_t queue;
760	int idx = 0;
761	int size = 0;
762
763	CALL_PDEBUG("In xilinx_download()\n");
764
765	init_waitqueue_head(&queue);
766
767	/*
768	 * Set PLX local interrupt 2 polarity to high.
769	 * Interrupt is thrown by init pin of xilinx.
770	 */
771	outl(0x10, info->plx_regbase + PLX_INTCSR);
772
773	/* Set /CS and /WRITE of the Xilinx */
774	value = inl(info->plx_regbase + PLX_ICR);
775	value |= 0x100;
776	outl(value, info->plx_regbase + PLX_ICR);
777
778	/* Init Xilinx with CS1 */
779	inb(info->program_regbase + 0xC8);
780
781	/* Wait until /INIT pin is set */
782	udelay(20);
783	if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) {
784		printk(KERN_ERR
785			"comedi%d: me4000: xilinx_download(): Can't init Xilinx\n",
786			dev->minor);
787		return -EIO;
788	}
789
790	/* Reset /CS and /WRITE of the Xilinx */
791	value = inl(info->plx_regbase + PLX_ICR);
792	value &= ~0x100;
793	outl(value, info->plx_regbase + PLX_ICR);
794	if (FIRMWARE_NOT_AVAILABLE) {
795		comedi_error(dev,
796			"xilinx firmware unavailable due to licensing, aborting");
797		return -EIO;
798	} else {
799		/* Download Xilinx firmware */
800		size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) +
801			(xilinx_firm[2] << 8) + xilinx_firm[3];
802		udelay(10);
803
804		for (idx = 0; idx < size; idx++) {
805			outb(xilinx_firm[16 + idx], info->program_regbase);
806			udelay(10);
807
808			/* Check if BUSY flag is low */
809			if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
810				printk(KERN_ERR
811					"comedi%d: me4000: xilinx_download(): Xilinx is still busy (idx = %d)\n",
812					dev->minor, idx);
813				return -EIO;
814			}
815		}
816	}
817
818	/* If done flag is high download was successful */
819	if (inl(info->plx_regbase + PLX_ICR) & 0x4) {
820	} else {
821		printk(KERN_ERR
822			"comedi%d: me4000: xilinx_download(): DONE flag is not set\n",
823			dev->minor);
824		printk(KERN_ERR
825			"comedi%d: me4000: xilinx_download(): Download not succesful\n",
826			dev->minor);
827		return -EIO;
828	}
829
830	/* Set /CS and /WRITE */
831	value = inl(info->plx_regbase + PLX_ICR);
832	value |= 0x100;
833	outl(value, info->plx_regbase + PLX_ICR);
834
835	return 0;
836}
837
838static int reset_board(struct comedi_device *dev)
839{
840	unsigned long icr;
841
842	CALL_PDEBUG("In reset_board()\n");
843
844	/* Make a hardware reset */
845	icr = me4000_inl(dev, info->plx_regbase + PLX_ICR);
846	icr |= 0x40000000;
847	me4000_outl(dev, icr, info->plx_regbase + PLX_ICR);
848	icr &= ~0x40000000;
849	me4000_outl(dev, icr, info->plx_regbase + PLX_ICR);
850
851	/* 0x8000 to the DACs means an output voltage of 0V */
852	me4000_outl(dev, 0x8000,
853		info->me4000_regbase + ME4000_AO_00_SINGLE_REG);
854	me4000_outl(dev, 0x8000,
855		info->me4000_regbase + ME4000_AO_01_SINGLE_REG);
856	me4000_outl(dev, 0x8000,
857		info->me4000_regbase + ME4000_AO_02_SINGLE_REG);
858	me4000_outl(dev, 0x8000,
859		info->me4000_regbase + ME4000_AO_03_SINGLE_REG);
860
861	/* Set both stop bits in the analog input control register */
862	me4000_outl(dev,
863		ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
864		info->me4000_regbase + ME4000_AI_CTRL_REG);
865
866	/* Set both stop bits in the analog output control register */
867	me4000_outl(dev,
868		ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
869		info->me4000_regbase + ME4000_AO_00_CTRL_REG);
870	me4000_outl(dev,
871		ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
872		info->me4000_regbase + ME4000_AO_01_CTRL_REG);
873	me4000_outl(dev,
874		ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
875		info->me4000_regbase + ME4000_AO_02_CTRL_REG);
876	me4000_outl(dev,
877		ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
878		info->me4000_regbase + ME4000_AO_03_CTRL_REG);
879
880	/* Enable interrupts on the PLX */
881	me4000_outl(dev, 0x43, info->plx_regbase + PLX_INTCSR);
882
883	/* Set the adustment register for AO demux */
884	me4000_outl(dev, ME4000_AO_DEMUX_ADJUST_VALUE,
885		info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
886
887	/* Set digital I/O direction for port 0 to output on isolated versions */
888	if (!(me4000_inl(dev, info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) {
889		me4000_outl(dev, 0x1,
890			info->me4000_regbase + ME4000_DIO_CTRL_REG);
891	}
892
893	return 0;
894}
895
896static int me4000_detach(struct comedi_device *dev)
897{
898	CALL_PDEBUG("In me4000_detach()\n");
899
900	if (info) {
901		if (info->pci_dev_p) {
902			reset_board(dev);
903			if (info->plx_regbase)
904				comedi_pci_disable(info->pci_dev_p);
905			pci_dev_put(info->pci_dev_p);
906		}
907	}
908
909	return 0;
910}
911
912/*=============================================================================
913  Analog input section
914  ===========================================================================*/
915
916static int me4000_ai_insn_read(struct comedi_device *dev,
917	struct comedi_subdevice *subdevice, comedi_insn *insn, unsigned int *data)
918{
919
920	int chan = CR_CHAN(insn->chanspec);
921	int rang = CR_RANGE(insn->chanspec);
922	int aref = CR_AREF(insn->chanspec);
923
924	unsigned long entry = 0;
925	unsigned long tmp;
926	long lval;
927
928	CALL_PDEBUG("In me4000_ai_insn_read()\n");
929
930	if (insn->n == 0) {
931		return 0;
932	} else if (insn->n > 1) {
933		printk(KERN_ERR
934			"comedi%d: me4000: me4000_ai_insn_read(): Invalid instruction length %d\n",
935			dev->minor, insn->n);
936		return -EINVAL;
937	}
938
939	switch (rang) {
940	case 0:
941		entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
942		break;
943	case 1:
944		entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
945		break;
946	case 2:
947		entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
948		break;
949	case 3:
950		entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
951		break;
952	default:
953		printk(KERN_ERR
954			"comedi%d: me4000: me4000_ai_insn_read(): Invalid range specified\n",
955			dev->minor);
956		return -EINVAL;
957	}
958
959	switch (aref) {
960	case AREF_GROUND:
961	case AREF_COMMON:
962		if (chan >= thisboard->ai.count) {
963			printk(KERN_ERR
964				"comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
965				dev->minor);
966			return -EINVAL;
967		}
968		entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
969		break;
970
971	case AREF_DIFF:
972		if (rang == 0 || rang == 1) {
973			printk(KERN_ERR
974				"comedi%d: me4000: me4000_ai_insn_read(): Range must be bipolar when aref = diff\n",
975				dev->minor);
976			return -EINVAL;
977		}
978
979		if (chan >= thisboard->ai.diff_count) {
980			printk(KERN_ERR
981				"comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
982				dev->minor);
983			return -EINVAL;
984		}
985		entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
986		break;
987	default:
988		printk(KERN_ERR
989			"comedi%d: me4000: me4000_ai_insn_read(): Invalid aref specified\n",
990			dev->minor);
991		return -EINVAL;
992	}
993
994	entry |= ME4000_AI_LIST_LAST_ENTRY;
995
996	/* Clear channel list, data fifo and both stop bits */
997	tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
998	tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
999		ME4000_AI_CTRL_BIT_DATA_FIFO |
1000		ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
1001	me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1002
1003	/* Set the acquisition mode to single */
1004	tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 |
1005		ME4000_AI_CTRL_BIT_MODE_2);
1006	me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1007
1008	/* Enable channel list and data fifo */
1009	tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
1010	me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1011
1012	/* Generate channel list entry */
1013	me4000_outl(dev, entry, info->ai_context.channel_list_reg);
1014
1015	/* Set the timer to maximum sample rate */
1016	me4000_outl(dev, ME4000_AI_MIN_TICKS, info->ai_context.chan_timer_reg);
1017	me4000_outl(dev, ME4000_AI_MIN_TICKS,
1018		info->ai_context.chan_pre_timer_reg);
1019
1020	/* Start conversion by dummy read */
1021	me4000_inl(dev, info->ai_context.start_reg);
1022
1023	/* Wait until ready */
1024	udelay(10);
1025	if (!(me4000_inl(dev, info->ai_context.
1026				status_reg) & ME4000_AI_STATUS_BIT_EF_DATA)) {
1027		printk(KERN_ERR
1028			"comedi%d: me4000: me4000_ai_insn_read(): Value not available after wait\n",
1029			dev->minor);
1030		return -EIO;
1031	}
1032
1033	/* Read value from data fifo */
1034	lval = me4000_inl(dev, info->ai_context.data_reg) & 0xFFFF;
1035	data[0] = lval ^ 0x8000;
1036
1037	return 1;
1038}
1039
1040static int me4000_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1041{
1042	unsigned long tmp;
1043
1044	CALL_PDEBUG("In me4000_ai_cancel()\n");
1045
1046	/* Stop any running conversion */
1047	tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
1048	tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
1049	me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1050
1051	/* Clear the control register */
1052	me4000_outl(dev, 0x0, info->ai_context.ctrl_reg);
1053
1054	return 0;
1055}
1056
1057static int ai_check_chanlist(struct comedi_device *dev,
1058	struct comedi_subdevice *s, comedi_cmd *cmd)
1059{
1060	int aref;
1061	int i;
1062
1063	CALL_PDEBUG("In ai_check_chanlist()\n");
1064
1065	/* Check whether a channel list is available */
1066	if (!cmd->chanlist_len) {
1067		printk(KERN_ERR
1068			"comedi%d: me4000: ai_check_chanlist(): No channel list available\n",
1069			dev->minor);
1070		return -EINVAL;
1071	}
1072
1073	/* Check the channel list size */
1074	if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) {
1075		printk(KERN_ERR
1076			"comedi%d: me4000: ai_check_chanlist(): Channel list is to large\n",
1077			dev->minor);
1078		return -EINVAL;
1079	}
1080
1081	/* Check the pointer */
1082	if (!cmd->chanlist) {
1083		printk(KERN_ERR
1084			"comedi%d: me4000: ai_check_chanlist(): NULL pointer to channel list\n",
1085			dev->minor);
1086		return -EFAULT;
1087	}
1088
1089	/* Check whether aref is equal for all entries */
1090	aref = CR_AREF(cmd->chanlist[0]);
1091	for (i = 0; i < cmd->chanlist_len; i++) {
1092		if (CR_AREF(cmd->chanlist[i]) != aref) {
1093			printk(KERN_ERR
1094				"comedi%d: me4000: ai_check_chanlist(): Mode is not equal for all entries\n",
1095				dev->minor);
1096			return -EINVAL;
1097		}
1098	}
1099
1100	/* Check whether channels are available for this ending */
1101	if (aref == SDF_DIFF) {
1102		for (i = 0; i < cmd->chanlist_len; i++) {
1103			if (CR_CHAN(cmd->chanlist[i]) >=
1104				thisboard->ai.diff_count) {
1105				printk(KERN_ERR
1106					"comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
1107					dev->minor);
1108				return -EINVAL;
1109			}
1110		}
1111	} else {
1112		for (i = 0; i < cmd->chanlist_len; i++) {
1113			if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai.count) {
1114				printk(KERN_ERR
1115					"comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
1116					dev->minor);
1117				return -EINVAL;
1118			}
1119		}
1120	}
1121
1122	/* Check if bipolar is set for all entries when in differential mode */
1123	if (aref == SDF_DIFF) {
1124		for (i = 0; i < cmd->chanlist_len; i++) {
1125			if (CR_RANGE(cmd->chanlist[i]) != 1 &&
1126				CR_RANGE(cmd->chanlist[i]) != 2) {
1127				printk(KERN_ERR
1128					"comedi%d: me4000: ai_check_chanlist(): Bipolar is not selected in differential mode\n",
1129					dev->minor);
1130				return -EINVAL;
1131			}
1132		}
1133	}
1134
1135	return 0;
1136}
1137
1138static int ai_round_cmd_args(struct comedi_device *dev,
1139	struct comedi_subdevice *s,
1140	comedi_cmd *cmd,
1141	unsigned int *init_ticks,
1142	unsigned int *scan_ticks, unsigned int *chan_ticks)
1143{
1144
1145	int rest;
1146
1147	CALL_PDEBUG("In ai_round_cmd_args()\n");
1148
1149	*init_ticks = 0;
1150	*scan_ticks = 0;
1151	*chan_ticks = 0;
1152
1153	PDEBUG("ai_round_cmd_arg(): start_arg = %d\n", cmd->start_arg);
1154	PDEBUG("ai_round_cmd_arg(): scan_begin_arg = %d\n",
1155		cmd->scan_begin_arg);
1156	PDEBUG("ai_round_cmd_arg(): convert_arg = %d\n", cmd->convert_arg);
1157
1158	if (cmd->start_arg) {
1159		*init_ticks = (cmd->start_arg * 33) / 1000;
1160		rest = (cmd->start_arg * 33) % 1000;
1161
1162		if (cmd->flags & TRIG_ROUND_NEAREST) {
1163			if (rest > 33)
1164				(*init_ticks)++;
1165		} else if (cmd->flags & TRIG_ROUND_UP) {
1166			if (rest)
1167				(*init_ticks)++;
1168		}
1169	}
1170
1171	if (cmd->scan_begin_arg) {
1172		*scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
1173		rest = (cmd->scan_begin_arg * 33) % 1000;
1174
1175		if (cmd->flags & TRIG_ROUND_NEAREST) {
1176			if (rest > 33)
1177				(*scan_ticks)++;
1178		} else if (cmd->flags & TRIG_ROUND_UP) {
1179			if (rest)
1180				(*scan_ticks)++;
1181		}
1182	}
1183
1184	if (cmd->convert_arg) {
1185		*chan_ticks = (cmd->convert_arg * 33) / 1000;
1186		rest = (cmd->convert_arg * 33) % 1000;
1187
1188		if (cmd->flags & TRIG_ROUND_NEAREST) {
1189			if (rest > 33)
1190				(*chan_ticks)++;
1191		} else if (cmd->flags & TRIG_ROUND_UP) {
1192			if (rest)
1193				(*chan_ticks)++;
1194		}
1195	}
1196
1197	PDEBUG("ai_round_cmd_args(): init_ticks = %d\n", *init_ticks);
1198	PDEBUG("ai_round_cmd_args(): scan_ticks = %d\n", *scan_ticks);
1199	PDEBUG("ai_round_cmd_args(): chan_ticks = %d\n", *chan_ticks);
1200
1201	return 0;
1202}
1203
1204static void ai_write_timer(struct comedi_device *dev,
1205	unsigned int init_ticks,
1206	unsigned int scan_ticks, unsigned int chan_ticks)
1207{
1208
1209	CALL_PDEBUG("In ai_write_timer()\n");
1210
1211	me4000_outl(dev, init_ticks - 1,
1212		info->ai_context.scan_pre_timer_low_reg);
1213	me4000_outl(dev, 0x0, info->ai_context.scan_pre_timer_high_reg);
1214
1215	if (scan_ticks) {
1216		me4000_outl(dev, scan_ticks - 1,
1217			info->ai_context.scan_timer_low_reg);
1218		me4000_outl(dev, 0x0, info->ai_context.scan_timer_high_reg);
1219	}
1220
1221	me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_pre_timer_reg);
1222	me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_timer_reg);
1223}
1224
1225static int ai_prepare(struct comedi_device *dev,
1226	struct comedi_subdevice *s,
1227	comedi_cmd *cmd,
1228	unsigned int init_ticks,
1229	unsigned int scan_ticks, unsigned int chan_ticks)
1230{
1231
1232	unsigned long tmp = 0;
1233
1234	CALL_PDEBUG("In ai_prepare()\n");
1235
1236	/* Write timer arguments */
1237	ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
1238
1239	/* Reset control register */
1240	me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1241
1242	/* Start sources */
1243	if ((cmd->start_src == TRIG_EXT &&
1244			cmd->scan_begin_src == TRIG_TIMER &&
1245			cmd->convert_src == TRIG_TIMER) ||
1246		(cmd->start_src == TRIG_EXT &&
1247			cmd->scan_begin_src == TRIG_FOLLOW &&
1248			cmd->convert_src == TRIG_TIMER)) {
1249		tmp = ME4000_AI_CTRL_BIT_MODE_1 |
1250			ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1251			ME4000_AI_CTRL_BIT_DATA_FIFO;
1252	} else if (cmd->start_src == TRIG_EXT &&
1253		cmd->scan_begin_src == TRIG_EXT &&
1254		cmd->convert_src == TRIG_TIMER) {
1255		tmp = ME4000_AI_CTRL_BIT_MODE_2 |
1256			ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1257			ME4000_AI_CTRL_BIT_DATA_FIFO;
1258	} else if (cmd->start_src == TRIG_EXT &&
1259		cmd->scan_begin_src == TRIG_EXT &&
1260		cmd->convert_src == TRIG_EXT) {
1261		tmp = ME4000_AI_CTRL_BIT_MODE_0 |
1262			ME4000_AI_CTRL_BIT_MODE_1 |
1263			ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1264			ME4000_AI_CTRL_BIT_DATA_FIFO;
1265	} else {
1266		tmp = ME4000_AI_CTRL_BIT_MODE_0 |
1267			ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1268			ME4000_AI_CTRL_BIT_DATA_FIFO;
1269	}
1270
1271	/* Stop triggers */
1272	if (cmd->stop_src == TRIG_COUNT) {
1273		me4000_outl(dev, cmd->chanlist_len * cmd->stop_arg,
1274			info->ai_context.sample_counter_reg);
1275		tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
1276	} else if (cmd->stop_src == TRIG_NONE &&
1277		cmd->scan_end_src == TRIG_COUNT) {
1278		me4000_outl(dev, cmd->scan_end_arg,
1279			info->ai_context.sample_counter_reg);
1280		tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
1281	} else {
1282		tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
1283	}
1284
1285	/* Write the setup to the control register */
1286	me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1287
1288	/* Write the channel list */
1289	ai_write_chanlist(dev, s, cmd);
1290
1291	return 0;
1292}
1293
1294static int ai_write_chanlist(struct comedi_device *dev,
1295	struct comedi_subdevice *s, comedi_cmd *cmd)
1296{
1297	unsigned int entry;
1298	unsigned int chan;
1299	unsigned int rang;
1300	unsigned int aref;
1301	int i;
1302
1303	CALL_PDEBUG("In ai_write_chanlist()\n");
1304
1305	for (i = 0; i < cmd->chanlist_len; i++) {
1306		chan = CR_CHAN(cmd->chanlist[i]);
1307		rang = CR_RANGE(cmd->chanlist[i]);
1308		aref = CR_AREF(cmd->chanlist[i]);
1309
1310		entry = chan;
1311
1312		if (rang == 0) {
1313			entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
1314		} else if (rang == 1) {
1315			entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
1316		} else if (rang == 2) {
1317			entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
1318		} else {
1319			entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
1320		}
1321
1322		if (aref == SDF_DIFF) {
1323			entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
1324		} else {
1325			entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
1326		}
1327
1328		me4000_outl(dev, entry, info->ai_context.channel_list_reg);
1329	}
1330
1331	return 0;
1332}
1333
1334static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1335{
1336	int err;
1337	unsigned int init_ticks = 0;
1338	unsigned int scan_ticks = 0;
1339	unsigned int chan_ticks = 0;
1340	comedi_cmd *cmd = &s->async->cmd;
1341
1342	CALL_PDEBUG("In me4000_ai_do_cmd()\n");
1343
1344	/* Reset the analog input */
1345	err = me4000_ai_cancel(dev, s);
1346	if (err)
1347		return err;
1348
1349	/* Round the timer arguments */
1350	err = ai_round_cmd_args(dev,
1351		s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
1352	if (err)
1353		return err;
1354
1355	/* Prepare the AI for acquisition */
1356	err = ai_prepare(dev, s, cmd, init_ticks, scan_ticks, chan_ticks);
1357	if (err)
1358		return err;
1359
1360	/* Start acquistion by dummy read */
1361	me4000_inl(dev, info->ai_context.start_reg);
1362
1363	return 0;
1364}
1365
1366/*
1367 * me4000_ai_do_cmd_test():
1368 *
1369 * The demo cmd.c in ./comedilib/demo specifies 6 return values:
1370 * - success
1371 * - invalid source
1372 * - source conflict
1373 * - invalid argument
1374 * - argument conflict
1375 * - invalid chanlist
1376 * So I tried to adopt this scheme.
1377 */
1378static int me4000_ai_do_cmd_test(struct comedi_device *dev,
1379	struct comedi_subdevice *s, comedi_cmd *cmd)
1380{
1381
1382	unsigned int init_ticks;
1383	unsigned int chan_ticks;
1384	unsigned int scan_ticks;
1385	int err = 0;
1386
1387	CALL_PDEBUG("In me4000_ai_do_cmd_test()\n");
1388
1389	PDEBUG("me4000_ai_do_cmd_test(): subdev         = %d\n", cmd->subdev);
1390	PDEBUG("me4000_ai_do_cmd_test(): flags          = %08X\n", cmd->flags);
1391	PDEBUG("me4000_ai_do_cmd_test(): start_src      = %08X\n",
1392		cmd->start_src);
1393	PDEBUG("me4000_ai_do_cmd_test(): start_arg      = %d\n",
1394		cmd->start_arg);
1395	PDEBUG("me4000_ai_do_cmd_test(): scan_begin_src = %08X\n",
1396		cmd->scan_begin_src);
1397	PDEBUG("me4000_ai_do_cmd_test(): scan_begin_arg = %d\n",
1398		cmd->scan_begin_arg);
1399	PDEBUG("me4000_ai_do_cmd_test(): convert_src    = %08X\n",
1400		cmd->convert_src);
1401	PDEBUG("me4000_ai_do_cmd_test(): convert_arg    = %d\n",
1402		cmd->convert_arg);
1403	PDEBUG("me4000_ai_do_cmd_test(): scan_end_src   = %08X\n",
1404		cmd->scan_end_src);
1405	PDEBUG("me4000_ai_do_cmd_test(): scan_end_arg   = %d\n",
1406		cmd->scan_end_arg);
1407	PDEBUG("me4000_ai_do_cmd_test(): stop_src       = %08X\n",
1408		cmd->stop_src);
1409	PDEBUG("me4000_ai_do_cmd_test(): stop_arg       = %d\n", cmd->stop_arg);
1410	PDEBUG("me4000_ai_do_cmd_test(): chanlist       = %d\n",
1411		(unsigned int)cmd->chanlist);
1412	PDEBUG("me4000_ai_do_cmd_test(): chanlist_len   = %d\n",
1413		cmd->chanlist_len);
1414
1415	/* Only rounding flags are implemented */
1416	cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN;
1417
1418	/* Round the timer arguments */
1419	ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
1420
1421	/*
1422	 * Stage 1. Check if the trigger sources are generally valid.
1423	 */
1424	switch (cmd->start_src) {
1425	case TRIG_NOW:
1426	case TRIG_EXT:
1427		break;
1428	case TRIG_ANY:
1429		cmd->start_src &= TRIG_NOW | TRIG_EXT;
1430		err++;
1431		break;
1432	default:
1433		printk(KERN_ERR
1434			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start source\n",
1435			dev->minor);
1436		cmd->start_src = TRIG_NOW;
1437		err++;
1438	}
1439	switch (cmd->scan_begin_src) {
1440	case TRIG_FOLLOW:
1441	case TRIG_TIMER:
1442	case TRIG_EXT:
1443		break;
1444	case TRIG_ANY:
1445		cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
1446		err++;
1447		break;
1448	default:
1449		printk(KERN_ERR
1450			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan begin source\n",
1451			dev->minor);
1452		cmd->scan_begin_src = TRIG_FOLLOW;
1453		err++;
1454	}
1455	switch (cmd->convert_src) {
1456	case TRIG_TIMER:
1457	case TRIG_EXT:
1458		break;
1459	case TRIG_ANY:
1460		cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1461		err++;
1462		break;
1463	default:
1464		printk(KERN_ERR
1465			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert source\n",
1466			dev->minor);
1467		cmd->convert_src = TRIG_TIMER;
1468		err++;
1469	}
1470	switch (cmd->scan_end_src) {
1471	case TRIG_NONE:
1472	case TRIG_COUNT:
1473		break;
1474	case TRIG_ANY:
1475		cmd->scan_end_src &= TRIG_NONE | TRIG_COUNT;
1476		err++;
1477		break;
1478	default:
1479		printk(KERN_ERR
1480			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end source\n",
1481			dev->minor);
1482		cmd->scan_end_src = TRIG_NONE;
1483		err++;
1484	}
1485	switch (cmd->stop_src) {
1486	case TRIG_NONE:
1487	case TRIG_COUNT:
1488		break;
1489	case TRIG_ANY:
1490		cmd->stop_src &= TRIG_NONE | TRIG_COUNT;
1491		err++;
1492		break;
1493	default:
1494		printk(KERN_ERR
1495			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop source\n",
1496			dev->minor);
1497		cmd->stop_src = TRIG_NONE;
1498		err++;
1499	}
1500	if (err)
1501		return 1;
1502
1503	/*
1504	 * Stage 2. Check for trigger source conflicts.
1505	 */
1506	if (cmd->start_src == TRIG_NOW &&
1507		cmd->scan_begin_src == TRIG_TIMER &&
1508		cmd->convert_src == TRIG_TIMER) {
1509	} else if (cmd->start_src == TRIG_NOW &&
1510		cmd->scan_begin_src == TRIG_FOLLOW &&
1511		cmd->convert_src == TRIG_TIMER) {
1512	} else if (cmd->start_src == TRIG_EXT &&
1513		cmd->scan_begin_src == TRIG_TIMER &&
1514		cmd->convert_src == TRIG_TIMER) {
1515	} else if (cmd->start_src == TRIG_EXT &&
1516		cmd->scan_begin_src == TRIG_FOLLOW &&
1517		cmd->convert_src == TRIG_TIMER) {
1518	} else if (cmd->start_src == TRIG_EXT &&
1519		cmd->scan_begin_src == TRIG_EXT &&
1520		cmd->convert_src == TRIG_TIMER) {
1521	} else if (cmd->start_src == TRIG_EXT &&
1522		cmd->scan_begin_src == TRIG_EXT &&
1523		cmd->convert_src == TRIG_EXT) {
1524	} else {
1525		printk(KERN_ERR
1526			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start trigger combination\n",
1527			dev->minor);
1528		cmd->start_src = TRIG_NOW;
1529		cmd->scan_begin_src = TRIG_FOLLOW;
1530		cmd->convert_src = TRIG_TIMER;
1531		err++;
1532	}
1533
1534	if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) {
1535	} else if (cmd->stop_src == TRIG_COUNT &&
1536		cmd->scan_end_src == TRIG_NONE) {
1537	} else if (cmd->stop_src == TRIG_NONE &&
1538		cmd->scan_end_src == TRIG_COUNT) {
1539	} else if (cmd->stop_src == TRIG_COUNT &&
1540		cmd->scan_end_src == TRIG_COUNT) {
1541	} else {
1542		printk(KERN_ERR
1543			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop trigger combination\n",
1544			dev->minor);
1545		cmd->stop_src = TRIG_NONE;
1546		cmd->scan_end_src = TRIG_NONE;
1547		err++;
1548	}
1549	if (err)
1550		return 2;
1551
1552	/*
1553	 * Stage 3. Check if arguments are generally valid.
1554	 */
1555	if (cmd->chanlist_len < 1) {
1556		printk(KERN_ERR
1557			"comedi%d: me4000: me4000_ai_do_cmd_test(): No channel list\n",
1558			dev->minor);
1559		cmd->chanlist_len = 1;
1560		err++;
1561	}
1562	if (init_ticks < 66) {
1563		printk(KERN_ERR
1564			"comedi%d: me4000: me4000_ai_do_cmd_test(): Start arg to low\n",
1565			dev->minor);
1566		cmd->start_arg = 2000;
1567		err++;
1568	}
1569	if (scan_ticks && scan_ticks < 67) {
1570		printk(KERN_ERR
1571			"comedi%d: me4000: me4000_ai_do_cmd_test(): Scan begin arg to low\n",
1572			dev->minor);
1573		cmd->scan_begin_arg = 2031;
1574		err++;
1575	}
1576	if (chan_ticks < 66) {
1577		printk(KERN_ERR
1578			"comedi%d: me4000: me4000_ai_do_cmd_test(): Convert arg to low\n",
1579			dev->minor);
1580		cmd->convert_arg = 2000;
1581		err++;
1582	}
1583
1584	if (err)
1585		return 3;
1586
1587	/*
1588	 * Stage 4. Check for argument conflicts.
1589	 */
1590	if (cmd->start_src == TRIG_NOW &&
1591		cmd->scan_begin_src == TRIG_TIMER &&
1592		cmd->convert_src == TRIG_TIMER) {
1593
1594		/* Check timer arguments */
1595		if (init_ticks < ME4000_AI_MIN_TICKS) {
1596			printk(KERN_ERR
1597				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1598				dev->minor);
1599			cmd->start_arg = 2000;	/*  66 ticks at least */
1600			err++;
1601		}
1602		if (chan_ticks < ME4000_AI_MIN_TICKS) {
1603			printk(KERN_ERR
1604				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1605				dev->minor);
1606			cmd->convert_arg = 2000;	/*  66 ticks at least */
1607			err++;
1608		}
1609		if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1610			printk(KERN_ERR
1611				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
1612				dev->minor);
1613			cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;	/*  At least one tick more */
1614			err++;
1615		}
1616	} else if (cmd->start_src == TRIG_NOW &&
1617		cmd->scan_begin_src == TRIG_FOLLOW &&
1618		cmd->convert_src == TRIG_TIMER) {
1619
1620		/* Check timer arguments */
1621		if (init_ticks < ME4000_AI_MIN_TICKS) {
1622			printk(KERN_ERR
1623				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1624				dev->minor);
1625			cmd->start_arg = 2000;	/*  66 ticks at least */
1626			err++;
1627		}
1628		if (chan_ticks < ME4000_AI_MIN_TICKS) {
1629			printk(KERN_ERR
1630				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1631				dev->minor);
1632			cmd->convert_arg = 2000;	/*  66 ticks at least */
1633			err++;
1634		}
1635	} else if (cmd->start_src == TRIG_EXT &&
1636		cmd->scan_begin_src == TRIG_TIMER &&
1637		cmd->convert_src == TRIG_TIMER) {
1638
1639		/* Check timer arguments */
1640		if (init_ticks < ME4000_AI_MIN_TICKS) {
1641			printk(KERN_ERR
1642				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1643				dev->minor);
1644			cmd->start_arg = 2000;	/*  66 ticks at least */
1645			err++;
1646		}
1647		if (chan_ticks < ME4000_AI_MIN_TICKS) {
1648			printk(KERN_ERR
1649				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1650				dev->minor);
1651			cmd->convert_arg = 2000;	/*  66 ticks at least */
1652			err++;
1653		}
1654		if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1655			printk(KERN_ERR
1656				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
1657				dev->minor);
1658			cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;	/*  At least one tick more */
1659			err++;
1660		}
1661	} else if (cmd->start_src == TRIG_EXT &&
1662		cmd->scan_begin_src == TRIG_FOLLOW &&
1663		cmd->convert_src == TRIG_TIMER) {
1664
1665		/* Check timer arguments */
1666		if (init_ticks < ME4000_AI_MIN_TICKS) {
1667			printk(KERN_ERR
1668				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1669				dev->minor);
1670			cmd->start_arg = 2000;	/*  66 ticks at least */
1671			err++;
1672		}
1673		if (chan_ticks < ME4000_AI_MIN_TICKS) {
1674			printk(KERN_ERR
1675				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1676				dev->minor);
1677			cmd->convert_arg = 2000;	/*  66 ticks at least */
1678			err++;
1679		}
1680	} else if (cmd->start_src == TRIG_EXT &&
1681		cmd->scan_begin_src == TRIG_EXT &&
1682		cmd->convert_src == TRIG_TIMER) {
1683
1684		/* Check timer arguments */
1685		if (init_ticks < ME4000_AI_MIN_TICKS) {
1686			printk(KERN_ERR
1687				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1688				dev->minor);
1689			cmd->start_arg = 2000;	/*  66 ticks at least */
1690			err++;
1691		}
1692		if (chan_ticks < ME4000_AI_MIN_TICKS) {
1693			printk(KERN_ERR
1694				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1695				dev->minor);
1696			cmd->convert_arg = 2000;	/*  66 ticks at least */
1697			err++;
1698		}
1699	} else if (cmd->start_src == TRIG_EXT &&
1700		cmd->scan_begin_src == TRIG_EXT &&
1701		cmd->convert_src == TRIG_EXT) {
1702
1703		/* Check timer arguments */
1704		if (init_ticks < ME4000_AI_MIN_TICKS) {
1705			printk(KERN_ERR
1706				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1707				dev->minor);
1708			cmd->start_arg = 2000;	/*  66 ticks at least */
1709			err++;
1710		}
1711	}
1712	if (cmd->stop_src == TRIG_COUNT) {
1713		if (cmd->stop_arg == 0) {
1714			printk(KERN_ERR
1715				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop arg\n",
1716				dev->minor);
1717			cmd->stop_arg = 1;
1718			err++;
1719		}
1720	}
1721	if (cmd->scan_end_src == TRIG_COUNT) {
1722		if (cmd->scan_end_arg == 0) {
1723			printk(KERN_ERR
1724				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
1725				dev->minor);
1726			cmd->scan_end_arg = 1;
1727			err++;
1728		}
1729	}
1730
1731	if (err)
1732		return 4;
1733
1734	/*
1735	 * Stage 5. Check the channel list.
1736	 */
1737	if (ai_check_chanlist(dev, s, cmd))
1738		return 5;
1739
1740	return 0;
1741}
1742
1743static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG)
1744{
1745	unsigned int tmp;
1746	struct comedi_device *dev = dev_id;
1747	struct comedi_subdevice *s = dev->subdevices;
1748	me4000_ai_context_t *ai_context = &info->ai_context;
1749	int i;
1750	int c = 0;
1751	long lval;
1752
1753	ISR_PDEBUG("me4000_ai_isr() is executed\n");
1754
1755	if (!dev->attached) {
1756		ISR_PDEBUG("me4000_ai_isr() premature interrupt\n");
1757		return IRQ_NONE;
1758	}
1759
1760	/* Reset all events */
1761	s->async->events = 0;
1762
1763	/* Check if irq number is right */
1764	if (irq != ai_context->irq) {
1765		printk(KERN_ERR
1766			"comedi%d: me4000: me4000_ai_isr(): Incorrect interrupt num: %d\n",
1767			dev->minor, irq);
1768		return IRQ_HANDLED;
1769	}
1770
1771	if (me4000_inl(dev,
1772			ai_context->
1773			irq_status_reg) & ME4000_IRQ_STATUS_BIT_AI_HF) {
1774		ISR_PDEBUG
1775			("me4000_ai_isr(): Fifo half full interrupt occured\n");
1776
1777		/* Read status register to find out what happened */
1778		tmp = me4000_inl(dev, ai_context->ctrl_reg);
1779
1780		if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
1781			!(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
1782			(tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1783			ISR_PDEBUG("me4000_ai_isr(): Fifo full\n");
1784			c = ME4000_AI_FIFO_COUNT;
1785
1786			/* FIFO overflow, so stop conversion and disable all interrupts */
1787			tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1788			tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1789				ME4000_AI_CTRL_BIT_SC_IRQ);
1790			me4000_outl(dev, tmp, ai_context->ctrl_reg);
1791
1792			s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1793
1794			printk(KERN_ERR
1795				"comedi%d: me4000: me4000_ai_isr(): FIFO overflow\n",
1796				dev->minor);
1797		} else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
1798			&& !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
1799			&& (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1800			ISR_PDEBUG("me4000_ai_isr(): Fifo half full\n");
1801
1802			s->async->events |= COMEDI_CB_BLOCK;
1803
1804			c = ME4000_AI_FIFO_COUNT / 2;
1805		} else {
1806			printk(KERN_ERR
1807				"comedi%d: me4000: me4000_ai_isr(): Can't determine state of fifo\n",
1808				dev->minor);
1809			c = 0;
1810
1811			/* Undefined state, so stop conversion and disable all interrupts */
1812			tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1813			tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1814				ME4000_AI_CTRL_BIT_SC_IRQ);
1815			me4000_outl(dev, tmp, ai_context->ctrl_reg);
1816
1817			s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1818
1819			printk(KERN_ERR
1820				"comedi%d: me4000: me4000_ai_isr(): Undefined FIFO state\n",
1821				dev->minor);
1822		}
1823
1824		ISR_PDEBUG("me4000_ai_isr(): Try to read %d values\n", c);
1825
1826		for (i = 0; i < c; i++) {
1827			/* Read value from data fifo */
1828			lval = inl(ai_context->data_reg) & 0xFFFF;
1829			lval ^= 0x8000;
1830
1831			if (!comedi_buf_put(s->async, lval)) {
1832				/* Buffer overflow, so stop conversion and disable all interrupts */
1833				tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1834				tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1835					ME4000_AI_CTRL_BIT_SC_IRQ);
1836				me4000_outl(dev, tmp, ai_context->ctrl_reg);
1837
1838				s->async->events |= COMEDI_CB_OVERFLOW;
1839
1840				printk(KERN_ERR
1841					"comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
1842					dev->minor);
1843
1844				break;
1845			}
1846		}
1847
1848		/* Work is done, so reset the interrupt */
1849		ISR_PDEBUG("me4000_ai_isr(): Reset fifo half full interrupt\n");
1850		tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1851		me4000_outl(dev, tmp, ai_context->ctrl_reg);
1852		tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1853		me4000_outl(dev, tmp, ai_context->ctrl_reg);
1854	}
1855
1856	if (me4000_inl(dev,
1857			ai_context->
1858			irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) {
1859		ISR_PDEBUG
1860			("me4000_ai_isr(): Sample counter interrupt occured\n");
1861
1862		s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
1863
1864		/* Acquisition is complete, so stop conversion and disable all interrupts */
1865		tmp = me4000_inl(dev, ai_context->ctrl_reg);
1866		tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1867		tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1868		me4000_outl(dev, tmp, ai_context->ctrl_reg);
1869
1870		/* Poll data until fifo empty */
1871		while (inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_EF_DATA) {
1872			/* Read value from data fifo */
1873			lval = inl(ai_context->data_reg) & 0xFFFF;
1874			lval ^= 0x8000;
1875
1876			if (!comedi_buf_put(s->async, lval)) {
1877				printk(KERN_ERR
1878					"comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
1879					dev->minor);
1880				s->async->events |= COMEDI_CB_OVERFLOW;
1881				break;
1882			}
1883		}
1884
1885		/* Work is done, so reset the interrupt */
1886		ISR_PDEBUG
1887			("me4000_ai_isr(): Reset interrupt from sample counter\n");
1888		tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1889		me4000_outl(dev, tmp, ai_context->ctrl_reg);
1890		tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1891		me4000_outl(dev, tmp, ai_context->ctrl_reg);
1892	}
1893
1894	ISR_PDEBUG("me4000_ai_isr(): Events = 0x%X\n", s->async->events);
1895
1896	if (s->async->events)
1897		comedi_event(dev, s);
1898
1899	return IRQ_HANDLED;
1900}
1901
1902/*=============================================================================
1903  Analog output section
1904  ===========================================================================*/
1905
1906static int me4000_ao_insn_write(struct comedi_device *dev,
1907	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
1908{
1909
1910	int chan = CR_CHAN(insn->chanspec);
1911	int rang = CR_RANGE(insn->chanspec);
1912	int aref = CR_AREF(insn->chanspec);
1913	unsigned long tmp;
1914
1915	CALL_PDEBUG("In me4000_ao_insn_write()\n");
1916
1917	if (insn->n == 0) {
1918		return 0;
1919	} else if (insn->n > 1) {
1920		printk(KERN_ERR
1921			"comedi%d: me4000: me4000_ao_insn_write(): Invalid instruction length %d\n",
1922			dev->minor, insn->n);
1923		return -EINVAL;
1924	}
1925
1926	if (chan >= thisboard->ao.count) {
1927		printk(KERN_ERR
1928			"comedi%d: me4000: me4000_ao_insn_write(): Invalid channel %d\n",
1929			dev->minor, insn->n);
1930		return -EINVAL;
1931	}
1932
1933	if (rang != 0) {
1934		printk(KERN_ERR
1935			"comedi%d: me4000: me4000_ao_insn_write(): Invalid range %d\n",
1936			dev->minor, insn->n);
1937		return -EINVAL;
1938	}
1939
1940	if (aref != AREF_GROUND && aref != AREF_COMMON) {
1941		printk(KERN_ERR
1942			"comedi%d: me4000: me4000_ao_insn_write(): Invalid aref %d\n",
1943			dev->minor, insn->n);
1944		return -EINVAL;
1945	}
1946
1947	/* Stop any running conversion */
1948	tmp = me4000_inl(dev, info->ao_context[chan].ctrl_reg);
1949	tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
1950	me4000_outl(dev, tmp, info->ao_context[chan].ctrl_reg);
1951
1952	/* Clear control register and set to single mode */
1953	me4000_outl(dev, 0x0, info->ao_context[chan].ctrl_reg);
1954
1955	/* Write data value */
1956	me4000_outl(dev, data[0], info->ao_context[chan].single_reg);
1957
1958	/* Store in the mirror */
1959	info->ao_context[chan].mirror = data[0];
1960
1961	return 1;
1962}
1963
1964static int me4000_ao_insn_read(struct comedi_device *dev,
1965	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
1966{
1967	int chan = CR_CHAN(insn->chanspec);
1968
1969	if (insn->n == 0) {
1970		return 0;
1971	} else if (insn->n > 1) {
1972		printk("comedi%d: me4000: me4000_ao_insn_read(): Invalid instruction length\n", dev->minor);
1973		return -EINVAL;
1974	}
1975
1976	data[0] = info->ao_context[chan].mirror;
1977
1978	return 1;
1979}
1980
1981/*=============================================================================
1982  Digital I/O section
1983  ===========================================================================*/
1984
1985static int me4000_dio_insn_bits(struct comedi_device *dev,
1986	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
1987{
1988
1989	CALL_PDEBUG("In me4000_dio_insn_bits()\n");
1990
1991	/* Length of data must be 2 (mask and new data, see below) */
1992	if (insn->n == 0)
1993		return 0;
1994
1995	if (insn->n != 2) {
1996		printk("comedi%d: me4000: me4000_dio_insn_bits(): Invalid instruction length\n", dev->minor);
1997		return -EINVAL;
1998	}
1999
2000	/*
2001	 * The insn data consists of a mask in data[0] and the new data
2002	 * in data[1]. The mask defines which bits we are concerning about.
2003	 * The new data must be anded with the mask.
2004	 * Each channel corresponds to a bit.
2005	 */
2006	if (data[0]) {
2007		/* Check if requested ports are configured for output */
2008		if ((s->io_bits & data[0]) != data[0])
2009			return -EIO;
2010
2011		s->state &= ~data[0];
2012		s->state |= data[0] & data[1];
2013
2014		/* Write out the new digital output lines */
2015		me4000_outl(dev, (s->state >> 0) & 0xFF,
2016			info->dio_context.port_0_reg);
2017		me4000_outl(dev, (s->state >> 8) & 0xFF,
2018			info->dio_context.port_1_reg);
2019		me4000_outl(dev, (s->state >> 16) & 0xFF,
2020			info->dio_context.port_2_reg);
2021		me4000_outl(dev, (s->state >> 24) & 0xFF,
2022			info->dio_context.port_3_reg);
2023	}
2024
2025	/* On return, data[1] contains the value of
2026	   the digital input and output lines. */
2027	data[1] =
2028		((me4000_inl(dev, info->dio_context.port_0_reg) & 0xFF) << 0) |
2029		((me4000_inl(dev, info->dio_context.port_1_reg) & 0xFF) << 8) |
2030		((me4000_inl(dev, info->dio_context.port_2_reg) & 0xFF) << 16) |
2031		((me4000_inl(dev, info->dio_context.port_3_reg) & 0xFF) << 24);
2032
2033	return 2;
2034}
2035
2036static int me4000_dio_insn_config(struct comedi_device *dev,
2037	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
2038{
2039	unsigned long tmp;
2040	int chan = CR_CHAN(insn->chanspec);
2041
2042	CALL_PDEBUG("In me4000_dio_insn_config()\n");
2043
2044	if (data[0] == INSN_CONFIG_DIO_QUERY) {
2045		data[1] =
2046			(s->
2047			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
2048		return insn->n;
2049	}
2050
2051	/*
2052	 * The input or output configuration of each digital line is
2053	 * configured by a special insn_config instruction.  chanspec
2054	 * contains the channel to be changed, and data[0] contains the
2055	 * value COMEDI_INPUT or COMEDI_OUTPUT.
2056	 * On the ME-4000 it is only possible to switch port wise (8 bit)
2057	 */
2058
2059	tmp = me4000_inl(dev, info->dio_context.ctrl_reg);
2060
2061	if (data[0] == COMEDI_OUTPUT) {
2062		if (chan < 8) {
2063			s->io_bits |= 0xFF;
2064			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
2065				ME4000_DIO_CTRL_BIT_MODE_1);
2066			tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
2067		} else if (chan < 16) {
2068			/*
2069			 * Chech for optoisolated ME-4000 version. If one the first
2070			 * port is a fixed output port and the second is a fixed input port.
2071			 */
2072			if (!me4000_inl(dev, info->dio_context.dir_reg))
2073				return -ENODEV;
2074
2075			s->io_bits |= 0xFF00;
2076			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
2077				ME4000_DIO_CTRL_BIT_MODE_3);
2078			tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
2079		} else if (chan < 24) {
2080			s->io_bits |= 0xFF0000;
2081			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
2082				ME4000_DIO_CTRL_BIT_MODE_5);
2083			tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
2084		} else if (chan < 32) {
2085			s->io_bits |= 0xFF000000;
2086			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
2087				ME4000_DIO_CTRL_BIT_MODE_7);
2088			tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
2089		} else {
2090			return -EINVAL;
2091		}
2092	} else {
2093		if (chan < 8) {
2094			/*
2095			 * Chech for optoisolated ME-4000 version. If one the first
2096			 * port is a fixed output port and the second is a fixed input port.
2097			 */
2098			if (!me4000_inl(dev, info->dio_context.dir_reg))
2099				return -ENODEV;
2100
2101			s->io_bits &= ~0xFF;
2102			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
2103				ME4000_DIO_CTRL_BIT_MODE_1);
2104		} else if (chan < 16) {
2105			s->io_bits &= ~0xFF00;
2106			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
2107				ME4000_DIO_CTRL_BIT_MODE_3);
2108		} else if (chan < 24) {
2109			s->io_bits &= ~0xFF0000;
2110			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
2111				ME4000_DIO_CTRL_BIT_MODE_5);
2112		} else if (chan < 32) {
2113			s->io_bits &= ~0xFF000000;
2114			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
2115				ME4000_DIO_CTRL_BIT_MODE_7);
2116		} else {
2117			return -EINVAL;
2118		}
2119	}
2120
2121	me4000_outl(dev, tmp, info->dio_context.ctrl_reg);
2122
2123	return 1;
2124}
2125
2126/*=============================================================================
2127  Counter section
2128  ===========================================================================*/
2129
2130static int cnt_reset(struct comedi_device *dev, unsigned int channel)
2131{
2132
2133	CALL_PDEBUG("In cnt_reset()\n");
2134
2135	switch (channel) {
2136	case 0:
2137		me4000_outb(dev, 0x30, info->cnt_context.ctrl_reg);
2138		me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg);
2139		me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg);
2140		break;
2141	case 1:
2142		me4000_outb(dev, 0x70, info->cnt_context.ctrl_reg);
2143		me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg);
2144		me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg);
2145		break;
2146	case 2:
2147		me4000_outb(dev, 0xB0, info->cnt_context.ctrl_reg);
2148		me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg);
2149		me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg);
2150		break;
2151	default:
2152		printk(KERN_ERR
2153			"comedi%d: me4000: cnt_reset(): Invalid channel\n",
2154			dev->minor);
2155		return -EINVAL;
2156	}
2157
2158	return 0;
2159}
2160
2161static int cnt_config(struct comedi_device *dev, unsigned int channel,
2162	unsigned int mode)
2163{
2164	int tmp = 0;
2165
2166	CALL_PDEBUG("In cnt_config()\n");
2167
2168	switch (channel) {
2169	case 0:
2170		tmp |= ME4000_CNT_COUNTER_0;
2171		break;
2172	case 1:
2173		tmp |= ME4000_CNT_COUNTER_1;
2174		break;
2175	case 2:
2176		tmp |= ME4000_CNT_COUNTER_2;
2177		break;
2178	default:
2179		printk(KERN_ERR
2180			"comedi%d: me4000: cnt_config(): Invalid channel\n",
2181			dev->minor);
2182		return -EINVAL;
2183	}
2184
2185	switch (mode) {
2186	case 0:
2187		tmp |= ME4000_CNT_MODE_0;
2188		break;
2189	case 1:
2190		tmp |= ME4000_CNT_MODE_1;
2191		break;
2192	case 2:
2193		tmp |= ME4000_CNT_MODE_2;
2194		break;
2195	case 3:
2196		tmp |= ME4000_CNT_MODE_3;
2197		break;
2198	case 4:
2199		tmp |= ME4000_CNT_MODE_4;
2200		break;
2201	case 5:
2202		tmp |= ME4000_CNT_MODE_5;
2203		break;
2204	default:
2205		printk(KERN_ERR
2206			"comedi%d: me4000: cnt_config(): Invalid counter mode\n",
2207			dev->minor);
2208		return -EINVAL;
2209	}
2210
2211	/* Write the control word */
2212	tmp |= 0x30;
2213	me4000_outb(dev, tmp, info->cnt_context.ctrl_reg);
2214
2215	return 0;
2216}
2217
2218static int me4000_cnt_insn_config(struct comedi_device *dev,
2219	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
2220{
2221
2222	int err;
2223
2224	CALL_PDEBUG("In me4000_cnt_insn_config()\n");
2225
2226	switch (data[0]) {
2227	case GPCT_RESET:
2228		if (insn->n != 1) {
2229			printk(KERN_ERR
2230				"comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
2231				dev->minor, insn->n);
2232			return -EINVAL;
2233		}
2234
2235		err = cnt_reset(dev, insn->chanspec);
2236		if (err)
2237			return err;
2238		break;
2239	case GPCT_SET_OPERATION:
2240		if (insn->n != 2) {
2241			printk(KERN_ERR
2242				"comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
2243				dev->minor, insn->n);
2244			return -EINVAL;
2245		}
2246
2247		err = cnt_config(dev, insn->chanspec, data[1]);
2248		if (err)
2249			return err;
2250		break;
2251	default:
2252		printk(KERN_ERR
2253			"comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction\n",
2254			dev->minor);
2255		return -EINVAL;
2256	}
2257
2258	return 2;
2259}
2260
2261static int me4000_cnt_insn_read(struct comedi_device *dev,
2262	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
2263{
2264
2265	unsigned short tmp;
2266
2267	CALL_PDEBUG("In me4000_cnt_insn_read()\n");
2268
2269	if (insn->n == 0)
2270		return 0;
2271
2272	if (insn->n > 1) {
2273		printk(KERN_ERR
2274			"comedi%d: me4000: me4000_cnt_insn_read(): Invalid instruction length %d\n",
2275			dev->minor, insn->n);
2276		return -EINVAL;
2277	}
2278
2279	switch (insn->chanspec) {
2280	case 0:
2281		tmp = me4000_inb(dev, info->cnt_context.counter_0_reg);
2282		data[0] = tmp;
2283		tmp = me4000_inb(dev, info->cnt_context.counter_0_reg);
2284		data[0] |= tmp << 8;
2285		break;
2286	case 1:
2287		tmp = me4000_inb(dev, info->cnt_context.counter_1_reg);
2288		data[0] = tmp;
2289		tmp = me4000_inb(dev, info->cnt_context.counter_1_reg);
2290		data[0] |= tmp << 8;
2291		break;
2292	case 2:
2293		tmp = me4000_inb(dev, info->cnt_context.counter_2_reg);
2294		data[0] = tmp;
2295		tmp = me4000_inb(dev, info->cnt_context.counter_2_reg);
2296		data[0] |= tmp << 8;
2297		break;
2298	default:
2299		printk(KERN_ERR
2300			"comedi%d: me4000: me4000_cnt_insn_read(): Invalid channel %d\n",
2301			dev->minor, insn->chanspec);
2302		return -EINVAL;
2303	}
2304
2305	return 1;
2306}
2307
2308static int me4000_cnt_insn_write(struct comedi_device *dev,
2309	struct comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
2310{
2311
2312	unsigned short tmp;
2313
2314	CALL_PDEBUG("In me4000_cnt_insn_write()\n");
2315
2316	if (insn->n == 0) {
2317		return 0;
2318	} else if (insn->n > 1) {
2319		printk(KERN_ERR
2320			"comedi%d: me4000: me4000_cnt_insn_write(): Invalid instruction length %d\n",
2321			dev->minor, insn->n);
2322		return -EINVAL;
2323	}
2324
2325	switch (insn->chanspec) {
2326	case 0:
2327		tmp = data[0] & 0xFF;
2328		me4000_outb(dev, tmp, info->cnt_context.counter_0_reg);
2329		tmp = (data[0] >> 8) & 0xFF;
2330		me4000_outb(dev, tmp, info->cnt_context.counter_0_reg);
2331		break;
2332	case 1:
2333		tmp = data[0] & 0xFF;
2334		me4000_outb(dev, tmp, info->cnt_context.counter_1_reg);
2335		tmp = (data[0] >> 8) & 0xFF;
2336		me4000_outb(dev, tmp, info->cnt_context.counter_1_reg);
2337		break;
2338	case 2:
2339		tmp = data[0] & 0xFF;
2340		me4000_outb(dev, tmp, info->cnt_context.counter_2_reg);
2341		tmp = (data[0] >> 8) & 0xFF;
2342		me4000_outb(dev, tmp, info->cnt_context.counter_2_reg);
2343		break;
2344	default:
2345		printk(KERN_ERR
2346			"comedi%d: me4000: me4000_cnt_insn_write(): Invalid channel %d\n",
2347			dev->minor, insn->chanspec);
2348		return -EINVAL;
2349	}
2350
2351	return 1;
2352}
2353
2354COMEDI_PCI_INITCLEANUP(driver_me4000, me4000_pci_table);
2355