148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/*
248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   Some comments on the code..
348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   - it shouldn't be necessary to use outb_p().
548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   - ignoreirq creates a race condition.  It needs to be fixed.
748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen */
948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
1048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/*
1148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   comedi/drivers/das6402.c
1248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   An experimental driver for Computerboards' DAS6402 I/O card
1348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
1448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   Copyright (C) 1999 Oystein Svendsen <svendsen@pvv.org>
1548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
1648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   This program is free software; you can redistribute it and/or modify
1748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   it under the terms of the GNU General Public License as published by
1848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   the Free Software Foundation; either version 2 of the License, or
1948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   (at your option) any later version.
2048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
2148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   This program is distributed in the hope that it will be useful,
2248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   but WITHOUT ANY WARRANTY; without even the implied warranty of
2348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   GNU General Public License for more details.
2548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
2648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   You should have received a copy of the GNU General Public License
2748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   along with this program; if not, write to the Free Software
2848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
3048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen */
3148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/*
3248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein SvendsenDriver: das6402
3348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein SvendsenDescription: Keithley Metrabyte DAS6402 (& compatibles)
3448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein SvendsenAuthor: Oystein Svendsen <svendsen@pvv.org>
3548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein SvendsenStatus: bitrotten
3648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein SvendsenDevices: [Keithley Metrabyte] DAS6402 (das6402)
3748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
3848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein SvendsenThis driver has suffered bitrot.
3948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen*/
4048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
4125436dc9d84f1be60ff549c9ab712bba2835f284Greg Kroah-Hartman#include <linux/interrupt.h>
4248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#include "../comedidev.h"
4348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
4448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#include <linux/ioport.h>
4548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
4648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define DAS6402_SIZE 16
4748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
48ecd89ddcabf8646651f152155bff5f8bed9c6e92Andrea Gelmini#define N_WORDS (3000*64)
4948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
5048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define STOP    0
5148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define START   1
5248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
5348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define SCANL 0x3f00
5448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define BYTE unsigned char
5548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define WORD unsigned short
5648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
5748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/*----- register 8 ----*/
5848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define CLRINT 0x01
5948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define CLRXTR 0x02
6048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define CLRXIN 0x04
6148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define EXTEND 0x10
6248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define ARMED 0x20		/* enable conting of post sample conv */
6348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define POSTMODE 0x40
6448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define MHZ 0x80		/* 10 MHz clock */
6548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/*---------------------*/
6648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
6748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/*----- register 9 ----*/
6848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define IRQ (0x04 << 4)		/* these two are                         */
6948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define IRQV 10			/*               dependent on each other */
7048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
7148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define CONVSRC 0x03		/* trig src is Intarnal pacer */
7248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define BURSTEN 0x04		/* enable burst */
7348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define XINTE 0x08		/* use external int. trig */
7448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define INTE 0x80		/* enable analog interrupts */
7548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/*---------------------*/
7648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
7748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/*----- register 10 ---*/
7848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define TGEN 0x01		/* Use pin DI1 for externl trigging? */
7948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define TGSEL 0x02		/* Use edge triggering */
8048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define TGPOL 0x04		/* active edge is falling */
8148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define PRETRIG 0x08		/* pretrig */
8248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/*---------------------*/
8348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
8448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/*----- register 11 ---*/
8548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define EOB 0x0c
8648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define FIFOHFULL 0x08
8748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define GAIN 0x01
8848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define FIFONEPTY 0x04
8948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define MODE 0x10
9048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define SEM 0x20
9148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define BIP 0x40
9248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/*---------------------*/
9348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
9448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define M0 0x00
9548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define M2 0x04
9648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
9748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define	C0 0x00
9848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define	C1 0x40
9948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define	C2 0x80
10048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#define	RWLH 0x30
10148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
1020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das6402_attach(struct comedi_device *dev,
1030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			  struct comedi_devconfig *it);
104da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das6402_detach(struct comedi_device *dev);
105139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_das6402 = {
10668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.driver_name = "das6402",
10768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.module = THIS_MODULE,
10868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.attach = das6402_attach,
10968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.detach = das6402_detach,
11048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen};
11148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
1127114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic int __init driver_das6402_init_module(void)
1137114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{
1147114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas	return comedi_driver_register(&driver_das6402);
1157114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas}
1167114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas
1177114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic void __exit driver_das6402_cleanup_module(void)
1187114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{
1197114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas	comedi_driver_unregister(&driver_das6402);
1207114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas}
1217114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas
1227114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_init(driver_das6402_init_module);
1237114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_exit(driver_das6402_cleanup_module);
12448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
125c7b8bb98a46e475ae848642cf60160fc7135cd52Bill Pembertonstruct das6402_private {
12648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	int ai_bytes_to_read;
12748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
12848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	int das6402_ignoreirq;
129c7b8bb98a46e475ae848642cf60160fc7135cd52Bill Pemberton};
130c7b8bb98a46e475ae848642cf60160fc7135cd52Bill Pemberton#define devpriv ((struct das6402_private *)dev->private)
13148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
1320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void das6402_ai_fifo_dregs(struct comedi_device *dev,
1330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				  struct comedi_subdevice *s);
13448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
135da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void das6402_setcounter(struct comedi_device *dev)
13648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{
13748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	BYTE p;
13848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	unsigned short ctrlwrd;
13948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
14048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	/* set up counter0 first, mode 0 */
14148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	p = M0 | C0 | RWLH;
14248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(p, dev->iobase + 15);
14348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	ctrlwrd = 2000;
14448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	p = (BYTE) (0xff & ctrlwrd);
14548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(p, dev->iobase + 12);
14648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	p = (BYTE) (0xff & (ctrlwrd >> 8));
14748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(p, dev->iobase + 12);
14848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
14948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	/* set up counter1, mode 2 */
15048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	p = M2 | C1 | RWLH;
15148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(p, dev->iobase + 15);
15248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	ctrlwrd = 10;
15348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	p = (BYTE) (0xff & ctrlwrd);
15448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(p, dev->iobase + 13);
15548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	p = (BYTE) (0xff & (ctrlwrd >> 8));
15648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(p, dev->iobase + 13);
15748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
15848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	/* set up counter1, mode 2 */
15948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	p = M2 | C2 | RWLH;
16048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(p, dev->iobase + 15);
16148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	ctrlwrd = 1000;
16248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	p = (BYTE) (0xff & ctrlwrd);
16348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(p, dev->iobase + 14);
16448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	p = (BYTE) (0xff & (ctrlwrd >> 8));
16548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(p, dev->iobase + 14);
16648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen}
16748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
16870265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t intr_handler(int irq, void *d)
16948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{
17071b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton	struct comedi_device *dev = d;
17134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s = dev->subdevices;
17248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
17348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	if (!dev->attached || devpriv->das6402_ignoreirq) {
1747e4198f47bda09b15d06822b610f99065901e45cRavishankar karkala Mallikarjunayya		dev_warn(dev->hw_dev, "BUG: spurious interrupt\n");
17548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		return IRQ_HANDLED;
17648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	}
17748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#ifdef DEBUG
17848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	printk("das6402: interrupt! das6402_irqcount=%i\n",
1790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->das6402_irqcount);
18048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	printk("das6402: iobase+2=%i\n", inw_p(dev->iobase + 2));
18148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#endif
18248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
18348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	das6402_ai_fifo_dregs(dev, s);
18448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
18548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	if (s->async->buf_write_count >= devpriv->ai_bytes_to_read) {
18648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		outw_p(SCANL, dev->iobase + 2);	/* clears the fifo */
18748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		outb(0x07, dev->iobase + 8);	/* clears all flip-flops */
18848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#ifdef DEBUG
18948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		printk("das6402: Got %i samples\n\n",
1900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       devpriv->das6402_wordsread - diff);
19148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#endif
19248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		s->async->events |= COMEDI_CB_EOA;
19348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		comedi_event(dev, s);
19448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	}
19548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
19648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb(0x01, dev->iobase + 8);	/* clear only the interrupt flip-flop */
19748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
19848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	comedi_event(dev, s);
19948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	return IRQ_HANDLED;
20048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen}
20148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
20248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#if 0
203da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void das6402_ai_fifo_read(struct comedi_device *dev, short *data, int n)
20448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{
20548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	int i;
20648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
20748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	for (i = 0; i < n; i++)
20848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		data[i] = inw(dev->iobase);
20948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen}
21048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#endif
21148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
2120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void das6402_ai_fifo_dregs(struct comedi_device *dev,
2130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				  struct comedi_subdevice *s)
21448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{
21548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	while (1) {
21648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		if (!(inb(dev->iobase + 8) & 0x01))
21748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen			return;
21848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		comedi_buf_put(s->async, inw(dev->iobase));
21948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	}
22048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen}
22148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
2220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das6402_ai_cancel(struct comedi_device *dev,
2230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			     struct comedi_subdevice *s)
22448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{
22548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	/*
22648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	 *  This function should reset the board from whatever condition it
22748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	 *  is in (i.e., acquiring data), to a non-active state.
22848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	 */
22948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
23048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	devpriv->das6402_ignoreirq = 1;
2317e4198f47bda09b15d06822b610f99065901e45cRavishankar karkala Mallikarjunayya	dev_dbg(dev->hw_dev, "Stopping acquisition\n");
23248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	devpriv->das6402_ignoreirq = 1;
23348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(0x02, dev->iobase + 10);	/* disable external trigging */
23448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outw_p(SCANL, dev->iobase + 2);	/* resets the card fifo */
23548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(0, dev->iobase + 9);	/* disables interrupts */
23648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
23748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outw_p(SCANL, dev->iobase + 2);
23848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
23948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	return 0;
24048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen}
24148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
24248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#ifdef unused
2430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das6402_ai_mode2(struct comedi_device *dev,
2440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    struct comedi_subdevice *s, comedi_trig * it)
24548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{
24648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	devpriv->das6402_ignoreirq = 1;
2477e4198f47bda09b15d06822b610f99065901e45cRavishankar karkala Mallikarjunayya	dev_dbg(dev->hw_dev, "Starting acquisition\n");
24848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(0x03, dev->iobase + 10);	/* enable external trigging */
24948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outw_p(SCANL, dev->iobase + 2);	/* resets the card fifo */
25048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(IRQ | CONVSRC | BURSTEN | INTE, dev->iobase + 9);
25148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
252790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	devpriv->ai_bytes_to_read = it->n * sizeof(short);
25348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
25448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	/* um... ignoreirq is a nasty race condition */
25548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	devpriv->das6402_ignoreirq = 0;
25648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
25748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outw_p(SCANL, dev->iobase + 2);
25848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
25948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	return 0;
26048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen}
26148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen#endif
26248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
263da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int board_init(struct comedi_device *dev)
26448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{
26548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	BYTE b;
26648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
26748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	devpriv->das6402_ignoreirq = 1;
26848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
26948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb(0x07, dev->iobase + 8);
27048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
27148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	/* register 11  */
27248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(MODE, dev->iobase + 11);
27348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	b = BIP | SEM | MODE | GAIN | FIFOHFULL;
27448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(b, dev->iobase + 11);
27548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
27648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	/* register 8   */
27748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(EXTEND, dev->iobase + 8);
27848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	b = EXTEND | MHZ;
27948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(b, dev->iobase + 8);
28048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	b = MHZ | CLRINT | CLRXTR | CLRXIN;
28148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(b, dev->iobase + 8);
28248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
28348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	/* register 9    */
28448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	b = IRQ | CONVSRC | BURSTEN | INTE;
28548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(b, dev->iobase + 9);
28648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
28748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	/* register 10   */
28848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	b = TGSEL | TGEN;
28948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(b, dev->iobase + 10);
29048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
29148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	b = 0x07;
29248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outb_p(b, dev->iobase + 8);
29348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
29448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	das6402_setcounter(dev);
29548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
29648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	outw_p(SCANL, dev->iobase + 2);	/* reset card fifo */
29748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
29848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	devpriv->das6402_ignoreirq = 0;
29948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
30048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	return 0;
30148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen}
30248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
303da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das6402_detach(struct comedi_device *dev)
30448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{
30548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	if (dev->irq)
3065f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		free_irq(dev->irq, dev);
30748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	if (dev->iobase)
30848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		release_region(dev->iobase, DAS6402_SIZE);
30948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
31048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	return 0;
31148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen}
31248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
3130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das6402_attach(struct comedi_device *dev,
3140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			  struct comedi_devconfig *it)
31548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{
31648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	unsigned int irq;
31748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	unsigned long iobase;
31848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	int ret;
31934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s;
32048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
32148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	dev->board_name = "das6402";
32248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
32348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	iobase = it->options[0];
32448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	if (iobase == 0)
32548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		iobase = 0x300;
32648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
32748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	if (!request_region(iobase, DAS6402_SIZE, "das6402")) {
3287e4198f47bda09b15d06822b610f99065901e45cRavishankar karkala Mallikarjunayya		dev_err(dev->hw_dev, "I/O port conflict\n");
32948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		return -EIO;
33048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	}
33148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	dev->iobase = iobase;
33248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
33348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	/* should do a probe here */
33448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
33548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	irq = it->options[0];
3367e4198f47bda09b15d06822b610f99065901e45cRavishankar karkala Mallikarjunayya	dev_dbg(dev->hw_dev, "( irq = %u )\n", irq);
3375f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	ret = request_irq(irq, intr_handler, 0, "das6402", dev);
3387e4198f47bda09b15d06822b610f99065901e45cRavishankar karkala Mallikarjunayya	if (ret < 0)
33948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		return ret;
34048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
3417e4198f47bda09b15d06822b610f99065901e45cRavishankar karkala Mallikarjunayya	dev->irq = irq;
342c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	ret = alloc_private(dev, sizeof(struct das6402_private));
343c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	if (ret < 0)
34448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		return ret;
34548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
346c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	ret = alloc_subdevices(dev, 1);
347c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	if (ret < 0)
34848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen		return ret;
34948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
35048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	/* ai subdevice */
35148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	s = dev->subdevices + 0;
35248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	s->type = COMEDI_SUBD_AI;
35348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	s->subdev_flags = SDF_READABLE | SDF_GROUND;
35448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	s->n_chan = 8;
3552696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	/* s->trig[2]=das6402_ai_mode2; */
35648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	s->cancel = das6402_ai_cancel;
35748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	s->maxdata = (1 << 12) - 1;
35848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	s->len_chanlist = 16;	/* ? */
35948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	s->range_table = &range_unknown;
36048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
36148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	board_init(dev);
36248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen
36348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen	return 0;
36448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen}
36590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas
36690f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
36790f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver");
36890f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
369