pcl816.c revision 68c3dbff9fc9f25872408d0e95980d41733d48d0
1dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
2dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera   comedi/drivers/pcl816.c
3dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
4dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera   Author:  Juan Grigera <juan@grigera.com.ar>
5dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera            based on pcl818 by Michal Dobes <dobes@tesnet.cz> and bits of pcl812
6dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
7dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera   hardware driver for Advantech cards:
8dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera    card:   PCL-816, PCL814B
9dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera    driver: pcl816
10dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
11dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
12dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan GrigeraDriver: pcl816
13dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan GrigeraDescription: Advantech PCL-816 cards, PCL-814
14dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan GrigeraAuthor: Juan Grigera <juan@grigera.com.ar>
15dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan GrigeraDevices: [Advantech] PCL-816 (pcl816), PCL-814B (pcl814b)
16dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan GrigeraStatus: works
17dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan GrigeraUpdated: Tue,  2 Apr 2002 23:15:21 -0800
18dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
19dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan GrigeraPCL 816 and 814B have 16 SE/DIFF ADCs, 16 DACs, 16 DI and 16 DO.
20dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan GrigeraDifferences are at resolution (16 vs 12 bits).
21dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
22dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan GrigeraThe driver support AI command mode, other subdevices not written.
23dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
24dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan GrigeraAnalog output and digital input and output are not supported.
25dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
26dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan GrigeraConfiguration Options:
27dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera  [0] - IO Base
28dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera  [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
29dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera  [2] - DMA	(0=disable, 1, 3)
30dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera  [3] - 0, 10=10MHz clock for 8254
31dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera            1= 1MHz clock for 8254
32dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
33dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
34dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
35dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#include "../comedidev.h"
36dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
37dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#include <linux/ioport.h>
38dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#include <linux/mc146818rtc.h>
39dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#include <linux/delay.h>
40dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#include <asm/dma.h>
41dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
42dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#include "8253.h"
43dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
44dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define DEBUG(x) x
45dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
4658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* boards constants */
4758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* IO space len */
48dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define PCLx1x_RANGE 16
49dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
5058c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* #define outb(x,y)  printk("OUTB(%x, 200+%d)\n", x,y-0x200); outb(x,y) */
51dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
5258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* INTEL 8254 counters */
53dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define PCL816_CTR0 4
54dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define PCL816_CTR1 5
55dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define PCL816_CTR2 6
5658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* R: counter read-back register W: counter control */
57dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define PCL816_CTRCTL 7
58dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
5958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* R: A/D high byte W: A/D range control */
60dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define PCL816_RANGE 9
6158c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* W: clear INT request */
62dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define PCL816_CLRINT 10
6358c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* R: next mux scan channel W: mux scan channel & range control pointer */
64dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define PCL816_MUX 11
6558c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* R/W: operation control register */
66dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define PCL816_CONTROL 12
67dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
6858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* R: return status byte  W: set DMA/IRQ */
69dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define PCL816_STATUS 13
70dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define PCL816_STATUS_DRDY_MASK 0x80
71dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
7258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* R: low byte of A/D W: soft A/D trigger */
73dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define PCL816_AD_LO 8
7458c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* R: high byte of A/D W: A/D range control */
75dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define PCL816_AD_HI 9
76dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
7758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* type of interrupt handler */
78dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define INT_TYPE_AI1_INT 1
79dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define INT_TYPE_AI1_DMA 2
80dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define INT_TYPE_AI3_INT 4
81dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define INT_TYPE_AI3_DMA 5
82dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#ifdef unused
83dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define INT_TYPE_AI1_DMA_RTC 9
84dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define INT_TYPE_AI3_DMA_RTC 10
85dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
8658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* RTC stuff... */
87dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define RTC_IRQ 	8
88dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define RTC_IO_EXTENT	0x10
89dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#endif
90dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
91dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#define MAGIC_DMA_WORD 0x5a5a
92dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
939ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_pcl816 = { 8, {
94dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			BIP_RANGE(10),
95dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			BIP_RANGE(5),
96dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			BIP_RANGE(2.5),
97dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			BIP_RANGE(1.25),
98dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			UNI_RANGE(10),
99dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			UNI_RANGE(5),
100dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			UNI_RANGE(2.5),
101dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			UNI_RANGE(1.25),
102dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
103dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera};
1041c7f40d91b99e73ae11056708225058afd0278d7Bill Pembertonstruct pcl816_board {
1051c7f40d91b99e73ae11056708225058afd0278d7Bill Pemberton
10658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	const char *name;	/*  board name */
10758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int n_ranges;		/*  len of range list */
10858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int n_aichan;		/*  num of A/D chans in diferencial mode */
10958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int ai_ns_min;	/*  minimal alllowed delay between samples (in ns) */
11058c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int n_aochan;		/*  num of D/A chans */
11158c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int n_dichan;		/*  num of DI chans */
11258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int n_dochan;		/*  num of DO chans */
11358c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	const struct comedi_lrange *ai_range_type;	/*  default A/D rangelist */
11458c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	const struct comedi_lrange *ao_range_type;	/*  dafault D/A rangelist */
11558c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int io_range;	/*  len of IO space */
11658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int IRQbits;	/*  allowed interrupts */
11758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int DMAbits;	/*  allowed DMA chans */
11858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int ai_maxdata;		/*  maxdata for A/D */
11958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int ao_maxdata;		/*  maxdata for D/A */
12058c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int ai_chanlist;	/*  allowed len of channel list A/D */
12158c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int ao_chanlist;	/*  allowed len of channel list D/A */
12258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int i8254_osc_base;	/*  1/frequency of on board oscilator in ns */
1231c7f40d91b99e73ae11056708225058afd0278d7Bill Pemberton};
1241c7f40d91b99e73ae11056708225058afd0278d7Bill Pemberton
125dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1261c7f40d91b99e73ae11056708225058afd0278d7Bill Pembertonstatic const struct pcl816_board boardtypes[] = {
127dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	{"pcl816", 8, 16, 10000, 1, 16, 16, &range_pcl816,
128dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			&range_pcl816, PCLx1x_RANGE,
12958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton			0x00fc,	/*  IRQ mask */
13058c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton			0x0a,	/*  DMA mask */
13158c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton			0xffff,	/*  16-bit card */
13258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton			0xffff,	/*  D/A maxdata */
133dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			1024,
13458c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton			1,	/*  ao chan list */
135dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		100},
136dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	{"pcl814b", 8, 16, 10000, 1, 16, 16, &range_pcl816,
137dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			&range_pcl816, PCLx1x_RANGE,
138dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			0x00fc,
139dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			0x0a,
140dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			0x3fff,	/* 14 bit card */
141dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			0x3fff,
142dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			1024,
143dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			1,
144dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		100},
145dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera};
146dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1471c7f40d91b99e73ae11056708225058afd0278d7Bill Pemberton#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl816_board))
148fe0ff175329a83de8f9aac7c0b759cde15cb2247Bill Pemberton#define devpriv ((struct pcl816_private *)dev->private)
1491c7f40d91b99e73ae11056708225058afd0278d7Bill Pemberton#define this_board ((const struct pcl816_board *)dev->board_ptr)
150dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
151da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it);
152da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl816_detach(struct comedi_device *dev);
153dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
154dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#ifdef unused
155dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigerastatic int RTC_lock = 0;	/* RTC lock */
156dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigerastatic int RTC_timer_lock = 0;	/* RTC int lock */
157dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#endif
158dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
159139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_pcl816 = {
16068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.driver_name = "pcl816",
16168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.module = THIS_MODULE,
16268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.attach = pcl816_attach,
16368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.detach = pcl816_detach,
16468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.board_name = &boardtypes[0].name,
16568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.num_names = n_boardtypes,
16668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.offset = sizeof(struct pcl816_board),
167dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera};
168dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
169dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan GrigeraCOMEDI_INITCLEANUP(driver_pcl816);
170dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
171fe0ff175329a83de8f9aac7c0b759cde15cb2247Bill Pembertonstruct pcl816_private {
172fe0ff175329a83de8f9aac7c0b759cde15cb2247Bill Pemberton
17358c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int dma;	/*  used DMA, 0=don't use DMA */
17458c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int dma_rtc;		/*  1=RTC used with DMA, 0=no RTC alloc */
175dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#ifdef unused
17658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned long rtc_iobase;	/*  RTC port region */
177dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned int rtc_iosize;
178dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned int rtc_irq;
179dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#endif
18058c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned long dmabuf[2];	/*  pointers to begin of DMA buffers */
18158c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int dmapages[2];	/*  len of DMA buffers in PAGE_SIZEs */
18258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int hwdmaptr[2];	/*  hardware address of DMA buffers */
18358c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int hwdmasize[2];	/*  len of DMA buffers in Bytes */
18458c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int dmasamplsize;	/*  size in samples hwdmasize[0]/2 */
18558c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int last_top_dma;	/*  DMA pointer in last RTC int */
18658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int next_dma_buf;	/*  which DMA buffer will be used next round */
18758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	long dma_runs_to_end;	/*  how many we must permorm DMA transfer to end of record */
18858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned long last_dma_run;	/*  how many bytes we must transfer on last DMA page */
18958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton
19058c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int ai_scans;	/*  len of scanlist */
19158c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned char ai_neverending;	/*  if=1, then we do neverending record (you must use cancel()) */
19258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int irq_free;		/*  1=have allocated IRQ */
19358c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int irq_blocked;	/*  1=IRQ now uses any subdev */
194dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#ifdef unused
19558c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int rtc_irq_blocked;	/*  1=we now do AI with DMA&RTC */
196dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#endif
19758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int irq_was_now_closed;	/*  when IRQ finish, there's stored int816_mode for last interrupt */
19858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int int816_mode;	/*  who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma */
19958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	struct comedi_subdevice *last_int_sub;	/*  ptr to subdevice which now finish */
20058c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	int ai_act_scan;	/*  how many scans we finished */
20158c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int ai_act_chanlist[16];	/*  MUX setting for actual AI operations */
20258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int ai_act_chanlist_len;	/*  how long is actual MUX list */
20358c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int ai_act_chanlist_pos;	/*  actual position in MUX list */
20458c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned int ai_poll_ptr;	/*  how many sampes transfer poll */
20558c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	struct comedi_subdevice *sub_ai;	/*  ptr to AI subdevice */
206dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#ifdef unused
20758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	struct timer_list rtc_irq_timer;	/*  timer for RTC sanity check */
20858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	unsigned long rtc_freq;	/*  RTC int freq */
209dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#endif
210fe0ff175329a83de8f9aac7c0b759cde15cb2247Bill Pemberton};
211fe0ff175329a83de8f9aac7c0b759cde15cb2247Bill Pemberton
212dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
213dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
214dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
215dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
216da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int check_and_setup_channel_list(struct comedi_device *dev,
217da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton	struct comedi_subdevice *s, unsigned int *chanlist, int chanlen);
218da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl816_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
219da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
220dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned int divisor2);
221dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#ifdef unused
222dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigerastatic int set_rtc_irq_bit(unsigned char bit);
223dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#endif
224dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
225da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl816_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
226da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton	struct comedi_cmd *cmd);
227da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
228dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
229dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
230dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
231dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera   ANALOG INPUT MODE0, 816 cards, slow version
232dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
233da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl816_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
234da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton	struct comedi_insn *insn, unsigned int *data)
235dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
236dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	int n;
237dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	int timeout;
238dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
239dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	DPRINTK("mode 0 analog input\n");
24058c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	/*  software trigger, DMA and INT off */
241dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0, dev->iobase + PCL816_CONTROL);
24258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	/*  clear INT (conversion end) flag */
243dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0, dev->iobase + PCL816_CLRINT);
244dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
24558c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	/*  Set the input channel */
246dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(CR_CHAN(insn->chanspec) & 0xf, dev->iobase + PCL816_MUX);
247dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(CR_RANGE(insn->chanspec), dev->iobase + PCL816_RANGE);	/* select gain */
248dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
249dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	for (n = 0; n < insn->n; n++) {
250dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
251dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		outb(0, dev->iobase + PCL816_AD_LO);	/* start conversion */
252dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
253dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		timeout = 100;
254dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		while (timeout--) {
255dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			if (!(inb(dev->iobase + PCL816_STATUS) &
256dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					PCL816_STATUS_DRDY_MASK)) {
25758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton				/*  return read value */
258dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				data[n] =
259dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					((inb(dev->iobase +
260dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera							PCL816_AD_HI) << 8) |
261dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					(inb(dev->iobase + PCL816_AD_LO)));
262dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
263dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT (conversion end) flag */
264dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				break;
265dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			}
266dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			comedi_udelay(1);
267dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
26858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		/*  Return timeout error */
269dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (!timeout) {
270dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			comedi_error(dev, "A/D insn timeout\n");
271dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			data[0] = 0;
272dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT (conversion end) flag */
273dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			return -EIO;
274dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
275dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
276dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
277dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	return n;
278dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
279dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
280dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
281dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
282dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera   analog input interrupt mode 1 & 3, 818 cards
283dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera   one sample per interrupt version
284dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
285dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigerastatic irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
286dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
28771b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton	struct comedi_device *dev = d;
28834c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s = dev->subdevices + 0;
289dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	int low, hi;
290dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	int timeout = 50;	/* wait max 50us */
291dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
292dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	while (timeout--) {
293dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (!(inb(dev->iobase + PCL816_STATUS) &
294dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				PCL816_STATUS_DRDY_MASK))
295dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			break;
296dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		comedi_udelay(1);
297dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
29858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	if (!timeout) {		/*  timeout, bail error */
299dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT request */
300dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		comedi_error(dev, "A/D mode1/3 IRQ without DRDY!");
301dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		pcl816_ai_cancel(dev, s);
302dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
303dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		comedi_event(dev, s);
304dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return IRQ_HANDLED;
305dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
306dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
307dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
30858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	/*  get the sample */
309dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	low = inb(dev->iobase + PCL816_AD_LO);
310dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	hi = inb(dev->iobase + PCL816_AD_HI);
311dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
312dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_buf_put(s->async, (hi << 8) | low);
313dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
314dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT request */
315dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
316dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (++devpriv->ai_act_chanlist_pos >= devpriv->ai_act_chanlist_len)
317dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->ai_act_chanlist_pos = 0;
318dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
319dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (s->async->cur_chan == 0) {
320dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->ai_act_scan++;
321dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
322dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
323dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (!devpriv->ai_neverending)
324dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (devpriv->ai_act_scan >= devpriv->ai_scans) {	/* all data sampled */
325dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			/* all data sampled */
326dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			pcl816_ai_cancel(dev, s);
327dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			s->async->events |= COMEDI_CB_EOA;
328dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
329dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_event(dev, s);
330dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	return IRQ_HANDLED;
331dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
332dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
333dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
334dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
335dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera   analog input dma mode 1 & 3, 816 cards
336dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
337da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void transfer_from_dma_buf(struct comedi_device *dev, struct comedi_subdevice *s,
338da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton	short *ptr, unsigned int bufptr, unsigned int len)
339dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
340dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	int i;
341dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
342dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->async->events = 0;
343dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
344dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	for (i = 0; i < len; i++) {
345dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
346dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		comedi_buf_put(s->async, ptr[bufptr++]);
347dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
348dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (++devpriv->ai_act_chanlist_pos >=
349dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->ai_act_chanlist_len) {
350dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->ai_act_chanlist_pos = 0;
351dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->ai_act_scan++;
352dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
353dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
354dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (!devpriv->ai_neverending)
35558c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton			if (devpriv->ai_act_scan >= devpriv->ai_scans) {	/*  all data sampled */
356dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				pcl816_ai_cancel(dev, s);
357dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				s->async->events |= COMEDI_CB_EOA;
358dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				s->async->events |= COMEDI_CB_BLOCK;
359dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				break;
360dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			}
361dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
362dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
363dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_event(dev, s);
364dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
365dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
366dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigerastatic irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d)
367dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
36871b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton	struct comedi_device *dev = d;
36934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s = dev->subdevices + 0;
370dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	int len, bufptr, this_dma_buf;
371dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned long dma_flags;
372790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	short *ptr;
373dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
374dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	disable_dma(devpriv->dma);
375dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	this_dma_buf = devpriv->next_dma_buf;
376dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
37758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	if ((devpriv->dma_runs_to_end > -1) || devpriv->ai_neverending) {	/*  switch dma bufs */
378dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
379dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
380dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		set_dma_mode(devpriv->dma, DMA_MODE_READ);
381dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		dma_flags = claim_dma_lock();
38258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* clear_dma_ff (devpriv->dma); */
383dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		set_dma_addr(devpriv->dma,
384dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->hwdmaptr[devpriv->next_dma_buf]);
385dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (devpriv->dma_runs_to_end) {
386dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			set_dma_count(devpriv->dma,
387dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				devpriv->hwdmasize[devpriv->next_dma_buf]);
388dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		} else {
389dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			set_dma_count(devpriv->dma, devpriv->last_dma_run);
390dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
391dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		release_dma_lock(dma_flags);
392dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		enable_dma(devpriv->dma);
393dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
394dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
395dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	devpriv->dma_runs_to_end--;
396dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT request */
397dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
398790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	ptr = (short *) devpriv->dmabuf[this_dma_buf];
399dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
400dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	len = (devpriv->hwdmasize[0] >> 1) - devpriv->ai_poll_ptr;
401dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	bufptr = devpriv->ai_poll_ptr;
402dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	devpriv->ai_poll_ptr = 0;
403dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
404dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	transfer_from_dma_buf(dev, s, ptr, bufptr, len);
405dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	return IRQ_HANDLED;
406dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
407dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
408dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
409dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
410dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera    INT procedure
411dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
41270265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t interrupt_pcl816(int irq, void *d)
413dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
41471b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton	struct comedi_device *dev = d;
415dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	DPRINTK("<I>");
416dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
417dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (!dev->attached) {
418dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		comedi_error(dev, "premature interrupt");
419dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return IRQ_HANDLED;
420dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
421dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
422dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	switch (devpriv->int816_mode) {
423dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	case INT_TYPE_AI1_DMA:
424dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	case INT_TYPE_AI3_DMA:
425dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return interrupt_pcl816_ai_mode13_dma(irq, d);
426dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	case INT_TYPE_AI1_INT:
427dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	case INT_TYPE_AI3_INT:
428dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return interrupt_pcl816_ai_mode13_int(irq, d);
429dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
430dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
431dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT request */
432dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if ((!dev->irq) | (!devpriv->irq_free) | (!devpriv->irq_blocked) |
433dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		(!devpriv->int816_mode)) {
434dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (devpriv->irq_was_now_closed) {
435dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->irq_was_now_closed = 0;
43658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton			/*  comedi_error(dev,"last IRQ.."); */
437dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			return IRQ_HANDLED;
438dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
439dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		comedi_error(dev, "bad IRQ!");
440dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return IRQ_NONE;
441dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
442dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_error(dev, "IRQ from unknow source!");
443dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	return IRQ_NONE;
444dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
445dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
446dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
447dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
448dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera   COMMAND MODE
449dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
450da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pcl816_cmdtest_out(int e, struct comedi_cmd *cmd)
451dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
452dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	rt_printk("pcl816 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
453dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
454dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	rt_printk("pcl816 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
455dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
456dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	rt_printk("pcl816 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
457dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		cmd->scan_end_src);
458dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	rt_printk("pcl816 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", e,
459dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
460dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
461dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
462dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
463dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
464dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
465da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl816_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
466da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton	struct comedi_cmd *cmd)
467dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
468dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	int err = 0;
469dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	int tmp, divisor1, divisor2;
470dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
471dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	DEBUG(rt_printk("pcl816 pcl812_ai_cmdtest\n");
472dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		pcl816_cmdtest_out(-1, cmd););
473dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
474dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	/* step 1: make sure trigger sources are trivially valid */
475dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	tmp = cmd->start_src;
476dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	cmd->start_src &= TRIG_NOW;
477dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (!cmd->start_src || tmp != cmd->start_src)
478dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
479dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
480dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	tmp = cmd->scan_begin_src;
481dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	cmd->scan_begin_src &= TRIG_FOLLOW;
482dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
483dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
484dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
485dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (!cmd->convert_src & (TRIG_EXT | TRIG_TIMER))
486dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
487dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
488dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	tmp = cmd->scan_end_src;
489dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	cmd->scan_end_src &= TRIG_COUNT;
490dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
491dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
492dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
493dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	tmp = cmd->stop_src;
494dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
495dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (!cmd->stop_src || tmp != cmd->stop_src)
496dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
497dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
498dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (err) {
499dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return 1;
500dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
501dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
502dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	/* step 2: make sure trigger sources are unique and mutually compatible */
503dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
504dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->start_src != TRIG_NOW) {
505dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		cmd->start_src = TRIG_NOW;
506dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
507dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
508dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
509dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->scan_begin_src != TRIG_FOLLOW) {
510dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		cmd->scan_begin_src = TRIG_FOLLOW;
511dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
512dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
513dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
514dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_TIMER) {
515dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		cmd->convert_src = TRIG_TIMER;
516dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
517dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
518dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
519dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->scan_end_src != TRIG_COUNT) {
520dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		cmd->scan_end_src = TRIG_COUNT;
521dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
522dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
523dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
524dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
525dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
526dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
527dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (err) {
528dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return 2;
529dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
530dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
531dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	/* step 3: make sure arguments are trivially compatible */
532dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->start_arg != 0) {
533dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		cmd->start_arg = 0;
534dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
535dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
536dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
537dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->scan_begin_arg != 0) {
538dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		cmd->scan_begin_arg = 0;
539dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
540dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
541dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->convert_src == TRIG_TIMER) {
542dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (cmd->convert_arg < this_board->ai_ns_min) {
543dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			cmd->convert_arg = this_board->ai_ns_min;
544dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			err++;
545dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
546dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	} else {		/* TRIG_EXT */
547dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (cmd->convert_arg != 0) {
548dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			cmd->convert_arg = 0;
549dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			err++;
550dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
551dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
552dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
553dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (!cmd->chanlist_len) {
554dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		cmd->chanlist_len = 1;
555dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
556dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
557dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->chanlist_len > this_board->n_aichan) {
558dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		cmd->chanlist_len = this_board->n_aichan;
559dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
560dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
561dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->scan_end_arg != cmd->chanlist_len) {
562dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		cmd->scan_end_arg = cmd->chanlist_len;
563dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		err++;
564dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
565dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->stop_src == TRIG_COUNT) {
566dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (!cmd->stop_arg) {
567dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			cmd->stop_arg = 1;
568dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			err++;
569dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
570dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	} else {		/* TRIG_NONE */
571dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (cmd->stop_arg != 0) {
572dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			cmd->stop_arg = 0;
573dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			err++;
574dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
575dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
576dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
577dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (err) {
578dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return 3;
579dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
580dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
581dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	/* step 4: fix up any arguments */
582dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->convert_src == TRIG_TIMER) {
583dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		tmp = cmd->convert_arg;
584dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		i8253_cascade_ns_to_timer(this_board->i8254_osc_base,
585dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			&divisor1, &divisor2, &cmd->convert_arg,
586dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			cmd->flags & TRIG_ROUND_MASK);
587dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (cmd->convert_arg < this_board->ai_ns_min)
588dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			cmd->convert_arg = this_board->ai_ns_min;
589dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (tmp != cmd->convert_arg)
590dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			err++;
591dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
592dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
593dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (err) {
594dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return 4;
595dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
596dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
597dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	return 0;
598dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
599dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
600da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
601dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
602dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq;
603ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton	struct comedi_cmd *cmd = &s->async->cmd;
604dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
605dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->start_src != TRIG_NOW)
606dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return -EINVAL;
607dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->scan_begin_src != TRIG_FOLLOW)
608dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return -EINVAL;
609dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->scan_end_src != TRIG_COUNT)
610dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return -EINVAL;
611dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->scan_end_arg != cmd->chanlist_len)
612dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return -EINVAL;
61358c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* if(cmd->chanlist_len>MAX_CHANLIST_LEN) return -EINVAL; */
614dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (devpriv->irq_blocked)
615dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return -EBUSY;
616dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
617dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->convert_src == TRIG_TIMER) {
618dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (cmd->convert_arg < this_board->ai_ns_min)
619dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			cmd->convert_arg = this_board->ai_ns_min;
620dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
621dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		i8253_cascade_ns_to_timer(this_board->i8254_osc_base, &divisor1,
622dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			&divisor2, &cmd->convert_arg,
623dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			cmd->flags & TRIG_ROUND_MASK);
62458c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		if (divisor1 == 1) {	/*  PCL816 crash if any divisor is set to 1 */
625dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			divisor1 = 2;
626dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			divisor2 /= 2;
627dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
628dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (divisor2 == 1) {
629dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			divisor2 = 2;
630dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			divisor1 /= 2;
631dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
632dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
633dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
63458c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	start_pacer(dev, -1, 0, 0);	/*  stop pacer */
635dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
636dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (!check_and_setup_channel_list(dev, s, cmd->chanlist,
637dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			cmd->chanlist_len))
638dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return -EINVAL;
639dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_udelay(1);
640dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
641dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	devpriv->ai_act_scan = 0;
642dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->async->cur_chan = 0;
643dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	devpriv->irq_blocked = 1;
644dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	devpriv->ai_poll_ptr = 0;
645dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	devpriv->irq_was_now_closed = 0;
646dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
647dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (cmd->stop_src == TRIG_COUNT) {
648dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->ai_scans = cmd->stop_arg;
649dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->ai_neverending = 0;
650dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	} else {
651dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->ai_scans = 0;
652dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->ai_neverending = 1;
653dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
654dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
65558c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	if ((cmd->flags & TRIG_WAKE_EOS)) {	/*  don't we want wake up every scan? */
656dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		printk("pl816: You wankt WAKE_EOS but I dont want handle it");
65758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		/*               devpriv->ai_eos=1; */
65858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		/* if (devpriv->ai_n_chan==1) */
65958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		/*       devpriv->dma=0; // DMA is useless for this situation */
660dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
661dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
662dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (devpriv->dma) {
663dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		bytes = devpriv->hwdmasize[0];
664dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (!devpriv->ai_neverending) {
66558c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton			bytes = s->async->cmd.chanlist_len * s->async->cmd.chanlist_len * sizeof(short);	/*  how many */
66658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton			devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0];	/*  how many DMA pages we must fill */
66758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton			devpriv->last_dma_run = bytes % devpriv->hwdmasize[0];	/* on last dma transfer must be moved */
668dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->dma_runs_to_end--;
669dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			if (devpriv->dma_runs_to_end >= 0)
670dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				bytes = devpriv->hwdmasize[0];
671dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		} else
672dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->dma_runs_to_end = -1;
673dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
674dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->next_dma_buf = 0;
675dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		set_dma_mode(devpriv->dma, DMA_MODE_READ);
676dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		dma_flags = claim_dma_lock();
677dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		clear_dma_ff(devpriv->dma);
678dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
679dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		set_dma_count(devpriv->dma, bytes);
680dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		release_dma_lock(dma_flags);
681dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		enable_dma(devpriv->dma);
682dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
683dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
684dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	start_pacer(dev, 1, divisor1, divisor2);
685dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	dmairq = ((devpriv->dma & 0x3) << 4) | (dev->irq & 0x7);
686dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
687dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	switch (cmd->convert_src) {
688dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	case TRIG_TIMER:
689dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->int816_mode = INT_TYPE_AI1_DMA;
69058c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		outb(0x32, dev->iobase + PCL816_CONTROL);	/*  Pacer+IRQ+DMA */
69158c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		outb(dmairq, dev->iobase + PCL816_STATUS);	/*  write irq and DMA to card */
692dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		break;
693dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
694dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	default:
695dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->int816_mode = INT_TYPE_AI3_DMA;
69658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		outb(0x34, dev->iobase + PCL816_CONTROL);	/*  Ext trig+IRQ+DMA */
69758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		outb(dmairq, dev->iobase + PCL816_STATUS);	/*  write irq to card */
698dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		break;
699dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
700dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
701dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	DPRINTK("pcl816 END: pcl812_ai_cmd()\n");
702dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	return 0;
703dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
704dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
705da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
706dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
707dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned long flags;
708dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned int top1, top2, i;
709dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
710dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (!devpriv->dma)
71158c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		return 0;	/*  poll is valid only for DMA transfer */
712dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
713dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_spin_lock_irqsave(&dev->spinlock, flags);
714dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
715dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	for (i = 0; i < 20; i++) {
71658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		top1 = get_dma_residue(devpriv->dma);	/*  where is now DMA */
717dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		top2 = get_dma_residue(devpriv->dma);
718dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (top1 == top2)
719dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			break;
720dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
721dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (top1 != top2) {
722dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
723dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return 0;
724dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
725dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
72658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	top1 = devpriv->hwdmasize[0] - top1;	/*  where is now DMA in buffer */
72758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	top1 >>= 1;		/*  sample position */
728dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	top2 = top1 - devpriv->ai_poll_ptr;
72958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	if (top2 < 1) {		/*  no new samples */
730dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
731dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return 0;
732dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
733dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
734dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	transfer_from_dma_buf(dev, s,
735790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton		(short *) devpriv->dmabuf[devpriv->next_dma_buf],
736dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->ai_poll_ptr, top2);
737dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
73858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	devpriv->ai_poll_ptr = top1;	/*  new buffer position */
739dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
740dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
741dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	return s->async->buf_write_count - s->async->buf_read_count;
742dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
743dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
744dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
745dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
746dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera cancel any mode 1-4 AI
747dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
748da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl816_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
749dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
75058c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* DEBUG(rt_printk("pcl816_ai_cancel()\n");) */
751dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
752dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (devpriv->irq_blocked > 0) {
753dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		switch (devpriv->int816_mode) {
754dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#ifdef unused
755dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		case INT_TYPE_AI1_DMA_RTC:
756dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		case INT_TYPE_AI3_DMA_RTC:
75758c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton			set_rtc_irq_bit(0);	/*  stop RTC */
758dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			del_timer(&devpriv->rtc_irq_timer);
759dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#endif
760dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		case INT_TYPE_AI1_DMA:
761dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		case INT_TYPE_AI3_DMA:
762dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			disable_dma(devpriv->dma);
763dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		case INT_TYPE_AI1_INT:
764dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		case INT_TYPE_AI3_INT:
765dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			outb(inb(dev->iobase + PCL816_CONTROL) & 0x73, dev->iobase + PCL816_CONTROL);	/* Stop A/D */
766dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			comedi_udelay(1);
767dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			outb(0, dev->iobase + PCL816_CONTROL);	/* Stop A/D */
768dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			outb(0xb0, dev->iobase + PCL816_CTRCTL);	/* Stop pacer */
769dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			outb(0x70, dev->iobase + PCL816_CTRCTL);
770dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			outb(0, dev->iobase + PCL816_AD_LO);
771dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			inb(dev->iobase + PCL816_AD_LO);
772dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			inb(dev->iobase + PCL816_AD_HI);
773dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT request */
774dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			outb(0, dev->iobase + PCL816_CONTROL);	/* Stop A/D */
775dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->irq_blocked = 0;
776dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->irq_was_now_closed = devpriv->int816_mode;
777dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->int816_mode = 0;
778dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->last_int_sub = s;
77958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* s->busy = 0; */
780dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			break;
781dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
782dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
783dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
784dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	DEBUG(rt_printk("comedi: pcl816_ai_cancel() successful\n");
785dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		)
786dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return 0;
787dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
788dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
789dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
790dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
791dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera chech for PCL816
792dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
793dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigerastatic int pcl816_check(unsigned long iobase)
794dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
795dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0x00, iobase + PCL816_MUX);
796dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_udelay(1);
797dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (inb(iobase + PCL816_MUX) != 0x00)
79858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		return 1;	/* there isn't card */
799dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0x55, iobase + PCL816_MUX);
800dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_udelay(1);
801dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (inb(iobase + PCL816_MUX) != 0x55)
80258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		return 1;	/* there isn't card */
803dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0x00, iobase + PCL816_MUX);
804dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_udelay(1);
805dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0x18, iobase + PCL816_CONTROL);
806dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_udelay(1);
807dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (inb(iobase + PCL816_CONTROL) != 0x18)
80858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		return 1;	/* there isn't card */
80958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	return 0;		/*  ok, card exist */
810dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
811dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
812dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
813dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
814dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera reset whole PCL-816 cards
815dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
816da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pcl816_reset(struct comedi_device *dev)
817dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
81858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* outb (0, dev->iobase + PCL818_DA_LO);         DAC=0V */
81958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* outb (0, dev->iobase + PCL818_DA_HI); */
82058c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* comedi_udelay (1); */
82158c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* outb (0, dev->iobase + PCL818_DO_HI);        DO=$0000 */
82258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* outb (0, dev->iobase + PCL818_DO_LO); */
82358c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* comedi_udelay (1); */
824dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0, dev->iobase + PCL816_CONTROL);
825dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0, dev->iobase + PCL816_MUX);
826dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0, dev->iobase + PCL816_CLRINT);
827dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0xb0, dev->iobase + PCL816_CTRCTL);	/* Stop pacer */
828dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0x70, dev->iobase + PCL816_CTRCTL);
829dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0x30, dev->iobase + PCL816_CTRCTL);
830dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0, dev->iobase + PCL816_RANGE);
831dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
832dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
833dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
834dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
835dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera Start/stop pacer onboard pacer
836dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
837dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigerastatic void
838da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstart_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
839dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned int divisor2)
840dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
841dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0x32, dev->iobase + PCL816_CTRCTL);
842dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0xff, dev->iobase + PCL816_CTR0);
843dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(0x00, dev->iobase + PCL816_CTR0);
844dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_udelay(1);
84558c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	outb(0xb4, dev->iobase + PCL816_CTRCTL);	/*  set counter 2 as mode 3 */
84658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	outb(0x74, dev->iobase + PCL816_CTRCTL);	/*  set counter 1 as mode 3 */
847dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_udelay(1);
848dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
849dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (mode == 1) {
850dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		DPRINTK("mode %d, divisor1 %d, divisor2 %d\n", mode, divisor1,
851dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			divisor2);
852dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		outb(divisor2 & 0xff, dev->iobase + PCL816_CTR2);
853dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		outb((divisor2 >> 8) & 0xff, dev->iobase + PCL816_CTR2);
854dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		outb(divisor1 & 0xff, dev->iobase + PCL816_CTR1);
855dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		outb((divisor1 >> 8) & 0xff, dev->iobase + PCL816_CTR1);
856dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
857dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
858dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	/* clear pending interrupts (just in case) */
85958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton/* outb(0, dev->iobase + PCL816_CLRINT); */
860dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
861dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
862dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
863dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
864dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera Check if channel list from user is builded correctly
865dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera If it's ok, then program scan/gain logic
866dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
867dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigerastatic int
868da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertoncheck_and_setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
869dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned int *chanlist, int chanlen)
870dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
871dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned int chansegment[16];
872dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned int i, nowmustbechan, seglen, segpos;
873dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
87458c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	/*  correct channel and range number check itself comedi/range.c */
875dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (chanlen < 1) {
876dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		comedi_error(dev, "range/channel list is empty!");
877dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return 0;
878dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
879dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
880dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (chanlen > 1) {
88158c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		chansegment[0] = chanlist[0];	/*  first channel is everytime ok */
882dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
88358c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton			/*  build part of chanlist */
884dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			DEBUG(rt_printk("%d. %d %d\n", i, CR_CHAN(chanlist[i]),
885dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					CR_RANGE(chanlist[i]));
886dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				)
887dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				if (chanlist[0] == chanlist[i])
88858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton				break;	/*  we detect loop, this must by finish */
889dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			nowmustbechan =
890dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				(CR_CHAN(chansegment[i - 1]) + 1) % chanlen;
891dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			if (nowmustbechan != CR_CHAN(chanlist[i])) {
89258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton				/*  channel list isn't continous :-( */
893dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				rt_printk
894dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					("comedi%d: pcl816: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
895dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					dev->minor, i, CR_CHAN(chanlist[i]),
896dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					nowmustbechan, CR_CHAN(chanlist[0]));
897dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				return 0;
898dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			}
89958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton			chansegment[i] = chanlist[i];	/*  well, this is next correct channel in list */
900dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
901dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
90258c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		for (i = 0, segpos = 0; i < chanlen; i++) {	/*  check whole chanlist */
903dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			DEBUG(rt_printk("%d %d=%d %d\n",
904dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					CR_CHAN(chansegment[i % seglen]),
905dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					CR_RANGE(chansegment[i % seglen]),
906dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					CR_CHAN(chanlist[i]),
907dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					CR_RANGE(chanlist[i]));
908dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				)
909dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				if (chanlist[i] != chansegment[i % seglen]) {
910dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				rt_printk
911dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					("comedi%d: pcl816: bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
912dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					dev->minor, i, CR_CHAN(chansegment[i]),
913dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					CR_RANGE(chansegment[i]),
914dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					CR_AREF(chansegment[i]),
915dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					CR_CHAN(chanlist[i % seglen]),
916dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					CR_RANGE(chanlist[i % seglen]),
917dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					CR_AREF(chansegment[i % seglen]));
91858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton				return 0;	/*  chan/gain list is strange */
919dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			}
920dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
921dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	} else {
922dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		seglen = 1;
923dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
924dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
925dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	devpriv->ai_act_chanlist_len = seglen;
926dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	devpriv->ai_act_chanlist_pos = 0;
927dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
92858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	for (i = 0; i < seglen; i++) {	/*  store range list to card */
929dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->ai_act_chanlist[i] = CR_CHAN(chanlist[i]);
930dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		outb(CR_CHAN(chanlist[0]) & 0xf, dev->iobase + PCL816_MUX);
931dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		outb(CR_RANGE(chanlist[0]), dev->iobase + PCL816_RANGE);	/* select gain */
932dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
933dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
934dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	comedi_udelay(1);
935dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
936dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX);	/* select channel interval to scan */
937dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
93858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	return 1;		/*  we can serve this with MUX logic */
939dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
940dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
941dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#ifdef unused
942dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
943dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
944dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera  Enable(1)/disable(0) periodic interrupts from RTC
945dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
946dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigerastatic int set_rtc_irq_bit(unsigned char bit)
947dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
948dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned char val;
949dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned long flags;
950dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
951dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (bit == 1) {
952dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		RTC_timer_lock++;
953dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (RTC_timer_lock > 1)
954dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			return 0;
955dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	} else {
956dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		RTC_timer_lock--;
957dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (RTC_timer_lock < 0)
958dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			RTC_timer_lock = 0;
959dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (RTC_timer_lock > 0)
960dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			return 0;
961dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
962dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
963dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	save_flags(flags);
964dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	cli();
965dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	val = CMOS_READ(RTC_CONTROL);
966dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (bit) {
967dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		val |= RTC_PIE;
968dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	} else {
969dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		val &= ~RTC_PIE;
970dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
971dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	CMOS_WRITE(val, RTC_CONTROL);
972dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	CMOS_READ(RTC_INTR_FLAGS);
973dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	restore_flags(flags);
974dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	return 0;
975dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
976dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#endif
977dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
978dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
979dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
980dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera  Free any resources that we have claimed
981dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
982da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void free_resources(struct comedi_device *dev)
983dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
98458c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	/* rt_printk("free_resource()\n"); */
985dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (dev->private) {
986dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		pcl816_ai_cancel(dev, devpriv->sub_ai);
987dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		pcl816_reset(dev);
988dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (devpriv->dma)
989dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			free_dma(devpriv->dma);
990dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (devpriv->dmabuf[0])
991dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
992dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (devpriv->dmabuf[1])
993dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
994dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#ifdef unused
995dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (devpriv->rtc_irq)
996dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			comedi_free_irq(devpriv->rtc_irq, dev);
997dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if ((devpriv->dma_rtc) && (RTC_lock == 1)) {
998dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			if (devpriv->rtc_iobase)
999dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				release_region(devpriv->rtc_iobase,
1000dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					devpriv->rtc_iosize);
1001dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
1002dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#endif
1003dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
1004dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1005dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (dev->irq)
1006dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		free_irq(dev->irq, dev);
1007dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (dev->iobase)
1008dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		release_region(dev->iobase, this_board->io_range);
100958c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	/* rt_printk("free_resource() end\n"); */
1010dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
1011dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1012dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
1013dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
1014dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1015dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera   Initialization
1016dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1017dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
1018da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1019dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
1020dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	int ret;
1021dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned long iobase;
1022dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned int irq, dma;
1023dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	unsigned long pages;
102458c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	/* int i; */
102534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s;
1026dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1027dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	/* claim our I/O space */
1028dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	iobase = it->options[0];
1029dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	printk("comedi%d: pcl816:  board=%s, ioport=0x%03lx", dev->minor,
1030dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		this_board->name, iobase);
1031dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1032dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (!request_region(iobase, this_board->io_range, "pcl816")) {
1033dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		rt_printk("I/O port conflict\n");
1034dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return -EIO;
1035dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
1036dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1037dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	dev->iobase = iobase;
1038dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1039dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (pcl816_check(iobase)) {
1040dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		rt_printk(", I cann't detect board. FAIL!\n");
1041dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return -EIO;
1042dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
1043dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1044c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	ret = alloc_private(dev, sizeof(struct pcl816_private));
1045c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	if (ret < 0)
1046dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return ret;	/* Can't alloc mem */
1047dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1048dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	/* set up some name stuff */
1049dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	dev->board_name = this_board->name;
1050dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1051dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	/* grab our IRQ */
1052dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	irq = 0;
1053dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (this_board->IRQbits != 0) {	/* board support IRQ */
1054dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		irq = it->options[1];
1055dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (irq) {	/* we want to use IRQ */
1056dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			if (((1 << irq) & this_board->IRQbits) == 0) {
1057dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				rt_printk
1058dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					(", IRQ %u is out of allowed range, DISABLING IT",
1059dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					irq);
1060dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				irq = 0;	/* Bad IRQ */
1061dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			} else {
1062dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				if (comedi_request_irq(irq, interrupt_pcl816, 0,
1063dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera						"pcl816", dev)) {
1064dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					rt_printk
1065dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera						(", unable to allocate IRQ %u, DISABLING IT",
1066dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera						irq);
1067dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					irq = 0;	/* Can't use IRQ */
1068dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				} else {
1069dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					rt_printk(", irq=%u", irq);
1070dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				}
1071dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			}
1072dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
1073dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
1074dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1075dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	dev->irq = irq;
1076dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (irq) {
1077dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->irq_free = 1;
1078dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	} /* 1=we have allocated irq */
1079dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	else {
1080dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->irq_free = 0;
1081dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
1082dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	devpriv->irq_blocked = 0;	/* number of subdevice which use IRQ */
1083dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	devpriv->int816_mode = 0;	/* mode of irq */
1084dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1085dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#ifdef unused
1086dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	/* grab RTC for DMA operations */
1087dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	devpriv->dma_rtc = 0;
108858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton	if (it->options[2] > 0) {	/*  we want to use DMA */
1089dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (RTC_lock == 0) {
1090dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			if (!request_region(RTC_PORT(0), RTC_IO_EXTENT,
1091dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					"pcl816 (RTC)"))
1092dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				goto no_rtc;
1093dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
1094dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->rtc_iobase = RTC_PORT(0);
1095dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->rtc_iosize = RTC_IO_EXTENT;
1096dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		RTC_lock++;
1097dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#ifdef UNTESTED_CODE
1098dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (!comedi_request_irq(RTC_IRQ,
1099dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				interrupt_pcl816_ai_mode13_dma_rtc, 0,
1100dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				"pcl816 DMA (RTC)", dev)) {
1101dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->dma_rtc = 1;
1102dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->rtc_irq = RTC_IRQ;
1103dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			rt_printk(", dma_irq=%u", devpriv->rtc_irq);
1104dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		} else {
1105dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			RTC_lock--;
1106dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			if (RTC_lock == 0) {
1107dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				if (devpriv->rtc_iobase)
1108dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					release_region(devpriv->rtc_iobase,
1109dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera						devpriv->rtc_iosize);
1110dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			}
1111dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->rtc_iobase = 0;
1112dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->rtc_iosize = 0;
1113dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
1114dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#else
1115dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		printk("pcl816: RTC code missing");
1116dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#endif
1117dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1118dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
1119dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1120dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera      no_rtc:
1121dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#endif
1122dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	/* grab our DMA */
1123dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	dma = 0;
1124dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	devpriv->dma = dma;
1125dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if ((devpriv->irq_free == 0) && (devpriv->dma_rtc == 0))
1126dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		goto no_dma;	/* if we haven't IRQ, we can't use DMA */
1127dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1128dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (this_board->DMAbits != 0) {	/* board support DMA */
1129dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		dma = it->options[2];
1130dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (dma < 1)
1131dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			goto no_dma;	/* DMA disabled */
1132dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1133dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (((1 << dma) & this_board->DMAbits) == 0) {
1134dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			rt_printk(", DMA is out of allowed range, FAIL!\n");
1135dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			return -EINVAL;	/* Bad DMA */
1136dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
1137dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		ret = request_dma(dma, "pcl816");
1138dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (ret) {
1139dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			rt_printk(", unable to allocate DMA %u, FAIL!\n", dma);
1140dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			return -EBUSY;	/* DMA isn't free */
1141dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
1142dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1143dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->dma = dma;
1144dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		rt_printk(", dma=%u", dma);
1145dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		pages = 2;	/* we need 16KB */
1146dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
1147dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1148dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		if (!devpriv->dmabuf[0]) {
1149dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			rt_printk(", unable to allocate DMA buffer, FAIL!\n");
1150dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			/* maybe experiment with try_to_free_pages() will help .... */
1151dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			return -EBUSY;	/* no buffer :-( */
1152dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
1153dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->dmapages[0] = pages;
1154dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
1155dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE;
115658c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		/* rt_printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE); */
1157dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
115858c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		if (devpriv->dma_rtc == 0) {	/*  we must do duble buff :-( */
1159dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
1160dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			if (!devpriv->dmabuf[1]) {
1161dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				rt_printk
1162dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera					(", unable to allocate DMA buffer, FAIL!\n");
1163dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				return -EBUSY;
1164dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			}
1165dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->dmapages[1] = pages;
1166dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->hwdmaptr[1] =
1167dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera				virt_to_bus((void *)devpriv->dmabuf[1]);
1168dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera			devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
1169dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		}
1170dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
1171dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1172dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera      no_dma:
1173dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1174dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*  if (this_board->n_aochan > 0)
1175dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera    subdevs[1] = COMEDI_SUBD_AO;
1176dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera  if (this_board->n_dichan > 0)
1177dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera    subdevs[2] = COMEDI_SUBD_DI;
1178dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera  if (this_board->n_dochan > 0)
1179dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera    subdevs[3] = COMEDI_SUBD_DO;
1180dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera*/
1181c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton
1182c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	ret = alloc_subdevices(dev, 1);
1183c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	if (ret < 0)
1184dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		return ret;
1185dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1186dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s = dev->subdevices + 0;
1187dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (this_board->n_aichan > 0) {
1188dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->type = COMEDI_SUBD_AI;
1189dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		devpriv->sub_ai = s;
1190dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		dev->read_subdev = s;
1191dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
1192dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->n_chan = this_board->n_aichan;
1193dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->subdev_flags |= SDF_DIFF;
119458c0576eea94298e698e03114c4d3d0179c5ef66Bill Pemberton		/* printk (", %dchans DIFF DAC - %d", s->n_chan, i); */
1195dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->maxdata = this_board->ai_maxdata;
1196dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->len_chanlist = this_board->ai_chanlist;
1197dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->range_table = this_board->ai_range_type;
1198dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->cancel = pcl816_ai_cancel;
1199dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->do_cmdtest = pcl816_ai_cmdtest;
1200dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->do_cmd = pcl816_ai_cmd;
1201dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->poll = pcl816_ai_poll;
1202dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->insn_read = pcl816_ai_insn_read;
1203dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	} else {
1204dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		s->type = COMEDI_SUBD_UNUSED;
1205dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	}
1206dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1207dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#if 0
1208dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigeracase COMEDI_SUBD_AO:
1209dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
1210dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->n_chan = this_board->n_aochan;
1211dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->maxdata = this_board->ao_maxdata;
1212dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->len_chanlist = this_board->ao_chanlist;
1213dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->range_table = this_board->ao_range_type;
1214dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	break;
1215dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1216dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigeracase COMEDI_SUBD_DI:
1217dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->subdev_flags = SDF_READABLE;
1218dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->n_chan = this_board->n_dichan;
1219dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->maxdata = 1;
1220dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->len_chanlist = this_board->n_dichan;
1221dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->range_table = &range_digital;
1222dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	break;
1223dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1224dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigeracase COMEDI_SUBD_DO:
1225dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->subdev_flags = SDF_WRITABLE;
1226dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->n_chan = this_board->n_dochan;
1227dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->maxdata = 1;
1228dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->len_chanlist = this_board->n_dochan;
1229dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	s->range_table = &range_digital;
1230dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	break;
1231dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#endif
1232dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1233dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	pcl816_reset(dev);
1234dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1235dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	rt_printk("\n");
1236dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1237dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	return 0;
1238dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
1239dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera
1240dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera/*
1241dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera==============================================================================
1242dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera  Removes device
1243dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera */
1244da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl816_detach(struct comedi_device *dev)
1245dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera{
1246dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	DEBUG(rt_printk("comedi%d: pcl816: remove\n", dev->minor);
1247dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		)
1248dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		free_resources(dev);
1249dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#ifdef unused
1250dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	if (devpriv->dma_rtc)
1251dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera		RTC_lock--;
1252dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera#endif
1253dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera	return 0;
1254dd2996b38be848c5f19a5e92a9be84069f09ebd3Juan Grigera}
1255