1/*
2 * comedi/drivers/pcl812.c
3 *
4 * Author: Michal Dobes <dobes@tesnet.cz>
5 *
6 * hardware driver for Advantech cards
7 *  card:   PCL-812, PCL-812PG, PCL-813, PCL-813B
8 *  driver: pcl812,  pcl812pg,  pcl813,  pcl813b
9 * and for ADlink cards
10 *  card:   ACL-8112DG, ACL-8112HG, ACL-8112PG, ACL-8113, ACL-8216
11 *  driver: acl8112dg,  acl8112hg,  acl8112pg,  acl8113,  acl8216
12 * and for ICP DAS cards
13 *  card:   ISO-813, A-821PGH, A-821PGL, A-821PGL-NDA, A-822PGH, A-822PGL,
14 *  driver: iso813,  a821pgh,  a-821pgl, a-821pglnda,  a822pgh,  a822pgl,
15 *  card:   A-823PGH, A-823PGL, A-826PG
16 * driver:  a823pgh,  a823pgl,  a826pg
17 */
18
19/*
20 * Driver: pcl812
21 * Description: Advantech PCL-812/PG, PCL-813/B,
22 *	     ADLink ACL-8112DG/HG/PG, ACL-8113, ACL-8216,
23 *	     ICP DAS A-821PGH/PGL/PGL-NDA, A-822PGH/PGL, A-823PGH/PGL, A-826PG,
24 *	     ICP DAS ISO-813
25 * Author: Michal Dobes <dobes@tesnet.cz>
26 * Devices: [Advantech] PCL-812 (pcl812), PCL-812PG (pcl812pg),
27 *	PCL-813 (pcl813), PCL-813B (pcl813b), [ADLink] ACL-8112DG (acl8112dg),
28 *	ACL-8112HG (acl8112hg), ACL-8113 (acl-8113), ACL-8216 (acl8216),
29 *	[ICP] ISO-813 (iso813), A-821PGH (a821pgh), A-821PGL (a821pgl),
30 *	A-821PGL-NDA (a821pclnda), A-822PGH (a822pgh), A-822PGL (a822pgl),
31 *	A-823PGH (a823pgh), A-823PGL (a823pgl), A-826PG (a826pg)
32 * Updated: Mon, 06 Aug 2007 12:03:15 +0100
33 * Status: works (I hope. My board fire up under my hands
34 *	       and I cann't test all features.)
35 *
36 * This driver supports insn and cmd interfaces. Some boards support only insn
37 * because their hardware don't allow more (PCL-813/B, ACL-8113, ISO-813).
38 * Data transfer over DMA is supported only when you measure only one
39 * channel, this is too hardware limitation of these boards.
40 *
41 * Options for PCL-812:
42 *   [0] - IO Base
43 *   [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
44 *   [2] - DMA  (0=disable, 1, 3)
45 *   [3] - 0=trigger source is internal 8253 with 2MHz clock
46 *         1=trigger source is external
47 *   [4] - 0=A/D input range is +/-10V
48 *	   1=A/D input range is +/-5V
49 *	   2=A/D input range is +/-2.5V
50 *	   3=A/D input range is +/-1.25V
51 *	   4=A/D input range is +/-0.625V
52 *	   5=A/D input range is +/-0.3125V
53 *   [5] - 0=D/A outputs 0-5V  (internal reference -5V)
54 *	   1=D/A outputs 0-10V (internal reference -10V)
55 *	   2=D/A outputs unknown (external reference)
56 *
57 * Options for PCL-812PG, ACL-8112PG:
58 *   [0] - IO Base
59 *   [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
60 *   [2] - DMA  (0=disable, 1, 3)
61 *   [3] - 0=trigger source is internal 8253 with 2MHz clock
62 *	   1=trigger source is external
63 *   [4] - 0=A/D have max +/-5V input
64 *	   1=A/D have max +/-10V input
65 *   [5] - 0=D/A outputs 0-5V  (internal reference -5V)
66 *	   1=D/A outputs 0-10V (internal reference -10V)
67 *	   2=D/A outputs unknown (external reference)
68 *
69 * Options for ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH, ACL-8216, A-826PG:
70 *   [0] - IO Base
71 *   [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
72 *   [2] - DMA  (0=disable, 1, 3)
73 *   [3] - 0=trigger source is internal 8253 with 2MHz clock
74 *	   1=trigger source is external
75 *   [4] - 0=A/D channels are S.E.
76 *	   1=A/D channels are DIFF
77 *   [5] - 0=D/A outputs 0-5V  (internal reference -5V)
78 *	   1=D/A outputs 0-10V (internal reference -10V)
79 *	   2=D/A outputs unknown (external reference)
80 *
81 * Options for A-821PGL/PGH:
82 *   [0] - IO Base
83 *   [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7)
84 *   [2] - 0=A/D channels are S.E.
85 *	   1=A/D channels are DIFF
86 *   [3] - 0=D/A output 0-5V  (internal reference -5V)
87 *	   1=D/A output 0-10V (internal reference -10V)
88 *
89 * Options for A-821PGL-NDA:
90 *   [0] - IO Base
91 *   [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7)
92 *   [2] - 0=A/D channels are S.E.
93 *	   1=A/D channels are DIFF
94 *
95 * Options for PCL-813:
96 *   [0] - IO Base
97 *
98 * Options for PCL-813B:
99 *   [0] - IO Base
100 *   [1] - 0= bipolar inputs
101 *	   1= unipolar inputs
102 *
103 * Options for ACL-8113, ISO-813:
104 *   [0] - IO Base
105 *   [1] - 0= 10V bipolar inputs
106 *	   1= 10V unipolar inputs
107 *	   2= 20V bipolar inputs
108 *	   3= 20V unipolar inputs
109 */
110
111#include <linux/module.h>
112#include <linux/interrupt.h>
113#include <linux/gfp.h>
114#include "../comedidev.h"
115
116#include <linux/delay.h>
117#include <linux/io.h>
118#include <asm/dma.h>
119
120#include "comedi_fc.h"
121#include "8253.h"
122
123/* hardware types of the cards */
124#define boardPCL812PG	      0	/* and ACL-8112PG */
125#define boardPCL813B	      1
126#define boardPCL812	      2
127#define boardPCL813	      3
128#define boardISO813	      5
129#define boardACL8113	      6
130#define boardACL8112	      7 /* ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH */
131#define boardACL8216	      8	/* and ICP DAS A-826PG */
132#define boardA821	      9	/* PGH, PGL, PGL/NDA versions */
133
134/*
135 * Register I/O map
136 */
137#define PCL812_TIMER_BASE			0x00
138#define PCL812_AI_LSB_REG			0x04
139#define PCL812_AI_MSB_REG			0x05
140#define PCL812_AI_MSB_DRDY			(1 << 4)
141#define PCL812_AO_LSB_REG(x)			(0x04 + ((x) * 2))
142#define PCL812_AO_MSB_REG(x)			(0x05 + ((x) * 2))
143#define PCL812_DI_LSB_REG			0x06
144#define PCL812_DI_MSB_REG			0x07
145#define PCL812_STATUS_REG			0x08
146#define PCL812_STATUS_DRDY			(1 << 5)
147#define PCL812_RANGE_REG			0x09
148#define PCL812_MUX_REG				0x0a
149#define PCL812_MUX_CHAN(x)			((x) << 0)
150#define PCL812_MUX_CS0				(1 << 4)
151#define PCL812_MUX_CS1				(1 << 5)
152#define PCL812_CTRL_REG				0x0b
153#define PCL812_CTRL_DISABLE_TRIG		(0 << 0)
154#define PCL812_CTRL_SOFT_TRIG			(1 << 0)
155#define PCL812_CTRL_PACER_DMA_TRIG		(2 << 0)
156#define PCL812_CTRL_PACER_EOC_TRIG		(6 << 0)
157#define PCL812_SOFTTRIG_REG			0x0c
158#define PCL812_DO_LSB_REG			0x0d
159#define PCL812_DO_MSB_REG			0x0e
160
161#define MAX_CHANLIST_LEN    256	/* length of scan list */
162
163static const struct comedi_lrange range_pcl812pg_ai = {
164	5, {
165		BIP_RANGE(5),
166		BIP_RANGE(2.5),
167		BIP_RANGE(1.25),
168		BIP_RANGE(0.625),
169		BIP_RANGE(0.3125)
170	}
171};
172
173static const struct comedi_lrange range_pcl812pg2_ai = {
174	5, {
175		BIP_RANGE(10),
176		BIP_RANGE(5),
177		BIP_RANGE(2.5),
178		BIP_RANGE(1.25),
179		BIP_RANGE(0.625)
180	}
181};
182
183static const struct comedi_lrange range812_bipolar1_25 = {
184	1, {
185		BIP_RANGE(1.25)
186	}
187};
188
189static const struct comedi_lrange range812_bipolar0_625 = {
190	1, {
191		BIP_RANGE(0.625)
192	}
193};
194
195static const struct comedi_lrange range812_bipolar0_3125 = {
196	1, {
197		BIP_RANGE(0.3125)
198	}
199};
200
201static const struct comedi_lrange range_pcl813b_ai = {
202	4, {
203		BIP_RANGE(5),
204		BIP_RANGE(2.5),
205		BIP_RANGE(1.25),
206		BIP_RANGE(0.625)
207	}
208};
209
210static const struct comedi_lrange range_pcl813b2_ai = {
211	4, {
212		UNI_RANGE(10),
213		UNI_RANGE(5),
214		UNI_RANGE(2.5),
215		UNI_RANGE(1.25)
216	}
217};
218
219static const struct comedi_lrange range_iso813_1_ai = {
220	5, {
221		BIP_RANGE(5),
222		BIP_RANGE(2.5),
223		BIP_RANGE(1.25),
224		BIP_RANGE(0.625),
225		BIP_RANGE(0.3125)
226	}
227};
228
229static const struct comedi_lrange range_iso813_1_2_ai = {
230	5, {
231		UNI_RANGE(10),
232		UNI_RANGE(5),
233		UNI_RANGE(2.5),
234		UNI_RANGE(1.25),
235		UNI_RANGE(0.625)
236	}
237};
238
239static const struct comedi_lrange range_iso813_2_ai = {
240	4, {
241		BIP_RANGE(5),
242		BIP_RANGE(2.5),
243		BIP_RANGE(1.25),
244		BIP_RANGE(0.625)
245	}
246};
247
248static const struct comedi_lrange range_iso813_2_2_ai = {
249	4, {
250		UNI_RANGE(10),
251		UNI_RANGE(5),
252		UNI_RANGE(2.5),
253		UNI_RANGE(1.25)
254	}
255};
256
257static const struct comedi_lrange range_acl8113_1_ai = {
258	4, {
259		BIP_RANGE(5),
260		BIP_RANGE(2.5),
261		BIP_RANGE(1.25),
262		BIP_RANGE(0.625)
263	}
264};
265
266static const struct comedi_lrange range_acl8113_1_2_ai = {
267	4, {
268		UNI_RANGE(10),
269		UNI_RANGE(5),
270		UNI_RANGE(2.5),
271		UNI_RANGE(1.25)
272	}
273};
274
275static const struct comedi_lrange range_acl8113_2_ai = {
276	3, {
277		BIP_RANGE(5),
278		BIP_RANGE(2.5),
279		BIP_RANGE(1.25)
280	}
281};
282
283static const struct comedi_lrange range_acl8113_2_2_ai = {
284	3, {
285		UNI_RANGE(10),
286		UNI_RANGE(5),
287		UNI_RANGE(2.5)
288	}
289};
290
291static const struct comedi_lrange range_acl8112dg_ai = {
292	9, {
293		BIP_RANGE(5),
294		BIP_RANGE(2.5),
295		BIP_RANGE(1.25),
296		BIP_RANGE(0.625),
297		UNI_RANGE(10),
298		UNI_RANGE(5),
299		UNI_RANGE(2.5),
300		UNI_RANGE(1.25),
301		BIP_RANGE(10)
302	}
303};
304
305static const struct comedi_lrange range_acl8112hg_ai = {
306	12, {
307		BIP_RANGE(5),
308		BIP_RANGE(0.5),
309		BIP_RANGE(0.05),
310		BIP_RANGE(0.005),
311		UNI_RANGE(10),
312		UNI_RANGE(1),
313		UNI_RANGE(0.1),
314		UNI_RANGE(0.01),
315		BIP_RANGE(10),
316		BIP_RANGE(1),
317		BIP_RANGE(0.1),
318		BIP_RANGE(0.01)
319	}
320};
321
322static const struct comedi_lrange range_a821pgh_ai = {
323	4, {
324		BIP_RANGE(5),
325		BIP_RANGE(0.5),
326		BIP_RANGE(0.05),
327		BIP_RANGE(0.005)
328	}
329};
330
331struct pcl812_board {
332	const char *name;
333	int board_type;
334	int n_aichan;
335	int n_aochan;
336	unsigned int ai_ns_min;
337	const struct comedi_lrange *rangelist_ai;
338	unsigned int IRQbits;
339	unsigned int has_dma:1;
340	unsigned int has_16bit_ai:1;
341	unsigned int has_mpc508_mux:1;
342	unsigned int has_dio:1;
343};
344
345static const struct pcl812_board boardtypes[] = {
346	{
347		.name		= "pcl812",
348		.board_type	= boardPCL812,
349		.n_aichan	= 16,
350		.n_aochan	= 2,
351		.ai_ns_min	= 33000,
352		.rangelist_ai	= &range_bipolar10,
353		.IRQbits	= 0xdcfc,
354		.has_dma	= 1,
355		.has_dio	= 1,
356	}, {
357		.name		= "pcl812pg",
358		.board_type	= boardPCL812PG,
359		.n_aichan	= 16,
360		.n_aochan	= 2,
361		.ai_ns_min	= 33000,
362		.rangelist_ai	= &range_pcl812pg_ai,
363		.IRQbits	= 0xdcfc,
364		.has_dma	= 1,
365		.has_dio	= 1,
366	}, {
367		.name		= "acl8112pg",
368		.board_type	= boardPCL812PG,
369		.n_aichan	= 16,
370		.n_aochan	= 2,
371		.ai_ns_min	= 10000,
372		.rangelist_ai	= &range_pcl812pg_ai,
373		.IRQbits	= 0xdcfc,
374		.has_dma	= 1,
375		.has_dio	= 1,
376	}, {
377		.name		= "acl8112dg",
378		.board_type	= boardACL8112,
379		.n_aichan	= 16,	/* 8 differential */
380		.n_aochan	= 2,
381		.ai_ns_min	= 10000,
382		.rangelist_ai	= &range_acl8112dg_ai,
383		.IRQbits	= 0xdcfc,
384		.has_dma	= 1,
385		.has_mpc508_mux	= 1,
386		.has_dio	= 1,
387	}, {
388		.name		= "acl8112hg",
389		.board_type	= boardACL8112,
390		.n_aichan	= 16,	/* 8 differential */
391		.n_aochan	= 2,
392		.ai_ns_min	= 10000,
393		.rangelist_ai	= &range_acl8112hg_ai,
394		.IRQbits	= 0xdcfc,
395		.has_dma	= 1,
396		.has_mpc508_mux	= 1,
397		.has_dio	= 1,
398	}, {
399		.name		= "a821pgl",
400		.board_type	= boardA821,
401		.n_aichan	= 16,	/* 8 differential */
402		.n_aochan	= 1,
403		.ai_ns_min	= 10000,
404		.rangelist_ai	= &range_pcl813b_ai,
405		.IRQbits	= 0x000c,
406		.has_dio	= 1,
407	}, {
408		.name		= "a821pglnda",
409		.board_type	= boardA821,
410		.n_aichan	= 16,	/* 8 differential */
411		.ai_ns_min	= 10000,
412		.rangelist_ai	= &range_pcl813b_ai,
413		.IRQbits	= 0x000c,
414	}, {
415		.name		= "a821pgh",
416		.board_type	= boardA821,
417		.n_aichan	= 16,	/* 8 differential */
418		.n_aochan	= 1,
419		.ai_ns_min	= 10000,
420		.rangelist_ai	= &range_a821pgh_ai,
421		.IRQbits	= 0x000c,
422		.has_dio	= 1,
423	}, {
424		.name		= "a822pgl",
425		.board_type	= boardACL8112,
426		.n_aichan	= 16,	/* 8 differential */
427		.n_aochan	= 2,
428		.ai_ns_min	= 10000,
429		.rangelist_ai	= &range_acl8112dg_ai,
430		.IRQbits	= 0xdcfc,
431		.has_dma	= 1,
432		.has_dio	= 1,
433	}, {
434		.name		= "a822pgh",
435		.board_type	= boardACL8112,
436		.n_aichan	= 16,	/* 8 differential */
437		.n_aochan	= 2,
438		.ai_ns_min	= 10000,
439		.rangelist_ai	= &range_acl8112hg_ai,
440		.IRQbits	= 0xdcfc,
441		.has_dma	= 1,
442		.has_dio	= 1,
443	}, {
444		.name		= "a823pgl",
445		.board_type	= boardACL8112,
446		.n_aichan	= 16,	/* 8 differential */
447		.n_aochan	= 2,
448		.ai_ns_min	= 8000,
449		.rangelist_ai	= &range_acl8112dg_ai,
450		.IRQbits	= 0xdcfc,
451		.has_dma	= 1,
452		.has_dio	= 1,
453	}, {
454		.name		= "a823pgh",
455		.board_type	= boardACL8112,
456		.n_aichan	= 16,	/* 8 differential */
457		.n_aochan	= 2,
458		.ai_ns_min	= 8000,
459		.rangelist_ai	= &range_acl8112hg_ai,
460		.IRQbits	= 0xdcfc,
461		.has_dma	= 1,
462		.has_dio	= 1,
463	}, {
464		.name		= "pcl813",
465		.board_type	= boardPCL813,
466		.n_aichan	= 32,
467		.rangelist_ai	= &range_pcl813b_ai,
468	}, {
469		.name		= "pcl813b",
470		.board_type	= boardPCL813B,
471		.n_aichan	= 32,
472		.rangelist_ai	= &range_pcl813b_ai,
473	}, {
474		.name		= "acl8113",
475		.board_type	= boardACL8113,
476		.n_aichan	= 32,
477		.rangelist_ai	= &range_acl8113_1_ai,
478	}, {
479		.name		= "iso813",
480		.board_type	= boardISO813,
481		.n_aichan	= 32,
482		.rangelist_ai	= &range_iso813_1_ai,
483	}, {
484		.name		= "acl8216",
485		.board_type	= boardACL8216,
486		.n_aichan	= 16,	/* 8 differential */
487		.n_aochan	= 2,
488		.ai_ns_min	= 10000,
489		.rangelist_ai	= &range_pcl813b2_ai,
490		.IRQbits	= 0xdcfc,
491		.has_dma	= 1,
492		.has_16bit_ai	= 1,
493		.has_mpc508_mux	= 1,
494		.has_dio	= 1,
495	}, {
496		.name		= "a826pg",
497		.board_type	= boardACL8216,
498		.n_aichan	= 16,	/* 8 differential */
499		.n_aochan	= 2,
500		.ai_ns_min	= 10000,
501		.rangelist_ai	= &range_pcl813b2_ai,
502		.IRQbits	= 0xdcfc,
503		.has_dma	= 1,
504		.has_16bit_ai	= 1,
505		.has_dio	= 1,
506	},
507};
508
509struct pcl812_private {
510	unsigned char dma;	/*  >0 use dma ( usedDMA channel) */
511	unsigned char range_correction;	/*  =1 we must add 1 to range number */
512	unsigned int last_ai_chanspec;
513	unsigned char mode_reg_int;	/*  there is stored INT number for some card */
514	unsigned int ai_poll_ptr;	/*  how many sampes transfer poll */
515	unsigned int ai_act_scan;	/*  how many scans we finished */
516	unsigned int dmapages;
517	unsigned int hwdmasize;
518	unsigned long dmabuf[2];	/*  PTR to DMA buf */
519	unsigned int hwdmaptr[2];	/*  HW PTR to DMA buf */
520	unsigned int dmabytestomove[2];	/*  how many bytes DMA transfer */
521	int next_dma_buf;	/*  which buffer is next to use */
522	unsigned int dma_runs_to_end;	/*  how many times we must switch DMA buffers */
523	unsigned int last_dma_run;	/*  how many bytes to transfer on last DMA buffer */
524	unsigned int max_812_ai_mode0_rangewait;	/*  setling time for gain */
525	unsigned int divisor1;
526	unsigned int divisor2;
527	unsigned int use_diff:1;
528	unsigned int use_mpc508:1;
529	unsigned int use_ext_trg:1;
530	unsigned int ai_dma:1;
531	unsigned int ai_eos:1;
532};
533
534static void pcl812_start_pacer(struct comedi_device *dev, bool load_timers)
535{
536	struct pcl812_private *devpriv = dev->private;
537	unsigned long timer_base = dev->iobase + PCL812_TIMER_BASE;
538
539	i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
540	i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
541	udelay(1);
542
543	if (load_timers) {
544		i8254_write(timer_base, 0, 2, devpriv->divisor2);
545		i8254_write(timer_base, 0, 1, devpriv->divisor1);
546	}
547}
548
549static void pcl812_ai_setup_dma(struct comedi_device *dev,
550				struct comedi_subdevice *s)
551{
552	struct pcl812_private *devpriv = dev->private;
553	struct comedi_cmd *cmd = &s->async->cmd;
554	unsigned int dma_flags;
555	unsigned int bytes;
556
557	/*  we use EOS, so adapt DMA buffer to one scan */
558	if (devpriv->ai_eos) {
559		devpriv->dmabytestomove[0] = cfc_bytes_per_scan(s);
560		devpriv->dmabytestomove[1] = cfc_bytes_per_scan(s);
561		devpriv->dma_runs_to_end = 1;
562	} else {
563		devpriv->dmabytestomove[0] = devpriv->hwdmasize;
564		devpriv->dmabytestomove[1] = devpriv->hwdmasize;
565		if (s->async->prealloc_bufsz < devpriv->hwdmasize) {
566			devpriv->dmabytestomove[0] =
567				s->async->prealloc_bufsz;
568			devpriv->dmabytestomove[1] =
569				s->async->prealloc_bufsz;
570		}
571		if (cmd->stop_src == TRIG_NONE) {
572			devpriv->dma_runs_to_end = 1;
573		} else {
574			/*  how many samples we must transfer? */
575			bytes = cmd->stop_arg * cfc_bytes_per_scan(s);
576
577			/*  how many DMA pages we must fill */
578			devpriv->dma_runs_to_end =
579				bytes / devpriv->dmabytestomove[0];
580
581			/* on last dma transfer must be moved */
582			devpriv->last_dma_run =
583				bytes % devpriv->dmabytestomove[0];
584			if (devpriv->dma_runs_to_end == 0)
585				devpriv->dmabytestomove[0] =
586					devpriv->last_dma_run;
587			devpriv->dma_runs_to_end--;
588		}
589	}
590	if (devpriv->dmabytestomove[0] > devpriv->hwdmasize) {
591		devpriv->dmabytestomove[0] = devpriv->hwdmasize;
592		devpriv->ai_eos = 0;
593	}
594	if (devpriv->dmabytestomove[1] > devpriv->hwdmasize) {
595		devpriv->dmabytestomove[1] = devpriv->hwdmasize;
596		devpriv->ai_eos = 0;
597	}
598	devpriv->next_dma_buf = 0;
599	set_dma_mode(devpriv->dma, DMA_MODE_READ);
600	dma_flags = claim_dma_lock();
601	clear_dma_ff(devpriv->dma);
602	set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
603	set_dma_count(devpriv->dma, devpriv->dmabytestomove[0]);
604	release_dma_lock(dma_flags);
605	enable_dma(devpriv->dma);
606}
607
608static void pcl812_ai_setup_next_dma(struct comedi_device *dev,
609				     struct comedi_subdevice *s)
610{
611	struct pcl812_private *devpriv = dev->private;
612	unsigned long dma_flags;
613
614	devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
615	disable_dma(devpriv->dma);
616	set_dma_mode(devpriv->dma, DMA_MODE_READ);
617	dma_flags = claim_dma_lock();
618	set_dma_addr(devpriv->dma, devpriv->hwdmaptr[devpriv->next_dma_buf]);
619	if (devpriv->ai_eos) {
620		set_dma_count(devpriv->dma,
621			      devpriv->dmabytestomove[devpriv->next_dma_buf]);
622	} else {
623		if (devpriv->dma_runs_to_end) {
624			set_dma_count(devpriv->dma,
625				      devpriv->dmabytestomove[devpriv->
626							      next_dma_buf]);
627		} else {
628			set_dma_count(devpriv->dma, devpriv->last_dma_run);
629		}
630		devpriv->dma_runs_to_end--;
631	}
632	release_dma_lock(dma_flags);
633	enable_dma(devpriv->dma);
634}
635
636static void pcl812_ai_set_chan_range(struct comedi_device *dev,
637				     unsigned int chanspec, char wait)
638{
639	struct pcl812_private *devpriv = dev->private;
640	unsigned int chan = CR_CHAN(chanspec);
641	unsigned int range = CR_RANGE(chanspec);
642	unsigned int mux = 0;
643
644	if (chanspec == devpriv->last_ai_chanspec)
645		return;
646
647	devpriv->last_ai_chanspec = chanspec;
648
649	if (devpriv->use_mpc508) {
650		if (devpriv->use_diff) {
651			mux |= PCL812_MUX_CS0 | PCL812_MUX_CS1;
652		} else {
653			if (chan < 8)
654				mux |= PCL812_MUX_CS0;
655			else
656				mux |= PCL812_MUX_CS1;
657		}
658	}
659
660	outb(mux | PCL812_MUX_CHAN(chan), dev->iobase + PCL812_MUX_REG);
661	outb(range + devpriv->range_correction, dev->iobase + PCL812_RANGE_REG);
662
663	if (wait)
664		/*
665		 * XXX this depends on selected range and can be very long for
666		 * some high gain ranges!
667		 */
668		udelay(devpriv->max_812_ai_mode0_rangewait);
669}
670
671static void pcl812_ai_clear_eoc(struct comedi_device *dev)
672{
673	/* writing any value clears the interrupt request */
674	outb(0, dev->iobase + PCL812_STATUS_REG);
675}
676
677static void pcl812_ai_soft_trig(struct comedi_device *dev)
678{
679	/* writing any value triggers a software conversion */
680	outb(255, dev->iobase + PCL812_SOFTTRIG_REG);
681}
682
683static unsigned int pcl812_ai_get_sample(struct comedi_device *dev,
684					 struct comedi_subdevice *s)
685{
686	unsigned int val;
687
688	val = inb(dev->iobase + PCL812_AI_MSB_REG) << 8;
689	val |= inb(dev->iobase + PCL812_AI_LSB_REG);
690
691	return val & s->maxdata;
692}
693
694static int pcl812_ai_eoc(struct comedi_device *dev,
695			 struct comedi_subdevice *s,
696			 struct comedi_insn *insn,
697			 unsigned long context)
698{
699	unsigned int status;
700
701	if (s->maxdata > 0x0fff) {
702		status = inb(dev->iobase + PCL812_STATUS_REG);
703		if ((status & PCL812_STATUS_DRDY) == 0)
704			return 0;
705	} else {
706		status = inb(dev->iobase + PCL812_AI_MSB_REG);
707		if ((status & PCL812_AI_MSB_DRDY) == 0)
708			return 0;
709	}
710	return -EBUSY;
711}
712
713static int pcl812_ai_cmdtest(struct comedi_device *dev,
714			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
715{
716	const struct pcl812_board *board = dev->board_ptr;
717	struct pcl812_private *devpriv = dev->private;
718	int err = 0;
719	unsigned int flags;
720	unsigned int arg;
721
722	/* Step 1 : check if triggers are trivially valid */
723
724	err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
725	err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
726
727	if (devpriv->use_ext_trg)
728		flags = TRIG_EXT;
729	else
730		flags = TRIG_TIMER;
731	err |= cfc_check_trigger_src(&cmd->convert_src, flags);
732
733	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
734	err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
735
736	if (err)
737		return 1;
738
739	/* Step 2a : make sure trigger sources are unique */
740
741	err |= cfc_check_trigger_is_unique(cmd->stop_src);
742
743	/* Step 2b : and mutually compatible */
744
745	if (err)
746		return 2;
747
748	/* Step 3: check if arguments are trivially valid */
749
750	err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
751	err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
752
753	if (cmd->convert_src == TRIG_TIMER)
754		err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
755						 board->ai_ns_min);
756	else	/* TRIG_EXT */
757		err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
758
759	err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
760	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
761
762	if (cmd->stop_src == TRIG_COUNT)
763		err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
764	else	/* TRIG_NONE */
765		err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
766
767	if (err)
768		return 3;
769
770	/* step 4: fix up any arguments */
771
772	if (cmd->convert_src == TRIG_TIMER) {
773		arg = cmd->convert_arg;
774		i8253_cascade_ns_to_timer(I8254_OSC_BASE_2MHZ,
775					  &devpriv->divisor1,
776					  &devpriv->divisor2,
777					  &arg, cmd->flags);
778		err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
779	}
780
781	if (err)
782		return 4;
783
784	return 0;
785}
786
787static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
788{
789	struct pcl812_private *devpriv = dev->private;
790	struct comedi_cmd *cmd = &s->async->cmd;
791	unsigned int ctrl = 0;
792	unsigned int i;
793
794	pcl812_start_pacer(dev, false);
795
796	pcl812_ai_set_chan_range(dev, cmd->chanlist[0], 1);
797
798	if (devpriv->dma) {	/*  check if we can use DMA transfer */
799		devpriv->ai_dma = 1;
800		for (i = 1; i < cmd->chanlist_len; i++)
801			if (cmd->chanlist[0] != cmd->chanlist[i]) {
802				/*  we cann't use DMA :-( */
803				devpriv->ai_dma = 0;
804				break;
805			}
806	} else {
807		devpriv->ai_dma = 0;
808	}
809
810	devpriv->ai_act_scan = 0;
811	devpriv->ai_poll_ptr = 0;
812	s->async->cur_chan = 0;
813
814	/*  don't we want wake up every scan? */
815	if (cmd->flags & CMDF_WAKE_EOS) {
816		devpriv->ai_eos = 1;
817
818		/*  DMA is useless for this situation */
819		if (cmd->chanlist_len == 1)
820			devpriv->ai_dma = 0;
821	}
822
823	if (devpriv->ai_dma)
824		pcl812_ai_setup_dma(dev, s);
825
826	switch (cmd->convert_src) {
827	case TRIG_TIMER:
828		pcl812_start_pacer(dev, true);
829		break;
830	}
831
832	if (devpriv->ai_dma)
833		ctrl |= PCL812_CTRL_PACER_DMA_TRIG;
834	else
835		ctrl |= PCL812_CTRL_PACER_EOC_TRIG;
836	outb(devpriv->mode_reg_int | ctrl, dev->iobase + PCL812_CTRL_REG);
837
838	return 0;
839}
840
841static bool pcl812_ai_next_chan(struct comedi_device *dev,
842				struct comedi_subdevice *s)
843{
844	struct pcl812_private *devpriv = dev->private;
845	struct comedi_cmd *cmd = &s->async->cmd;
846
847	s->async->events |= COMEDI_CB_BLOCK;
848
849	s->async->cur_chan++;
850	if (s->async->cur_chan >= cmd->chanlist_len) {
851		s->async->cur_chan = 0;
852		devpriv->ai_act_scan++;
853		s->async->events |= COMEDI_CB_EOS;
854	}
855
856	if (cmd->stop_src == TRIG_COUNT &&
857	    devpriv->ai_act_scan >= cmd->stop_arg) {
858		/* all data sampled */
859		s->async->events |= COMEDI_CB_EOA;
860		return false;
861	}
862
863	return true;
864}
865
866static void pcl812_handle_eoc(struct comedi_device *dev,
867			      struct comedi_subdevice *s)
868{
869	struct comedi_cmd *cmd = &s->async->cmd;
870	unsigned int next_chan;
871
872	if (pcl812_ai_eoc(dev, s, NULL, 0)) {
873		dev_dbg(dev->class_dev, "A/D cmd IRQ without DRDY!\n");
874		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
875		return;
876	}
877
878	comedi_buf_put(s, pcl812_ai_get_sample(dev, s));
879
880	/* Set up next channel. Added by abbotti 2010-01-20, but untested. */
881	next_chan = s->async->cur_chan + 1;
882	if (next_chan >= cmd->chanlist_len)
883		next_chan = 0;
884	if (cmd->chanlist[s->async->cur_chan] != cmd->chanlist[next_chan])
885		pcl812_ai_set_chan_range(dev, cmd->chanlist[next_chan], 0);
886
887	pcl812_ai_next_chan(dev, s);
888}
889
890static void transfer_from_dma_buf(struct comedi_device *dev,
891				  struct comedi_subdevice *s,
892				  unsigned short *ptr,
893				  unsigned int bufptr, unsigned int len)
894{
895	unsigned int i;
896
897	for (i = len; i; i--) {
898		comedi_buf_put(s, ptr[bufptr++]);
899
900		if (!pcl812_ai_next_chan(dev, s))
901			break;
902	}
903}
904
905static void pcl812_handle_dma(struct comedi_device *dev,
906			      struct comedi_subdevice *s)
907{
908	struct pcl812_private *devpriv = dev->private;
909	int len, bufptr;
910	unsigned short *ptr;
911
912	ptr = (unsigned short *)devpriv->dmabuf[devpriv->next_dma_buf];
913	len = (devpriv->dmabytestomove[devpriv->next_dma_buf] >> 1) -
914	    devpriv->ai_poll_ptr;
915
916	pcl812_ai_setup_next_dma(dev, s);
917
918	bufptr = devpriv->ai_poll_ptr;
919	devpriv->ai_poll_ptr = 0;
920
921	transfer_from_dma_buf(dev, s, ptr, bufptr, len);
922}
923
924static irqreturn_t pcl812_interrupt(int irq, void *d)
925{
926	struct comedi_device *dev = d;
927	struct comedi_subdevice *s = dev->read_subdev;
928	struct pcl812_private *devpriv = dev->private;
929
930	if (!dev->attached) {
931		pcl812_ai_clear_eoc(dev);
932		return IRQ_HANDLED;
933	}
934
935	if (devpriv->ai_dma)
936		pcl812_handle_dma(dev, s);
937	else
938		pcl812_handle_eoc(dev, s);
939
940	pcl812_ai_clear_eoc(dev);
941
942	cfc_handle_events(dev, s);
943	return IRQ_HANDLED;
944}
945
946static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
947{
948	struct pcl812_private *devpriv = dev->private;
949	unsigned long flags;
950	unsigned int top1, top2, i;
951
952	if (!devpriv->ai_dma)
953		return 0;	/*  poll is valid only for DMA transfer */
954
955	spin_lock_irqsave(&dev->spinlock, flags);
956
957	for (i = 0; i < 10; i++) {
958		/*  where is now DMA */
959		top1 = get_dma_residue(devpriv->ai_dma);
960		top2 = get_dma_residue(devpriv->ai_dma);
961		if (top1 == top2)
962			break;
963	}
964
965	if (top1 != top2) {
966		spin_unlock_irqrestore(&dev->spinlock, flags);
967		return 0;
968	}
969	/*  where is now DMA in buffer */
970	top1 = devpriv->dmabytestomove[1 - devpriv->next_dma_buf] - top1;
971	top1 >>= 1;		/*  sample position */
972	top2 = top1 - devpriv->ai_poll_ptr;
973	if (top2 < 1) {		/*  no new samples */
974		spin_unlock_irqrestore(&dev->spinlock, flags);
975		return 0;
976	}
977
978	transfer_from_dma_buf(dev, s,
979			      (void *)devpriv->dmabuf[1 -
980						      devpriv->next_dma_buf],
981			      devpriv->ai_poll_ptr, top2);
982
983	devpriv->ai_poll_ptr = top1;	/*  new buffer position */
984
985	spin_unlock_irqrestore(&dev->spinlock, flags);
986
987	return comedi_buf_n_bytes_ready(s);
988}
989
990static int pcl812_ai_cancel(struct comedi_device *dev,
991			    struct comedi_subdevice *s)
992{
993	struct pcl812_private *devpriv = dev->private;
994
995	if (devpriv->ai_dma)
996		disable_dma(devpriv->dma);
997
998	outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG,
999	     dev->iobase + PCL812_CTRL_REG);
1000	pcl812_start_pacer(dev, false);
1001	pcl812_ai_clear_eoc(dev);
1002	return 0;
1003}
1004
1005static int pcl812_ai_insn_read(struct comedi_device *dev,
1006			       struct comedi_subdevice *s,
1007			       struct comedi_insn *insn,
1008			       unsigned int *data)
1009{
1010	struct pcl812_private *devpriv = dev->private;
1011	int ret = 0;
1012	int i;
1013
1014	outb(devpriv->mode_reg_int | PCL812_CTRL_SOFT_TRIG,
1015	     dev->iobase + PCL812_CTRL_REG);
1016
1017	pcl812_ai_set_chan_range(dev, insn->chanspec, 1);
1018
1019	for (i = 0; i < insn->n; i++) {
1020		pcl812_ai_clear_eoc(dev);
1021		pcl812_ai_soft_trig(dev);
1022
1023		ret = comedi_timeout(dev, s, insn, pcl812_ai_eoc, 0);
1024		if (ret)
1025			break;
1026
1027		data[i] = pcl812_ai_get_sample(dev, s);
1028	}
1029	outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG,
1030	     dev->iobase + PCL812_CTRL_REG);
1031	pcl812_ai_clear_eoc(dev);
1032
1033	return ret ? ret : insn->n;
1034}
1035
1036static int pcl812_ao_insn_write(struct comedi_device *dev,
1037				struct comedi_subdevice *s,
1038				struct comedi_insn *insn,
1039				unsigned int *data)
1040{
1041	unsigned int chan = CR_CHAN(insn->chanspec);
1042	unsigned int val = s->readback[chan];
1043	int i;
1044
1045	for (i = 0; i < insn->n; i++) {
1046		val = data[i];
1047		outb(val & 0xff, dev->iobase + PCL812_AO_LSB_REG(chan));
1048		outb((val >> 8) & 0x0f, dev->iobase + PCL812_AO_MSB_REG(chan));
1049	}
1050	s->readback[chan] = val;
1051
1052	return insn->n;
1053}
1054
1055static int pcl812_di_insn_bits(struct comedi_device *dev,
1056			       struct comedi_subdevice *s,
1057			       struct comedi_insn *insn,
1058			       unsigned int *data)
1059{
1060	data[1] = inb(dev->iobase + PCL812_DI_LSB_REG) |
1061		  (inb(dev->iobase + PCL812_DI_MSB_REG) << 8);
1062
1063	return insn->n;
1064}
1065
1066static int pcl812_do_insn_bits(struct comedi_device *dev,
1067			       struct comedi_subdevice *s,
1068			       struct comedi_insn *insn,
1069			       unsigned int *data)
1070{
1071	if (comedi_dio_update_state(s, data)) {
1072		outb(s->state & 0xff, dev->iobase + PCL812_DO_LSB_REG);
1073		outb((s->state >> 8), dev->iobase + PCL812_DO_MSB_REG);
1074	}
1075
1076	data[1] = s->state;
1077
1078	return insn->n;
1079}
1080
1081static void pcl812_reset(struct comedi_device *dev)
1082{
1083	const struct pcl812_board *board = dev->board_ptr;
1084	struct pcl812_private *devpriv = dev->private;
1085	unsigned int chan;
1086
1087	/* disable analog input trigger */
1088	outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG,
1089	     dev->iobase + PCL812_CTRL_REG);
1090	pcl812_ai_clear_eoc(dev);
1091
1092	/* stop pacer */
1093	if (board->IRQbits)
1094		pcl812_start_pacer(dev, false);
1095
1096	/*
1097	 * Invalidate last_ai_chanspec then set analog input to
1098	 * known channel/range.
1099	 */
1100	devpriv->last_ai_chanspec = CR_PACK(16, 0, 0);
1101	pcl812_ai_set_chan_range(dev, CR_PACK(0, 0, 0), 0);
1102
1103	/* set analog output channels to 0V */
1104	for (chan = 0; chan < board->n_aochan; chan++) {
1105		outb(0, dev->iobase + PCL812_AO_LSB_REG(chan));
1106		outb(0, dev->iobase + PCL812_AO_MSB_REG(chan));
1107	}
1108
1109	/* set all digital outputs low */
1110	if (board->has_dio) {
1111		outb(0, dev->iobase + PCL812_DO_MSB_REG);
1112		outb(0, dev->iobase + PCL812_DO_LSB_REG);
1113	}
1114}
1115
1116static void pcl812_set_ai_range_table(struct comedi_device *dev,
1117				      struct comedi_subdevice *s,
1118				      struct comedi_devconfig *it)
1119{
1120	const struct pcl812_board *board = dev->board_ptr;
1121	struct pcl812_private *devpriv = dev->private;
1122
1123	/* default to the range table from the boardinfo */
1124	s->range_table = board->rangelist_ai;
1125
1126	/* now check the user config option based on the boardtype */
1127	switch (board->board_type) {
1128	case boardPCL812PG:
1129		if (it->options[4] == 1)
1130			s->range_table = &range_pcl812pg2_ai;
1131		break;
1132	case boardPCL812:
1133		switch (it->options[4]) {
1134		case 0:
1135			s->range_table = &range_bipolar10;
1136			break;
1137		case 1:
1138			s->range_table = &range_bipolar5;
1139			break;
1140		case 2:
1141			s->range_table = &range_bipolar2_5;
1142			break;
1143		case 3:
1144			s->range_table = &range812_bipolar1_25;
1145			break;
1146		case 4:
1147			s->range_table = &range812_bipolar0_625;
1148			break;
1149		case 5:
1150			s->range_table = &range812_bipolar0_3125;
1151			break;
1152		default:
1153			s->range_table = &range_bipolar10;
1154			break;
1155		}
1156		break;
1157	case boardPCL813B:
1158		if (it->options[1] == 1)
1159			s->range_table = &range_pcl813b2_ai;
1160		break;
1161	case boardISO813:
1162		switch (it->options[1]) {
1163		case 0:
1164			s->range_table = &range_iso813_1_ai;
1165			break;
1166		case 1:
1167			s->range_table = &range_iso813_1_2_ai;
1168			break;
1169		case 2:
1170			s->range_table = &range_iso813_2_ai;
1171			devpriv->range_correction = 1;
1172			break;
1173		case 3:
1174			s->range_table = &range_iso813_2_2_ai;
1175			devpriv->range_correction = 1;
1176			break;
1177		default:
1178			s->range_table = &range_iso813_1_ai;
1179			break;
1180		}
1181		break;
1182	case boardACL8113:
1183		switch (it->options[1]) {
1184		case 0:
1185			s->range_table = &range_acl8113_1_ai;
1186			break;
1187		case 1:
1188			s->range_table = &range_acl8113_1_2_ai;
1189			break;
1190		case 2:
1191			s->range_table = &range_acl8113_2_ai;
1192			devpriv->range_correction = 1;
1193			break;
1194		case 3:
1195			s->range_table = &range_acl8113_2_2_ai;
1196			devpriv->range_correction = 1;
1197			break;
1198		default:
1199			s->range_table = &range_acl8113_1_ai;
1200			break;
1201		}
1202		break;
1203	}
1204}
1205
1206static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1207{
1208	const struct pcl812_board *board = dev->board_ptr;
1209	struct pcl812_private *devpriv;
1210	struct comedi_subdevice *s;
1211	int n_subdevices;
1212	int subdev;
1213	int ret;
1214	int i;
1215
1216	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1217	if (!devpriv)
1218		return -ENOMEM;
1219
1220	ret = comedi_request_region(dev, it->options[0], 0x10);
1221	if (ret)
1222		return ret;
1223
1224	if ((1 << it->options[1]) & board->IRQbits) {
1225		ret = request_irq(it->options[1], pcl812_interrupt, 0,
1226				  dev->board_name, dev);
1227		if (ret == 0)
1228			dev->irq = it->options[1];
1229	}
1230
1231	/* we need an IRQ to do DMA on channel 3 or 1 */
1232	if (dev->irq && board->has_dma &&
1233	    (it->options[2] == 3 || it->options[2] == 1)) {
1234		ret = request_dma(it->options[2], dev->board_name);
1235		if (ret) {
1236			dev_err(dev->class_dev,
1237				"unable to request DMA channel %d\n",
1238				it->options[2]);
1239			return -EBUSY;
1240		}
1241		devpriv->dma = it->options[2];
1242
1243		devpriv->dmapages = 1;	/* we want 8KB */
1244		devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE;
1245
1246		for (i = 0; i < 2; i++) {
1247			unsigned long dmabuf;
1248
1249			dmabuf =  __get_dma_pages(GFP_KERNEL, devpriv->dmapages);
1250			if (!dmabuf)
1251				return -ENOMEM;
1252
1253			devpriv->dmabuf[i] = dmabuf;
1254			devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf);
1255		}
1256	}
1257
1258	/* differential analog inputs? */
1259	switch (board->board_type) {
1260	case boardA821:
1261		if (it->options[2] == 1)
1262			devpriv->use_diff = 1;
1263		break;
1264	case boardACL8112:
1265	case boardACL8216:
1266		if (it->options[4] == 1)
1267			devpriv->use_diff = 1;
1268		break;
1269	}
1270
1271	n_subdevices = 1;		/* all boardtypes have analog inputs */
1272	if (board->n_aochan > 0)
1273		n_subdevices++;
1274	if (board->has_dio)
1275		n_subdevices += 2;
1276
1277	ret = comedi_alloc_subdevices(dev, n_subdevices);
1278	if (ret)
1279		return ret;
1280
1281	subdev = 0;
1282
1283	/* Analog Input subdevice */
1284	s = &dev->subdevices[subdev];
1285	s->type		= COMEDI_SUBD_AI;
1286	s->subdev_flags	= SDF_READABLE;
1287	if (devpriv->use_diff) {
1288		s->subdev_flags	|= SDF_DIFF;
1289		s->n_chan	= board->n_aichan / 2;
1290	} else {
1291		s->subdev_flags	|= SDF_GROUND;
1292		s->n_chan	= board->n_aichan;
1293	}
1294	s->maxdata	= board->has_16bit_ai ? 0xffff : 0x0fff;
1295
1296	pcl812_set_ai_range_table(dev, s, it);
1297
1298	s->insn_read	= pcl812_ai_insn_read;
1299
1300	if (dev->irq) {
1301		dev->read_subdev = s;
1302		s->subdev_flags	|= SDF_CMD_READ;
1303		s->len_chanlist	= MAX_CHANLIST_LEN;
1304		s->do_cmdtest	= pcl812_ai_cmdtest;
1305		s->do_cmd	= pcl812_ai_cmd;
1306		s->poll		= pcl812_ai_poll;
1307		s->cancel	= pcl812_ai_cancel;
1308	}
1309
1310	devpriv->use_mpc508 = board->has_mpc508_mux;
1311
1312	subdev++;
1313
1314	/* analog output */
1315	if (board->n_aochan > 0) {
1316		s = &dev->subdevices[subdev];
1317		s->type		= COMEDI_SUBD_AO;
1318		s->subdev_flags	= SDF_WRITABLE | SDF_GROUND;
1319		s->n_chan	= board->n_aochan;
1320		s->maxdata	= 0xfff;
1321		s->range_table	= &range_unipolar5;
1322		switch (board->board_type) {
1323		case boardA821:
1324			if (it->options[3] == 1)
1325				s->range_table = &range_unipolar10;
1326			break;
1327		case boardPCL812:
1328		case boardACL8112:
1329		case boardPCL812PG:
1330		case boardACL8216:
1331			if (it->options[5] == 1)
1332				s->range_table = &range_unipolar10;
1333			if (it->options[5] == 2)
1334				s->range_table = &range_unknown;
1335			break;
1336		}
1337		s->insn_write	= pcl812_ao_insn_write;
1338		s->insn_read	= comedi_readback_insn_read;
1339
1340		ret = comedi_alloc_subdev_readback(s);
1341		if (ret)
1342			return ret;
1343
1344		subdev++;
1345	}
1346
1347	if (board->has_dio) {
1348		/* Digital Input subdevice */
1349		s = &dev->subdevices[subdev];
1350		s->type		= COMEDI_SUBD_DI;
1351		s->subdev_flags	= SDF_READABLE;
1352		s->n_chan	= 16;
1353		s->maxdata	= 1;
1354		s->range_table	= &range_digital;
1355		s->insn_bits	= pcl812_di_insn_bits;
1356		subdev++;
1357
1358		/* Digital Output subdevice */
1359		s = &dev->subdevices[subdev];
1360		s->type		= COMEDI_SUBD_DO;
1361		s->subdev_flags	= SDF_WRITABLE;
1362		s->n_chan	= 16;
1363		s->maxdata	= 1;
1364		s->range_table	= &range_digital;
1365		s->insn_bits	= pcl812_do_insn_bits;
1366		subdev++;
1367	}
1368
1369	switch (board->board_type) {
1370	case boardACL8216:
1371	case boardPCL812PG:
1372	case boardPCL812:
1373	case boardACL8112:
1374		devpriv->max_812_ai_mode0_rangewait = 1;
1375		if (it->options[3] > 0)
1376						/*  we use external trigger */
1377			devpriv->use_ext_trg = 1;
1378		break;
1379	case boardA821:
1380		devpriv->max_812_ai_mode0_rangewait = 1;
1381		devpriv->mode_reg_int = (dev->irq << 4) & 0xf0;
1382		break;
1383	case boardPCL813B:
1384	case boardPCL813:
1385	case boardISO813:
1386	case boardACL8113:
1387		/* maybe there must by greatest timeout */
1388		devpriv->max_812_ai_mode0_rangewait = 5;
1389		break;
1390	}
1391
1392	pcl812_reset(dev);
1393
1394	return 0;
1395}
1396
1397static void pcl812_detach(struct comedi_device *dev)
1398{
1399	struct pcl812_private *devpriv = dev->private;
1400
1401	if (devpriv) {
1402		if (devpriv->dmabuf[0])
1403			free_pages(devpriv->dmabuf[0], devpriv->dmapages);
1404		if (devpriv->dmabuf[1])
1405			free_pages(devpriv->dmabuf[1], devpriv->dmapages);
1406		if (devpriv->dma)
1407			free_dma(devpriv->dma);
1408	}
1409	comedi_legacy_detach(dev);
1410}
1411
1412static struct comedi_driver pcl812_driver = {
1413	.driver_name	= "pcl812",
1414	.module		= THIS_MODULE,
1415	.attach		= pcl812_attach,
1416	.detach		= pcl812_detach,
1417	.board_name	= &boardtypes[0].name,
1418	.num_names	= ARRAY_SIZE(boardtypes),
1419	.offset		= sizeof(struct pcl812_board),
1420};
1421module_comedi_driver(pcl812_driver);
1422
1423MODULE_AUTHOR("Comedi http://www.comedi.org");
1424MODULE_DESCRIPTION("Comedi low-level driver");
1425MODULE_LICENSE("GPL");
1426