das16.c revision 25436dc9d84f1be60ff549c9ab712bba2835f284
1/*
2    comedi/drivers/das16.c
3    DAS16 driver
4
5    COMEDI - Linux Control and Measurement Device Interface
6    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
7    Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
8    Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24************************************************************************
25*/
26/*
27Driver: das16
28Description: DAS16 compatible boards
29Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
30Devices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g),
31  DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202),
32  DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601),
33  DAS-1602 (das-1602),
34  [ComputerBoards] PC104-DAS16/JR (pc104-das16jr),
35  PC104-DAS16JR/16 (pc104-das16jr/16),
36  CIO-DAS16JR/16 (cio-das16jr/16),
37  CIO-DAS16/JR (cio-das16/jr), CIO-DAS1401/12 (cio-das1401/12),
38  CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16),
39  CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12),
40  CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330)
41Status: works
42Updated: 2003-10-12
43
44A rewrite of the das16 and das1600 drivers.
45Options:
46	[0] - base io address
47	[1] - irq (does nothing, irq is not used anymore)
48	[2] - dma (optional, required for comedi_command support)
49	[3] - master clock speed in MHz (optional, 1 or 10, ignored if
50		board can probe clock, defaults to 1)
51	[4] - analog input range lowest voltage in microvolts (optional,
52		only useful if your board does not have software
53		programmable gain)
54	[5] - analog input range highest voltage in microvolts (optional,
55		only useful if board does not have software programmable
56		gain)
57	[6] - analog output range lowest voltage in microvolts (optional)
58	[7] - analog output range highest voltage in microvolts (optional)
59	[8] - use timer mode for DMA.  Timer mode is needed e.g. for
60		buggy DMA controllers in NS CS5530A (Geode Companion), and for
61		'jr' cards that lack a hardware fifo.  This option is no
62		longer needed, since timer mode is _always_ used.
63
64Passing a zero for an option is the same as leaving it unspecified.
65
66*/
67/*
68
69Testing and debugging help provided by Daniel Koch.
70
71Keithley Manuals:
72	2309.PDF (das16)
73	4919.PDF (das1400, 1600)
74	4922.PDF (das-1400)
75	4923.PDF (das1200, 1400, 1600)
76
77Computer boards manuals also available from their website www.measurementcomputing.com
78
79*/
80
81#include <linux/pci.h>
82#include <linux/interrupt.h>
83#include <asm/dma.h>
84#include "../comedidev.h"
85
86#include "8253.h"
87#include "8255.h"
88#include "comedi_fc.h"
89
90#undef DEBUG
91/* #define DEBUG */
92
93#ifdef DEBUG
94#define DEBUG_PRINT(format, args...) printk("das16: " format, ## args)
95#else
96#define DEBUG_PRINT(format, args...)
97#endif
98
99#define DAS16_SIZE 20		/*  number of ioports */
100#define DAS16_DMA_SIZE 0xff00	/*  size in bytes of allocated dma buffer */
101
102/*
103    cio-das16.pdf
104
105    "das16"
106    "das16/f"
107
108  0	a/d bits 0-3		start 12 bit
109  1	a/d bits 4-11		unused
110  2	mux read		mux set
111  3	di 4 bit		do 4 bit
112  4	unused			ao0_lsb
113  5	unused			ao0_msb
114  6	unused			ao1_lsb
115  7	unused			ao1_msb
116  8	status eoc uni/bip	interrupt reset
117  9	dma, int, trig ctrl	set dma, int
118  a	pacer control		unused
119  b	reserved		reserved
120  cdef	8254
121  0123	8255
122
123*/
124
125/*
126    cio-das16jr.pdf
127
128    "das16jr"
129
130  0	a/d bits 0-3		start 12 bit
131  1	a/d bits 4-11		unused
132  2	mux read		mux set
133  3	di 4 bit		do 4 bit
134  4567	unused			unused
135  8	status eoc uni/bip	interrupt reset
136  9	dma, int, trig ctrl	set dma, int
137  a	pacer control		unused
138  b	gain status		gain control
139  cdef	8254
140
141*/
142
143/*
144    cio-das16jr_16.pdf
145
146    "das16jr_16"
147
148  0	a/d bits 0-7		start 16 bit
149  1	a/d bits 8-15		unused
150  2	mux read		mux set
151  3	di 4 bit		do 4 bit
152  4567	unused			unused
153  8	status eoc uni/bip	interrupt reset
154  9	dma, int, trig ctrl	set dma, int
155  a	pacer control		unused
156  b	gain status		gain control
157  cdef	8254
158
159*/
160/*
161    cio-das160x-1x.pdf
162
163    "das1601/12"
164    "das1602/12"
165    "das1602/16"
166
167  0	a/d bits 0-3		start 12 bit
168  1	a/d bits 4-11		unused
169  2	mux read		mux set
170  3	di 4 bit		do 4 bit
171  4	unused			ao0_lsb
172  5	unused			ao0_msb
173  6	unused			ao1_lsb
174  7	unused			ao1_msb
175  8	status eoc uni/bip	interrupt reset
176  9	dma, int, trig ctrl	set dma, int
177  a	pacer control		unused
178  b	gain status		gain control
179  cdef	8254
180  400	8255
181  404	unused			conversion enable
182  405	unused			burst enable
183  406	unused			das1600 enable
184  407	status
185
186*/
187
188static const int sample_size = 2;	/*  size in bytes of a sample from board */
189
190#define DAS16_TRIG		0
191#define DAS16_AI_LSB		0
192#define DAS16_AI_MSB		1
193#define DAS16_MUX		2
194#define DAS16_DIO		3
195#define DAS16_AO_LSB(x)	((x)?6:4)
196#define DAS16_AO_MSB(x)	((x)?7:5)
197#define DAS16_STATUS		8
198#define   BUSY			(1<<7)
199#define   UNIPOLAR			(1<<6)
200#define   DAS16_MUXBIT			(1<<5)
201#define   DAS16_INT			(1<<4)
202#define DAS16_CONTROL		9
203#define   DAS16_INTE			(1<<7)
204#define   DAS16_IRQ(x)			(((x) & 0x7) << 4)
205#define   DMA_ENABLE			(1<<2)
206#define   PACING_MASK	0x3
207#define   INT_PACER		0x03
208#define   EXT_PACER			0x02
209#define   DAS16_SOFT		0x00
210#define DAS16_PACER		0x0A
211#define   DAS16_CTR0			(1<<1)
212#define   DAS16_TRIG0			(1<<0)
213#define   BURST_LEN_BITS(x)			(((x) & 0xf) << 4)
214#define DAS16_GAIN		0x0B
215#define DAS16_CNTR0_DATA		0x0C
216#define DAS16_CNTR1_DATA		0x0D
217#define DAS16_CNTR2_DATA		0x0E
218#define DAS16_CNTR_CONTROL	0x0F
219#define   DAS16_TERM_CNT	0x00
220#define   DAS16_ONE_SHOT	0x02
221#define   DAS16_RATE_GEN	0x04
222#define   DAS16_CNTR_LSB_MSB	0x30
223#define   DAS16_CNTR0		0x00
224#define   DAS16_CNTR1		0x40
225#define   DAS16_CNTR2		0x80
226
227#define DAS1600_CONV		0x404
228#define   DAS1600_CONV_DISABLE		0x40
229#define DAS1600_BURST		0x405
230#define   DAS1600_BURST_VAL		0x40
231#define DAS1600_ENABLE		0x406
232#define   DAS1600_ENABLE_VAL		0x40
233#define DAS1600_STATUS_B	0x407
234#define   DAS1600_BME		0x40
235#define   DAS1600_ME		0x20
236#define   DAS1600_CD			0x10
237#define   DAS1600_WS			0x02
238#define   DAS1600_CLK_10MHZ		0x01
239
240static const struct comedi_lrange range_das1x01_bip = { 4, {
241			BIP_RANGE(10),
242			BIP_RANGE(1),
243			BIP_RANGE(0.1),
244			BIP_RANGE(0.01),
245	}
246};
247static const struct comedi_lrange range_das1x01_unip = { 4, {
248			UNI_RANGE(10),
249			UNI_RANGE(1),
250			UNI_RANGE(0.1),
251			UNI_RANGE(0.01),
252	}
253};
254static const struct comedi_lrange range_das1x02_bip = { 4, {
255			BIP_RANGE(10),
256			BIP_RANGE(5),
257			BIP_RANGE(2.5),
258			BIP_RANGE(1.25),
259	}
260};
261static const struct comedi_lrange range_das1x02_unip = { 4, {
262			UNI_RANGE(10),
263			UNI_RANGE(5),
264			UNI_RANGE(2.5),
265			UNI_RANGE(1.25),
266	}
267};
268static const struct comedi_lrange range_das16jr = { 9, {
269			/*  also used by 16/330 */
270			BIP_RANGE(10),
271			BIP_RANGE(5),
272			BIP_RANGE(2.5),
273			BIP_RANGE(1.25),
274			BIP_RANGE(0.625),
275			UNI_RANGE(10),
276			UNI_RANGE(5),
277			UNI_RANGE(2.5),
278			UNI_RANGE(1.25),
279	}
280};
281static const struct comedi_lrange range_das16jr_16 = { 8, {
282			BIP_RANGE(10),
283			BIP_RANGE(5),
284			BIP_RANGE(2.5),
285			BIP_RANGE(1.25),
286			UNI_RANGE(10),
287			UNI_RANGE(5),
288			UNI_RANGE(2.5),
289			UNI_RANGE(1.25),
290	}
291};
292
293static const int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 };
294static const int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
295static const int das1600_gainlist[] = { 0, 1, 2, 3 };
296enum {
297	das16_pg_none = 0,
298	das16_pg_16jr,
299	das16_pg_16jr_16,
300	das16_pg_1601,
301	das16_pg_1602,
302};
303static const int *const das16_gainlists[] = {
304	NULL,
305	das16jr_gainlist,
306	das16jr_16_gainlist,
307	das1600_gainlist,
308	das1600_gainlist,
309};
310static const struct comedi_lrange *const das16_ai_uni_lranges[] = {
311	&range_unknown,
312	&range_das16jr,
313	&range_das16jr_16,
314	&range_das1x01_unip,
315	&range_das1x02_unip,
316};
317static const struct comedi_lrange *const das16_ai_bip_lranges[] = {
318	&range_unknown,
319	&range_das16jr,
320	&range_das16jr_16,
321	&range_das1x01_bip,
322	&range_das1x02_bip,
323};
324
325struct munge_info {
326	uint8_t byte;
327	unsigned have_byte:1;
328};
329
330static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
331	struct comedi_insn *insn, unsigned int *data);
332static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
333	struct comedi_insn *insn, unsigned int *data);
334static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
335	struct comedi_insn *insn, unsigned int *data);
336static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
337	struct comedi_insn *insn, unsigned int *data);
338
339static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
340	struct comedi_cmd *cmd);
341static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s);
342static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
343static void das16_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
344	void *array, unsigned int num_bytes, unsigned int start_chan_index);
345
346static void das16_reset(struct comedi_device *dev);
347static irqreturn_t das16_dma_interrupt(int irq, void *d);
348static void das16_timer_interrupt(unsigned long arg);
349static void das16_interrupt(struct comedi_device *dev);
350
351static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
352	int flags);
353static int das1600_mode_detect(struct comedi_device *dev);
354static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
355	struct comedi_cmd cmd);
356
357static void reg_dump(struct comedi_device *dev);
358
359struct das16_board {
360	const char *name;
361	void *ai;
362	unsigned int ai_nbits;
363	unsigned int ai_speed;	/*  max conversion speed in nanosec */
364	unsigned int ai_pg;
365	void *ao;
366	unsigned int ao_nbits;
367	void *di;
368	void *do_;
369
370	unsigned int i8255_offset;
371	unsigned int i8254_offset;
372
373	unsigned int size;
374	unsigned int id;
375};
376
377static const struct das16_board das16_boards[] = {
378	{
379	.name = "das-16",
380	.ai = das16_ai_rinsn,
381	.ai_nbits = 12,
382	.ai_speed = 15000,
383	.ai_pg = das16_pg_none,
384	.ao = das16_ao_winsn,
385	.ao_nbits = 12,
386	.di = das16_di_rbits,
387	.do_ = das16_do_wbits,
388	.i8255_offset = 0x10,
389	.i8254_offset = 0x0c,
390	.size = 0x14,
391	.id = 0x00,
392		},
393	{
394	.name = "das-16g",
395	.ai = das16_ai_rinsn,
396	.ai_nbits = 12,
397	.ai_speed = 15000,
398	.ai_pg = das16_pg_none,
399	.ao = das16_ao_winsn,
400	.ao_nbits = 12,
401	.di = das16_di_rbits,
402	.do_ = das16_do_wbits,
403	.i8255_offset = 0x10,
404	.i8254_offset = 0x0c,
405	.size = 0x14,
406	.id = 0x00,
407		},
408	{
409	.name = "das-16f",
410	.ai = das16_ai_rinsn,
411	.ai_nbits = 12,
412	.ai_speed = 8500,
413	.ai_pg = das16_pg_none,
414	.ao = das16_ao_winsn,
415	.ao_nbits = 12,
416	.di = das16_di_rbits,
417	.do_ = das16_do_wbits,
418	.i8255_offset = 0x10,
419	.i8254_offset = 0x0c,
420	.size = 0x14,
421	.id = 0x00,
422		},
423	{
424	.name = "cio-das16",	/*  cio-das16.pdf */
425	.ai = das16_ai_rinsn,
426	.ai_nbits = 12,
427	.ai_speed = 20000,
428	.ai_pg = das16_pg_none,
429	.ao = das16_ao_winsn,
430	.ao_nbits = 12,
431	.di = das16_di_rbits,
432	.do_ = das16_do_wbits,
433	.i8255_offset = 0x10,
434	.i8254_offset = 0x0c,
435	.size = 0x14,
436	.id = 0x80,
437		},
438	{
439	.name = "cio-das16/f",	/*  das16.pdf */
440	.ai = das16_ai_rinsn,
441	.ai_nbits = 12,
442	.ai_speed = 10000,
443	.ai_pg = das16_pg_none,
444	.ao = das16_ao_winsn,
445	.ao_nbits = 12,
446	.di = das16_di_rbits,
447	.do_ = das16_do_wbits,
448	.i8255_offset = 0x10,
449	.i8254_offset = 0x0c,
450	.size = 0x14,
451	.id = 0x80,
452		},
453	{
454	.name = "cio-das16/jr",	/*  cio-das16jr.pdf */
455	.ai = das16_ai_rinsn,
456	.ai_nbits = 12,
457	.ai_speed = 7692,
458	.ai_pg = das16_pg_16jr,
459	.ao = NULL,
460	.di = das16_di_rbits,
461	.do_ = das16_do_wbits,
462	.i8255_offset = 0,
463	.i8254_offset = 0x0c,
464	.size = 0x10,
465	.id = 0x00,
466		},
467	{
468	.name = "pc104-das16jr",	/*  pc104-das16jr_xx.pdf */
469	.ai = das16_ai_rinsn,
470	.ai_nbits = 12,
471	.ai_speed = 3300,
472	.ai_pg = das16_pg_16jr,
473	.ao = NULL,
474	.di = das16_di_rbits,
475	.do_ = das16_do_wbits,
476	.i8255_offset = 0,
477	.i8254_offset = 0x0c,
478	.size = 0x10,
479	.id = 0x00,
480		},
481	{
482	.name = "cio-das16jr/16",	/*  cio-das16jr_16.pdf */
483	.ai = das16_ai_rinsn,
484	.ai_nbits = 16,
485	.ai_speed = 10000,
486	.ai_pg = das16_pg_16jr_16,
487	.ao = NULL,
488	.di = das16_di_rbits,
489	.do_ = das16_do_wbits,
490	.i8255_offset = 0,
491	.i8254_offset = 0x0c,
492	.size = 0x10,
493	.id = 0x00,
494		},
495	{
496	.name = "pc104-das16jr/16",	/*  pc104-das16jr_xx.pdf */
497	.ai = das16_ai_rinsn,
498	.ai_nbits = 16,
499	.ai_speed = 10000,
500	.ai_pg = das16_pg_16jr_16,
501	.ao = NULL,
502	.di = das16_di_rbits,
503	.do_ = das16_do_wbits,
504	.i8255_offset = 0,
505	.i8254_offset = 0x0c,
506	.size = 0x10,
507	.id = 0x00,
508		},
509	{
510	.name = "das-1201",	/*  4924.pdf (keithley user's manual) */
511	.ai = das16_ai_rinsn,
512	.ai_nbits = 12,
513	.ai_speed = 20000,
514	.ai_pg = das16_pg_none,
515	.ao = NULL,
516	.di = das16_di_rbits,
517	.do_ = das16_do_wbits,
518	.i8255_offset = 0x400,
519	.i8254_offset = 0x0c,
520	.size = 0x408,
521	.id = 0x20,
522		},
523	{
524	.name = "das-1202",	/*  4924.pdf (keithley user's manual) */
525	.ai = das16_ai_rinsn,
526	.ai_nbits = 12,
527	.ai_speed = 10000,
528	.ai_pg = das16_pg_none,
529	.ao = NULL,
530	.di = das16_di_rbits,
531	.do_ = das16_do_wbits,
532	.i8255_offset = 0x400,
533	.i8254_offset = 0x0c,
534	.size = 0x408,
535	.id = 0x20,
536		},
537	{
538	.name = "das-1401",	/*  4919.pdf and 4922.pdf (keithley user's manual) */
539	.ai = das16_ai_rinsn,
540	.ai_nbits = 12,
541	.ai_speed = 10000,
542	.ai_pg = das16_pg_1601,
543	.ao = NULL,
544	.di = das16_di_rbits,
545	.do_ = das16_do_wbits,
546	.i8255_offset = 0x0,
547	.i8254_offset = 0x0c,
548	.size = 0x408,
549	.id = 0xc0	/*  4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */
550		},
551	{
552	.name = "das-1402",	/*  4919.pdf and 4922.pdf (keithley user's manual) */
553	.ai = das16_ai_rinsn,
554	.ai_nbits = 12,
555	.ai_speed = 10000,
556	.ai_pg = das16_pg_1602,
557	.ao = NULL,
558	.di = das16_di_rbits,
559	.do_ = das16_do_wbits,
560	.i8255_offset = 0x0,
561	.i8254_offset = 0x0c,
562	.size = 0x408,
563	.id = 0xc0	/*  4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */
564		},
565	{
566	.name = "das-1601",	/*  4919.pdf */
567	.ai = das16_ai_rinsn,
568	.ai_nbits = 12,
569	.ai_speed = 10000,
570	.ai_pg = das16_pg_1601,
571	.ao = das16_ao_winsn,
572	.ao_nbits = 12,
573	.di = das16_di_rbits,
574	.do_ = das16_do_wbits,
575	.i8255_offset = 0x400,
576	.i8254_offset = 0x0c,
577	.size = 0x408,
578	.id = 0xc0},
579	{
580	.name = "das-1602",	/*  4919.pdf */
581	.ai = das16_ai_rinsn,
582	.ai_nbits = 12,
583	.ai_speed = 10000,
584	.ai_pg = das16_pg_1602,
585	.ao = das16_ao_winsn,
586	.ao_nbits = 12,
587	.di = das16_di_rbits,
588	.do_ = das16_do_wbits,
589	.i8255_offset = 0x400,
590	.i8254_offset = 0x0c,
591	.size = 0x408,
592	.id = 0xc0},
593	{
594	.name = "cio-das1401/12",	/*  cio-das1400_series.pdf */
595	.ai = das16_ai_rinsn,
596	.ai_nbits = 12,
597	.ai_speed = 6250,
598	.ai_pg = das16_pg_1601,
599	.ao = NULL,
600	.di = das16_di_rbits,
601	.do_ = das16_do_wbits,
602	.i8255_offset = 0,
603	.i8254_offset = 0x0c,
604	.size = 0x408,
605	.id = 0xc0},
606	{
607	.name = "cio-das1402/12",	/*  cio-das1400_series.pdf */
608	.ai = das16_ai_rinsn,
609	.ai_nbits = 12,
610	.ai_speed = 6250,
611	.ai_pg = das16_pg_1602,
612	.ao = NULL,
613	.di = das16_di_rbits,
614	.do_ = das16_do_wbits,
615	.i8255_offset = 0,
616	.i8254_offset = 0x0c,
617	.size = 0x408,
618	.id = 0xc0},
619	{
620	.name = "cio-das1402/16",	/*  cio-das1400_series.pdf */
621	.ai = das16_ai_rinsn,
622	.ai_nbits = 16,
623	.ai_speed = 10000,
624	.ai_pg = das16_pg_1602,
625	.ao = NULL,
626	.di = das16_di_rbits,
627	.do_ = das16_do_wbits,
628	.i8255_offset = 0,
629	.i8254_offset = 0x0c,
630	.size = 0x408,
631	.id = 0xc0},
632	{
633	.name = "cio-das1601/12",	/*  cio-das160x-1x.pdf */
634	.ai = das16_ai_rinsn,
635	.ai_nbits = 12,
636	.ai_speed = 6250,
637	.ai_pg = das16_pg_1601,
638	.ao = das16_ao_winsn,
639	.ao_nbits = 12,
640	.di = das16_di_rbits,
641	.do_ = das16_do_wbits,
642	.i8255_offset = 0x400,
643	.i8254_offset = 0x0c,
644	.size = 0x408,
645	.id = 0xc0},
646	{
647	.name = "cio-das1602/12",	/*  cio-das160x-1x.pdf */
648	.ai = das16_ai_rinsn,
649	.ai_nbits = 12,
650	.ai_speed = 10000,
651	.ai_pg = das16_pg_1602,
652	.ao = das16_ao_winsn,
653	.ao_nbits = 12,
654	.di = das16_di_rbits,
655	.do_ = das16_do_wbits,
656	.i8255_offset = 0x400,
657	.i8254_offset = 0x0c,
658	.size = 0x408,
659	.id = 0xc0},
660	{
661	.name = "cio-das1602/16",	/*  cio-das160x-1x.pdf */
662	.ai = das16_ai_rinsn,
663	.ai_nbits = 16,
664	.ai_speed = 10000,
665	.ai_pg = das16_pg_1602,
666	.ao = das16_ao_winsn,
667	.ao_nbits = 12,
668	.di = das16_di_rbits,
669	.do_ = das16_do_wbits,
670	.i8255_offset = 0x400,
671	.i8254_offset = 0x0c,
672	.size = 0x408,
673	.id = 0xc0},
674	{
675	.name = "cio-das16/330",	/*  ? */
676	.ai = das16_ai_rinsn,
677	.ai_nbits = 12,
678	.ai_speed = 3030,
679	.ai_pg = das16_pg_16jr,
680	.ao = NULL,
681	.di = das16_di_rbits,
682	.do_ = das16_do_wbits,
683	.i8255_offset = 0,
684	.i8254_offset = 0x0c,
685	.size = 0x14,
686	.id = 0xf0},
687#if 0
688	{
689	.name = "das16/330i",	/*  ? */
690		},
691	{
692	.name = "das16/jr/ctr5",	/*  ? */
693		},
694	{
695	.name = "cio-das16/m1/16",	/*  cio-das16_m1_16.pdf, this board is a bit quirky, no dma */
696		},
697#endif
698};
699
700static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it);
701static int das16_detach(struct comedi_device *dev);
702static struct comedi_driver driver_das16 = {
703	.driver_name = "das16",
704	.module = THIS_MODULE,
705	.attach = das16_attach,
706	.detach = das16_detach,
707	.board_name = &das16_boards[0].name,
708	.num_names = ARRAY_SIZE(das16_boards),
709	.offset = sizeof(das16_boards[0]),
710};
711
712#define DAS16_TIMEOUT 1000
713
714/* Period for timer interrupt in jiffies.  It's a function
715 * to deal with possibility of dynamic HZ patches  */
716static inline int timer_period(void)
717{
718	return HZ / 20;
719}
720struct das16_private_struct {
721	unsigned int ai_unipolar;	/*  unipolar flag */
722	unsigned int ai_singleended;	/*  single ended flag */
723	unsigned int clockbase;	/*  master clock speed in ns */
724	volatile unsigned int control_state;	/*  dma, interrupt and trigger control bits */
725	volatile unsigned long adc_byte_count;	/*  number of bytes remaining */
726	unsigned int divisor1;	/*  divisor dividing master clock to get conversion frequency */
727	unsigned int divisor2;	/*  divisor dividing master clock to get conversion frequency */
728	unsigned int dma_chan;	/*  dma channel */
729	uint16_t *dma_buffer[2];
730	dma_addr_t dma_buffer_addr[2];
731	unsigned int current_buffer;
732	volatile unsigned int dma_transfer_size;	/*  target number of bytes to transfer per dma shot */
733	/*  user-defined analog input and output ranges defined from config options */
734	struct comedi_lrange *user_ai_range_table;
735	struct comedi_lrange *user_ao_range_table;
736
737	struct timer_list timer;	/*  for timed interrupt */
738	volatile short timer_running;
739	volatile short timer_mode;	/*  true if using timer mode */
740};
741#define devpriv ((struct das16_private_struct *)(dev->private))
742#define thisboard ((struct das16_board *)(dev->board_ptr))
743
744static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
745	struct comedi_cmd *cmd)
746{
747	int err = 0, tmp;
748	int gain, start_chan, i;
749	int mask;
750
751	/* make sure triggers are valid */
752	tmp = cmd->start_src;
753	cmd->start_src &= TRIG_NOW;
754	if (!cmd->start_src || tmp != cmd->start_src)
755		err++;
756
757	tmp = cmd->scan_begin_src;
758	mask = TRIG_FOLLOW;
759	/*  if board supports burst mode */
760	if (thisboard->size > 0x400)
761		mask |= TRIG_TIMER | TRIG_EXT;
762	cmd->scan_begin_src &= mask;
763	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
764		err++;
765
766	tmp = cmd->convert_src;
767	mask = TRIG_TIMER | TRIG_EXT;
768	/*  if board supports burst mode */
769	if (thisboard->size > 0x400)
770		mask |= TRIG_NOW;
771	cmd->convert_src &= mask;
772	if (!cmd->convert_src || tmp != cmd->convert_src)
773		err++;
774
775	tmp = cmd->scan_end_src;
776	cmd->scan_end_src &= TRIG_COUNT;
777	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
778		err++;
779
780	tmp = cmd->stop_src;
781	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
782	if (!cmd->stop_src || tmp != cmd->stop_src)
783		err++;
784
785	if (err)
786		return 1;
787
788	/* step 2: make sure trigger sources are unique and mutually compatible */
789	if (cmd->scan_begin_src != TRIG_TIMER &&
790		cmd->scan_begin_src != TRIG_EXT &&
791		cmd->scan_begin_src != TRIG_FOLLOW)
792		err++;
793	if (cmd->convert_src != TRIG_TIMER &&
794		cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
795		err++;
796	if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
797		err++;
798
799	/*  make sure scan_begin_src and convert_src dont conflict */
800	if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
801		err++;
802	if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
803		err++;
804
805	if (err)
806		return 2;
807
808	/* step 3: make sure arguments are trivially compatible */
809	if (cmd->start_arg != 0) {
810		cmd->start_arg = 0;
811		err++;
812	}
813
814	if (cmd->scan_begin_src == TRIG_FOLLOW) {
815		/* internal trigger */
816		if (cmd->scan_begin_arg != 0) {
817			cmd->scan_begin_arg = 0;
818			err++;
819		}
820	}
821
822	if (cmd->scan_end_arg != cmd->chanlist_len) {
823		cmd->scan_end_arg = cmd->chanlist_len;
824		err++;
825	}
826	/*  check against maximum frequency */
827	if (cmd->scan_begin_src == TRIG_TIMER) {
828		if (cmd->scan_begin_arg <
829			thisboard->ai_speed * cmd->chanlist_len) {
830			cmd->scan_begin_arg =
831				thisboard->ai_speed * cmd->chanlist_len;
832			err++;
833		}
834	}
835	if (cmd->convert_src == TRIG_TIMER) {
836		if (cmd->convert_arg < thisboard->ai_speed) {
837			cmd->convert_arg = thisboard->ai_speed;
838			err++;
839		}
840	}
841
842	if (cmd->stop_src == TRIG_NONE) {
843		if (cmd->stop_arg != 0) {
844			cmd->stop_arg = 0;
845			err++;
846		}
847	}
848	if (err)
849		return 3;
850
851	/*  step 4: fix up arguments */
852	if (cmd->scan_begin_src == TRIG_TIMER) {
853		unsigned int tmp = cmd->scan_begin_arg;
854		/*  set divisors, correct timing arguments */
855		i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
856			&(devpriv->divisor1), &(devpriv->divisor2),
857			&(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
858		err += (tmp != cmd->scan_begin_arg);
859	}
860	if (cmd->convert_src == TRIG_TIMER) {
861		unsigned int tmp = cmd->convert_arg;
862		/*  set divisors, correct timing arguments */
863		i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
864			&(devpriv->divisor1), &(devpriv->divisor2),
865			&(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
866		err += (tmp != cmd->convert_arg);
867	}
868	if (err)
869		return 4;
870
871	/*  check channel/gain list against card's limitations */
872	if (cmd->chanlist) {
873		gain = CR_RANGE(cmd->chanlist[0]);
874		start_chan = CR_CHAN(cmd->chanlist[0]);
875		for (i = 1; i < cmd->chanlist_len; i++) {
876			if (CR_CHAN(cmd->chanlist[i]) !=
877				(start_chan + i) % s->n_chan) {
878				comedi_error(dev,
879					"entries in chanlist must be consecutive channels, counting upwards\n");
880				err++;
881			}
882			if (CR_RANGE(cmd->chanlist[i]) != gain) {
883				comedi_error(dev,
884					"entries in chanlist must all have the same gain\n");
885				err++;
886			}
887		}
888	}
889	if (err)
890		return 5;
891
892	return 0;
893}
894
895static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
896{
897	struct comedi_async *async = s->async;
898	struct comedi_cmd *cmd = &async->cmd;
899	unsigned int byte;
900	unsigned long flags;
901	int range;
902
903	if (devpriv->dma_chan == 0 || (dev->irq == 0
904			&& devpriv->timer_mode == 0)) {
905		comedi_error(dev,
906			"irq (or use of 'timer mode') dma required to execute comedi_cmd");
907		return -1;
908	}
909	if (cmd->flags & TRIG_RT) {
910		comedi_error(dev,
911			"isa dma transfers cannot be performed with TRIG_RT, aborting");
912		return -1;
913	}
914
915	devpriv->adc_byte_count =
916		cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t);
917
918	/*  disable conversions for das1600 mode */
919	if (thisboard->size > 0x400) {
920		outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV);
921	}
922	/*  set scan limits */
923	byte = CR_CHAN(cmd->chanlist[0]);
924	byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4;
925	outb(byte, dev->iobase + DAS16_MUX);
926
927	/* set gain (this is also burst rate register but according to
928	 * computer boards manual, burst rate does nothing, even on keithley cards) */
929	if (thisboard->ai_pg != das16_pg_none) {
930		range = CR_RANGE(cmd->chanlist[0]);
931		outb((das16_gainlists[thisboard->ai_pg])[range],
932			dev->iobase + DAS16_GAIN);
933	}
934
935	/* set counter mode and counts */
936	cmd->convert_arg =
937		das16_set_pacer(dev, cmd->convert_arg,
938		cmd->flags & TRIG_ROUND_MASK);
939	DEBUG_PRINT("pacer period: %d ns\n", cmd->convert_arg);
940
941	/* enable counters */
942	byte = 0;
943	/* Enable burst mode if appropriate. */
944	if (thisboard->size > 0x400) {
945		if (cmd->convert_src == TRIG_NOW) {
946			outb(DAS1600_BURST_VAL, dev->iobase + DAS1600_BURST);
947			/*  set burst length */
948			byte |= BURST_LEN_BITS(cmd->chanlist_len - 1);
949		} else {
950			outb(0, dev->iobase + DAS1600_BURST);
951		}
952	}
953	outb(byte, dev->iobase + DAS16_PACER);
954
955	/*  set up dma transfer */
956	flags = claim_dma_lock();
957	disable_dma(devpriv->dma_chan);
958	/* clear flip-flop to make sure 2-byte registers for
959	 * count and address get set correctly */
960	clear_dma_ff(devpriv->dma_chan);
961	devpriv->current_buffer = 0;
962	set_dma_addr(devpriv->dma_chan,
963		devpriv->dma_buffer_addr[devpriv->current_buffer]);
964	/*  set appropriate size of transfer */
965	devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, *cmd);
966	set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
967	enable_dma(devpriv->dma_chan);
968	release_dma_lock(flags);
969
970	/*  set up interrupt */
971	if (devpriv->timer_mode) {
972		devpriv->timer_running = 1;
973		devpriv->timer.expires = jiffies + timer_period();
974		add_timer(&devpriv->timer);
975		devpriv->control_state &= ~DAS16_INTE;
976	} else {
977		/* clear interrupt bit */
978		outb(0x00, dev->iobase + DAS16_STATUS);
979		/* enable interrupts */
980		devpriv->control_state |= DAS16_INTE;
981	}
982	devpriv->control_state |= DMA_ENABLE;
983	devpriv->control_state &= ~PACING_MASK;
984	if (cmd->convert_src == TRIG_EXT)
985		devpriv->control_state |= EXT_PACER;
986	else
987		devpriv->control_state |= INT_PACER;
988	outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
989
990	/* Enable conversions if using das1600 mode */
991	if (thisboard->size > 0x400) {
992		outb(0, dev->iobase + DAS1600_CONV);
993	}
994
995	return 0;
996}
997
998static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
999{
1000	unsigned long flags;
1001
1002	spin_lock_irqsave(&dev->spinlock, flags);
1003	/* disable interrupts, dma and pacer clocked conversions */
1004	devpriv->control_state &= ~DAS16_INTE & ~PACING_MASK & ~DMA_ENABLE;
1005	outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1006	if (devpriv->dma_chan)
1007		disable_dma(devpriv->dma_chan);
1008
1009	/*  disable SW timer */
1010	if (devpriv->timer_mode && devpriv->timer_running) {
1011		devpriv->timer_running = 0;
1012		del_timer(&devpriv->timer);
1013	}
1014
1015	/* disable burst mode */
1016	if (thisboard->size > 0x400) {
1017		outb(0, dev->iobase + DAS1600_BURST);
1018	}
1019
1020	spin_unlock_irqrestore(&dev->spinlock, flags);
1021
1022	return 0;
1023}
1024
1025static void das16_reset(struct comedi_device *dev)
1026{
1027	outb(0, dev->iobase + DAS16_STATUS);
1028	outb(0, dev->iobase + DAS16_CONTROL);
1029	outb(0, dev->iobase + DAS16_PACER);
1030	outb(0, dev->iobase + DAS16_CNTR_CONTROL);
1031}
1032
1033static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
1034	struct comedi_insn *insn, unsigned int *data)
1035{
1036	int i, n;
1037	int range;
1038	int chan;
1039	int msb, lsb;
1040
1041	/*  disable interrupts and pacing */
1042	devpriv->control_state &= ~DAS16_INTE & ~DMA_ENABLE & ~PACING_MASK;
1043	outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1044
1045	/* set multiplexer */
1046	chan = CR_CHAN(insn->chanspec);
1047	chan |= CR_CHAN(insn->chanspec) << 4;
1048	outb(chan, dev->iobase + DAS16_MUX);
1049
1050	/* set gain */
1051	if (thisboard->ai_pg != das16_pg_none) {
1052		range = CR_RANGE(insn->chanspec);
1053		outb((das16_gainlists[thisboard->ai_pg])[range],
1054			dev->iobase + DAS16_GAIN);
1055	}
1056
1057	for (n = 0; n < insn->n; n++) {
1058		/* trigger conversion */
1059		outb_p(0, dev->iobase + DAS16_TRIG);
1060
1061		for (i = 0; i < DAS16_TIMEOUT; i++) {
1062			if (!(inb(dev->iobase + DAS16_STATUS) & BUSY))
1063				break;
1064		}
1065		if (i == DAS16_TIMEOUT) {
1066			printk("das16: timeout\n");
1067			return -ETIME;
1068		}
1069		msb = inb(dev->iobase + DAS16_AI_MSB);
1070		lsb = inb(dev->iobase + DAS16_AI_LSB);
1071		if (thisboard->ai_nbits == 12) {
1072			data[n] = ((lsb >> 4) & 0xf) | (msb << 4);
1073		} else {
1074			data[n] = lsb | (msb << 8);
1075		}
1076	}
1077
1078	return n;
1079}
1080
1081static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
1082	struct comedi_insn *insn, unsigned int *data)
1083{
1084	unsigned int bits;
1085
1086	bits = inb(dev->iobase + DAS16_DIO) & 0xf;
1087	data[1] = bits;
1088	data[0] = 0;
1089
1090	return 2;
1091}
1092
1093static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
1094	struct comedi_insn *insn, unsigned int *data)
1095{
1096	unsigned int wbits;
1097
1098	/*  only set bits that have been masked */
1099	data[0] &= 0xf;
1100	wbits = s->state;
1101	/*  zero bits that have been masked */
1102	wbits &= ~data[0];
1103	/*  set masked bits */
1104	wbits |= data[0] & data[1];
1105	s->state = wbits;
1106	data[1] = wbits;
1107
1108	outb(s->state, dev->iobase + DAS16_DIO);
1109
1110	return 2;
1111}
1112
1113static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
1114	struct comedi_insn *insn, unsigned int *data)
1115{
1116	int i;
1117	int lsb, msb;
1118	int chan;
1119
1120	chan = CR_CHAN(insn->chanspec);
1121
1122	for (i = 0; i < insn->n; i++) {
1123		if (thisboard->ao_nbits == 12) {
1124			lsb = (data[i] << 4) & 0xff;
1125			msb = (data[i] >> 4) & 0xff;
1126		} else {
1127			lsb = data[i] & 0xff;
1128			msb = (data[i] >> 8) & 0xff;
1129		}
1130		outb(lsb, dev->iobase + DAS16_AO_LSB(chan));
1131		outb(msb, dev->iobase + DAS16_AO_MSB(chan));
1132	}
1133
1134	return i;
1135}
1136
1137static irqreturn_t das16_dma_interrupt(int irq, void *d)
1138{
1139	int status;
1140	struct comedi_device *dev = d;
1141
1142	status = inb(dev->iobase + DAS16_STATUS);
1143
1144	if ((status & DAS16_INT) == 0) {
1145		DEBUG_PRINT("spurious interrupt\n");
1146		return IRQ_NONE;
1147	}
1148
1149	/* clear interrupt */
1150	outb(0x00, dev->iobase + DAS16_STATUS);
1151	das16_interrupt(dev);
1152	return IRQ_HANDLED;
1153}
1154
1155static void das16_timer_interrupt(unsigned long arg)
1156{
1157	struct comedi_device *dev = (struct comedi_device *) arg;
1158
1159	das16_interrupt(dev);
1160
1161	if (devpriv->timer_running)
1162		mod_timer(&devpriv->timer, jiffies + timer_period());
1163}
1164
1165/* the pc104-das16jr (at least) has problems if the dma
1166	transfer is interrupted in the middle of transferring
1167	a 16 bit sample, so this function takes care to get
1168	an even transfer count after disabling dma
1169	channel.
1170*/
1171static int disable_dma_on_even(struct comedi_device *dev)
1172{
1173	int residue;
1174	int i;
1175	static const int disable_limit = 100;
1176	static const int enable_timeout = 100;
1177	disable_dma(devpriv->dma_chan);
1178	residue = get_dma_residue(devpriv->dma_chan);
1179	for (i = 0; i < disable_limit && (residue % 2); ++i) {
1180		int j;
1181		enable_dma(devpriv->dma_chan);
1182		for (j = 0; j < enable_timeout; ++j) {
1183			int new_residue;
1184			udelay(2);
1185			new_residue = get_dma_residue(devpriv->dma_chan);
1186			if (new_residue != residue)
1187				break;
1188		}
1189		disable_dma(devpriv->dma_chan);
1190		residue = get_dma_residue(devpriv->dma_chan);
1191	}
1192	if (i == disable_limit) {
1193		comedi_error(dev,
1194			"failed to get an even dma transfer, could be trouble.");
1195	}
1196	return residue;
1197}
1198
1199static void das16_interrupt(struct comedi_device *dev)
1200{
1201	unsigned long dma_flags, spin_flags;
1202	struct comedi_subdevice *s = dev->read_subdev;
1203	struct comedi_async *async;
1204	struct comedi_cmd *cmd;
1205	int num_bytes, residue;
1206	int buffer_index;
1207
1208	if (dev->attached == 0) {
1209		comedi_error(dev, "premature interrupt");
1210		return;
1211	}
1212	/*  initialize async here to make sure it is not NULL */
1213	async = s->async;
1214	cmd = &async->cmd;
1215
1216	if (devpriv->dma_chan == 0) {
1217		comedi_error(dev, "interrupt with no dma channel?");
1218		return;
1219	}
1220
1221	spin_lock_irqsave(&dev->spinlock, spin_flags);
1222	if ((devpriv->control_state & DMA_ENABLE) == 0) {
1223		spin_unlock_irqrestore(&dev->spinlock, spin_flags);
1224		DEBUG_PRINT("interrupt while dma disabled?\n");
1225		return;
1226	}
1227
1228	dma_flags = claim_dma_lock();
1229	clear_dma_ff(devpriv->dma_chan);
1230	residue = disable_dma_on_even(dev);
1231
1232	/*  figure out how many points to read */
1233	if (residue > devpriv->dma_transfer_size) {
1234		comedi_error(dev, "residue > transfer size!\n");
1235		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1236		num_bytes = 0;
1237	} else
1238		num_bytes = devpriv->dma_transfer_size - residue;
1239
1240	if (cmd->stop_src == TRIG_COUNT && num_bytes >= devpriv->adc_byte_count) {
1241		num_bytes = devpriv->adc_byte_count;
1242		async->events |= COMEDI_CB_EOA;
1243	}
1244
1245	buffer_index = devpriv->current_buffer;
1246	devpriv->current_buffer = (devpriv->current_buffer + 1) % 2;
1247	devpriv->adc_byte_count -= num_bytes;
1248
1249	/*  figure out how many bytes for next transfer */
1250	if (cmd->stop_src == TRIG_COUNT && devpriv->timer_mode == 0 &&
1251		devpriv->dma_transfer_size > devpriv->adc_byte_count)
1252		devpriv->dma_transfer_size = devpriv->adc_byte_count;
1253
1254	/*  re-enable  dma */
1255	if ((async->events & COMEDI_CB_EOA) == 0) {
1256		set_dma_addr(devpriv->dma_chan,
1257			devpriv->dma_buffer_addr[devpriv->current_buffer]);
1258		set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
1259		enable_dma(devpriv->dma_chan);
1260		/* reenable conversions for das1600 mode, (stupid hardware) */
1261		if (thisboard->size > 0x400 && devpriv->timer_mode == 0) {
1262			outb(0x00, dev->iobase + DAS1600_CONV);
1263		}
1264	}
1265	release_dma_lock(dma_flags);
1266
1267	spin_unlock_irqrestore(&dev->spinlock, spin_flags);
1268
1269	cfc_write_array_to_buffer(s,
1270		devpriv->dma_buffer[buffer_index], num_bytes);
1271
1272	cfc_handle_events(dev, s);
1273}
1274
1275static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
1276	int rounding_flags)
1277{
1278	i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1),
1279		&(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK);
1280
1281	/* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1282	i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 1, devpriv->divisor1, 2);
1283	i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 2, devpriv->divisor2, 2);
1284
1285	return ns;
1286}
1287
1288static void reg_dump(struct comedi_device *dev)
1289{
1290	DEBUG_PRINT("********DAS1600 REGISTER DUMP********\n");
1291	DEBUG_PRINT("DAS16_MUX: %x\n", inb(dev->iobase + DAS16_MUX));
1292	DEBUG_PRINT("DAS16_DIO: %x\n", inb(dev->iobase + DAS16_DIO));
1293	DEBUG_PRINT("DAS16_STATUS: %x\n", inb(dev->iobase + DAS16_STATUS));
1294	DEBUG_PRINT("DAS16_CONTROL: %x\n", inb(dev->iobase + DAS16_CONTROL));
1295	DEBUG_PRINT("DAS16_PACER: %x\n", inb(dev->iobase + DAS16_PACER));
1296	DEBUG_PRINT("DAS16_GAIN: %x\n", inb(dev->iobase + DAS16_GAIN));
1297	DEBUG_PRINT("DAS16_CNTR_CONTROL: %x\n",
1298		inb(dev->iobase + DAS16_CNTR_CONTROL));
1299	DEBUG_PRINT("DAS1600_CONV: %x\n", inb(dev->iobase + DAS1600_CONV));
1300	DEBUG_PRINT("DAS1600_BURST: %x\n", inb(dev->iobase + DAS1600_BURST));
1301	DEBUG_PRINT("DAS1600_ENABLE: %x\n", inb(dev->iobase + DAS1600_ENABLE));
1302	DEBUG_PRINT("DAS1600_STATUS_B: %x\n",
1303		inb(dev->iobase + DAS1600_STATUS_B));
1304}
1305
1306static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it)
1307{
1308	int status;
1309	int diobits;
1310
1311	/* status is available on all boards */
1312
1313	status = inb(dev->iobase + DAS16_STATUS);
1314
1315	if ((status & UNIPOLAR)) {
1316		devpriv->ai_unipolar = 1;
1317	} else {
1318		devpriv->ai_unipolar = 0;
1319	}
1320
1321	if ((status & DAS16_MUXBIT)) {
1322		devpriv->ai_singleended = 1;
1323	} else {
1324		devpriv->ai_singleended = 0;
1325	}
1326
1327	/* diobits indicates boards */
1328
1329	diobits = inb(dev->iobase + DAS16_DIO) & 0xf0;
1330
1331	printk(" id bits are 0x%02x\n", diobits);
1332	if (thisboard->id != diobits) {
1333		printk(" requested board's id bits are 0x%x (ignore)\n",
1334			thisboard->id);
1335	}
1336
1337	return 0;
1338}
1339
1340static int das1600_mode_detect(struct comedi_device *dev)
1341{
1342	int status = 0;
1343
1344	status = inb(dev->iobase + DAS1600_STATUS_B);
1345
1346	if (status & DAS1600_CLK_10MHZ) {
1347		devpriv->clockbase = 100;
1348		printk(" 10MHz pacer clock\n");
1349	} else {
1350		devpriv->clockbase = 1000;
1351		printk(" 1MHz pacer clock\n");
1352	}
1353
1354	reg_dump(dev);
1355
1356	return 0;
1357}
1358
1359/*
1360 *
1361 * Options list:
1362 *   0  I/O base
1363 *   1  IRQ
1364 *   2  DMA
1365 *   3  Clock speed (in MHz)
1366 */
1367
1368static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1369{
1370	struct comedi_subdevice *s;
1371	int ret;
1372	unsigned int irq;
1373	unsigned long iobase;
1374	unsigned int dma_chan;
1375	int timer_mode;
1376	unsigned long flags;
1377	struct comedi_krange *user_ai_range, *user_ao_range;
1378
1379	iobase = it->options[0];
1380#if 0
1381	irq = it->options[1];
1382	timer_mode = it->options[8];
1383#endif
1384	/* always use time_mode since using irq can drop samples while
1385	 * waiting for dma done interrupt (due to hardware limitations) */
1386	irq = 0;
1387	timer_mode = 1;
1388	if (timer_mode)
1389		irq = 0;
1390
1391	printk("comedi%d: das16:", dev->minor);
1392
1393	/*  check that clock setting is valid */
1394	if (it->options[3]) {
1395		if (it->options[3] != 0 &&
1396			it->options[3] != 1 && it->options[3] != 10) {
1397			printk("\n Invalid option.  Master clock must be set to 1 or 10 (MHz)\n");
1398			return -EINVAL;
1399		}
1400	}
1401
1402	ret = alloc_private(dev, sizeof(struct das16_private_struct));
1403	if (ret < 0)
1404		return ret;
1405
1406	if (thisboard->size < 0x400) {
1407		printk(" 0x%04lx-0x%04lx\n", iobase, iobase + thisboard->size);
1408		if (!request_region(iobase, thisboard->size, "das16")) {
1409			printk(" I/O port conflict\n");
1410			return -EIO;
1411		}
1412	} else {
1413		printk(" 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n",
1414			iobase, iobase + 0x0f,
1415			iobase + 0x400,
1416			iobase + 0x400 + (thisboard->size & 0x3ff));
1417		if (!request_region(iobase, 0x10, "das16")) {
1418			printk(" I/O port conflict:  0x%04lx-0x%04lx\n",
1419				iobase, iobase + 0x0f);
1420			return -EIO;
1421		}
1422		if (!request_region(iobase + 0x400, thisboard->size & 0x3ff,
1423				"das16")) {
1424			release_region(iobase, 0x10);
1425			printk(" I/O port conflict:  0x%04lx-0x%04lx\n",
1426				iobase + 0x400,
1427				iobase + 0x400 + (thisboard->size & 0x3ff));
1428			return -EIO;
1429		}
1430	}
1431
1432	dev->iobase = iobase;
1433
1434	/*  probe id bits to make sure they are consistent */
1435	if (das16_probe(dev, it)) {
1436		printk(" id bits do not match selected board, aborting\n");
1437		return -EINVAL;
1438	}
1439	dev->board_name = thisboard->name;
1440
1441	/*  get master clock speed */
1442	if (thisboard->size < 0x400) {
1443		if (it->options[3])
1444			devpriv->clockbase = 1000 / it->options[3];
1445		else
1446			devpriv->clockbase = 1000;	/*  1 MHz default */
1447	} else {
1448		das1600_mode_detect(dev);
1449	}
1450
1451	/* now for the irq */
1452	if (irq > 1 && irq < 8) {
1453		ret = request_irq(irq, das16_dma_interrupt, 0, "das16", dev);
1454
1455		if (ret < 0)
1456			return ret;
1457		dev->irq = irq;
1458		printk(" ( irq = %u )", irq);
1459	} else if (irq == 0) {
1460		printk(" ( no irq )");
1461	} else {
1462		printk(" invalid irq\n");
1463		return -EINVAL;
1464	}
1465
1466	/*  initialize dma */
1467	dma_chan = it->options[2];
1468	if (dma_chan == 1 || dma_chan == 3) {
1469		/*  allocate dma buffers */
1470		int i;
1471		for (i = 0; i < 2; i++) {
1472			devpriv->dma_buffer[i] = pci_alloc_consistent(NULL,
1473				DAS16_DMA_SIZE, &devpriv->dma_buffer_addr[i]);
1474			if (devpriv->dma_buffer[i] == NULL)
1475				return -ENOMEM;
1476		}
1477		if (request_dma(dma_chan, "das16")) {
1478			printk(" failed to allocate dma channel %i\n",
1479				dma_chan);
1480			return -EINVAL;
1481		}
1482		devpriv->dma_chan = dma_chan;
1483		flags = claim_dma_lock();
1484		disable_dma(devpriv->dma_chan);
1485		set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
1486		release_dma_lock(flags);
1487		printk(" ( dma = %u)\n", dma_chan);
1488	} else if (dma_chan == 0) {
1489		printk(" ( no dma )\n");
1490	} else {
1491		printk(" invalid dma channel\n");
1492		return -EINVAL;
1493	}
1494
1495	/*  get any user-defined input range */
1496	if (thisboard->ai_pg == das16_pg_none &&
1497		(it->options[4] || it->options[5])) {
1498		/*  allocate single-range range table */
1499		devpriv->user_ai_range_table =
1500			kmalloc(sizeof(struct comedi_lrange) + sizeof(struct comedi_krange),
1501			GFP_KERNEL);
1502		/*  initialize ai range */
1503		devpriv->user_ai_range_table->length = 1;
1504		user_ai_range = devpriv->user_ai_range_table->range;
1505		user_ai_range->min = it->options[4];
1506		user_ai_range->max = it->options[5];
1507		user_ai_range->flags = UNIT_volt;
1508	}
1509	/*  get any user-defined output range */
1510	if (it->options[6] || it->options[7]) {
1511		/*  allocate single-range range table */
1512		devpriv->user_ao_range_table =
1513			kmalloc(sizeof(struct comedi_lrange) + sizeof(struct comedi_krange),
1514			GFP_KERNEL);
1515		/*  initialize ao range */
1516		devpriv->user_ao_range_table->length = 1;
1517		user_ao_range = devpriv->user_ao_range_table->range;
1518		user_ao_range->min = it->options[6];
1519		user_ao_range->max = it->options[7];
1520		user_ao_range->flags = UNIT_volt;
1521	}
1522
1523	if (timer_mode) {
1524		init_timer(&(devpriv->timer));
1525		devpriv->timer.function = das16_timer_interrupt;
1526		devpriv->timer.data = (unsigned long)dev;
1527	}
1528	devpriv->timer_mode = timer_mode ? 1 : 0;
1529
1530	ret = alloc_subdevices(dev, 5);
1531	if (ret < 0)
1532		return ret;
1533
1534	s = dev->subdevices + 0;
1535	dev->read_subdev = s;
1536	/* ai */
1537	if (thisboard->ai) {
1538		s->type = COMEDI_SUBD_AI;
1539		s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
1540		if (devpriv->ai_singleended) {
1541			s->n_chan = 16;
1542			s->len_chanlist = 16;
1543			s->subdev_flags |= SDF_GROUND;
1544		} else {
1545			s->n_chan = 8;
1546			s->len_chanlist = 8;
1547			s->subdev_flags |= SDF_DIFF;
1548		}
1549		s->maxdata = (1 << thisboard->ai_nbits) - 1;
1550		if (devpriv->user_ai_range_table) {	/*  user defined ai range */
1551			s->range_table = devpriv->user_ai_range_table;
1552		} else if (devpriv->ai_unipolar) {
1553			s->range_table = das16_ai_uni_lranges[thisboard->ai_pg];
1554		} else {
1555			s->range_table = das16_ai_bip_lranges[thisboard->ai_pg];
1556		}
1557		s->insn_read = thisboard->ai;
1558		s->do_cmdtest = das16_cmd_test;
1559		s->do_cmd = das16_cmd_exec;
1560		s->cancel = das16_cancel;
1561		s->munge = das16_ai_munge;
1562	} else {
1563		s->type = COMEDI_SUBD_UNUSED;
1564	}
1565
1566	s = dev->subdevices + 1;
1567	/* ao */
1568	if (thisboard->ao) {
1569		s->type = COMEDI_SUBD_AO;
1570		s->subdev_flags = SDF_WRITABLE;
1571		s->n_chan = 2;
1572		s->maxdata = (1 << thisboard->ao_nbits) - 1;
1573		if (devpriv->user_ao_range_table) {	/*  user defined ao range */
1574			s->range_table = devpriv->user_ao_range_table;
1575		} else {
1576			s->range_table = &range_unknown;
1577		}
1578		s->insn_write = thisboard->ao;
1579	} else {
1580		s->type = COMEDI_SUBD_UNUSED;
1581	}
1582
1583	s = dev->subdevices + 2;
1584	/* di */
1585	if (thisboard->di) {
1586		s->type = COMEDI_SUBD_DI;
1587		s->subdev_flags = SDF_READABLE;
1588		s->n_chan = 4;
1589		s->maxdata = 1;
1590		s->range_table = &range_digital;
1591		s->insn_bits = thisboard->di;
1592	} else {
1593		s->type = COMEDI_SUBD_UNUSED;
1594	}
1595
1596	s = dev->subdevices + 3;
1597	/* do */
1598	if (thisboard->do_) {
1599		s->type = COMEDI_SUBD_DO;
1600		s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1601		s->n_chan = 4;
1602		s->maxdata = 1;
1603		s->range_table = &range_digital;
1604		s->insn_bits = thisboard->do_;
1605		/*  initialize digital output lines */
1606		outb(s->state, dev->iobase + DAS16_DIO);
1607	} else {
1608		s->type = COMEDI_SUBD_UNUSED;
1609	}
1610
1611	s = dev->subdevices + 4;
1612	/* 8255 */
1613	if (thisboard->i8255_offset != 0) {
1614		subdev_8255_init(dev, s, NULL, (dev->iobase +
1615				thisboard->i8255_offset));
1616	} else {
1617		s->type = COMEDI_SUBD_UNUSED;
1618	}
1619
1620	das16_reset(dev);
1621	/* set the interrupt level */
1622	devpriv->control_state = DAS16_IRQ(dev->irq);
1623	outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1624
1625	/*  turn on das1600 mode if available */
1626	if (thisboard->size > 0x400) {
1627		outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE);
1628		outb(0, dev->iobase + DAS1600_CONV);
1629		outb(0, dev->iobase + DAS1600_BURST);
1630	}
1631
1632	return 0;
1633}
1634
1635static int das16_detach(struct comedi_device *dev)
1636{
1637	printk("comedi%d: das16: remove\n", dev->minor);
1638
1639	das16_reset(dev);
1640
1641	if (dev->subdevices)
1642		subdev_8255_cleanup(dev, dev->subdevices + 4);
1643
1644	if (devpriv) {
1645		int i;
1646		for (i = 0; i < 2; i++) {
1647			if (devpriv->dma_buffer[i])
1648				pci_free_consistent(NULL, DAS16_DMA_SIZE,
1649					devpriv->dma_buffer[i],
1650					devpriv->dma_buffer_addr[i]);
1651		}
1652		if (devpriv->dma_chan)
1653			free_dma(devpriv->dma_chan);
1654		if (devpriv->user_ai_range_table)
1655			kfree(devpriv->user_ai_range_table);
1656		if (devpriv->user_ao_range_table)
1657			kfree(devpriv->user_ao_range_table);
1658	}
1659
1660	if (dev->irq)
1661		free_irq(dev->irq, dev);
1662
1663	if (dev->iobase) {
1664		if (thisboard->size < 0x400) {
1665			release_region(dev->iobase, thisboard->size);
1666		} else {
1667			release_region(dev->iobase, 0x10);
1668			release_region(dev->iobase + 0x400,
1669				thisboard->size & 0x3ff);
1670		}
1671	}
1672
1673	return 0;
1674}
1675
1676COMEDI_INITCLEANUP(driver_das16);
1677
1678/* utility function that suggests a dma transfer size in bytes */
1679static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
1680	struct comedi_cmd cmd)
1681{
1682	unsigned int size;
1683	unsigned int freq;
1684
1685	/* if we are using timer interrupt, we don't care how long it
1686	 * will take to complete transfer since it will be interrupted
1687	 * by timer interrupt */
1688	if (devpriv->timer_mode)
1689		return DAS16_DMA_SIZE;
1690
1691	/* otherwise, we are relying on dma terminal count interrupt,
1692	 * so pick a reasonable size */
1693	if (cmd.convert_src == TRIG_TIMER)
1694		freq = 1000000000 / cmd.convert_arg;
1695	else if (cmd.scan_begin_src == TRIG_TIMER)
1696		freq = (1000000000 / cmd.scan_begin_arg) * cmd.chanlist_len;
1697	/*  return some default value */
1698	else
1699		freq = 0xffffffff;
1700
1701	if (cmd.flags & TRIG_WAKE_EOS) {
1702		size = sample_size * cmd.chanlist_len;
1703	} else {
1704		/*  make buffer fill in no more than 1/3 second */
1705		size = (freq / 3) * sample_size;
1706	}
1707
1708	/*  set a minimum and maximum size allowed */
1709	if (size > DAS16_DMA_SIZE)
1710		size = DAS16_DMA_SIZE - DAS16_DMA_SIZE % sample_size;
1711	else if (size < sample_size)
1712		size = sample_size;
1713
1714	if (cmd.stop_src == TRIG_COUNT && size > devpriv->adc_byte_count)
1715		size = devpriv->adc_byte_count;
1716
1717	return size;
1718}
1719
1720static void das16_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
1721	void *array, unsigned int num_bytes, unsigned int start_chan_index)
1722{
1723	unsigned int i, num_samples = num_bytes / sizeof(short);
1724	short *data = array;
1725
1726	for (i = 0; i < num_samples; i++) {
1727		data[i] = le16_to_cpu(data[i]);
1728		if (thisboard->ai_nbits == 12) {
1729			data[i] = (data[i] >> 4) & 0xfff;
1730		}
1731	}
1732}
1733