1/*
2 * 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
21/*
22 * Driver: das16
23 * Description: DAS16 compatible boards
24 * Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
25 * Devices: (Keithley Metrabyte) DAS-16 [das-16]
26 *	    (Keithley Metrabyte) DAS-16G [das-16g]
27 *	    (Keithley Metrabyte) DAS-16F [das-16f]
28 *	    (Keithley Metrabyte) DAS-1201 [das-1201]
29 *	    (Keithley Metrabyte) DAS-1202 [das-1202]
30 *	    (Keithley Metrabyte) DAS-1401 [das-1401]
31 *	    (Keithley Metrabyte) DAS-1402 [das-1402]
32 *	    (Keithley Metrabyte) DAS-1601 [das-1601]
33 *	    (Keithley Metrabyte) DAS-1602 [das-1602]
34 *	    (ComputerBoards) PC104-DAS16/JR [pc104-das16jr]
35 *	    (ComputerBoards) PC104-DAS16JR/16 [pc104-das16jr/16]
36 *	    (ComputerBoards) CIO-DAS16 [cio-das16]
37 *	    (ComputerBoards) CIO-DAS16F [cio-das16/f]
38 *	    (ComputerBoards) CIO-DAS16/JR [cio-das16/jr]
39 *	    (ComputerBoards) CIO-DAS16JR/16 [cio-das16jr/16]
40 *	    (ComputerBoards) CIO-DAS1401/12 [cio-das1401/12]
41 *	    (ComputerBoards) CIO-DAS1402/12 [cio-das1402/12]
42 *	    (ComputerBoards) CIO-DAS1402/16 [cio-das1402/16]
43 *	    (ComputerBoards) CIO-DAS1601/12 [cio-das1601/12]
44 *	    (ComputerBoards) CIO-DAS1602/12 [cio-das1602/12]
45 *	    (ComputerBoards) CIO-DAS1602/16 [cio-das1602/16]
46 *	    (ComputerBoards) CIO-DAS16/330 [cio-das16/330]
47 * Status: works
48 * Updated: 2003-10-12
49 *
50 * A rewrite of the das16 and das1600 drivers.
51 *
52 * Options:
53 *	[0] - base io address
54 *	[1] - irq (does nothing, irq is not used anymore)
55 *	[2] - dma channel (optional, required for comedi_command support)
56 *	[3] - master clock speed in MHz (optional, 1 or 10, ignored if
57 *		board can probe clock, defaults to 1)
58 *	[4] - analog input range lowest voltage in microvolts (optional,
59 *		only useful if your board does not have software
60 *		programmable gain)
61 *	[5] - analog input range highest voltage in microvolts (optional,
62 *		only useful if board does not have software programmable
63 *		gain)
64 *	[6] - analog output range lowest voltage in microvolts (optional)
65 *	[7] - analog output range highest voltage in microvolts (optional)
66 *
67 * Passing a zero for an option is the same as leaving it unspecified.
68 */
69
70/*
71 * Testing and debugging help provided by Daniel Koch.
72 *
73 * Keithley Manuals:
74 *	2309.PDF (das16)
75 *	4919.PDF (das1400, 1600)
76 *	4922.PDF (das-1400)
77 *	4923.PDF (das1200, 1400, 1600)
78 *
79 * Computer boards manuals also available from their website
80 * www.measurementcomputing.com
81 */
82
83#include <linux/module.h>
84#include <linux/slab.h>
85#include <linux/delay.h>
86#include <linux/pci.h>
87#include <linux/interrupt.h>
88
89#include <asm/dma.h>
90
91#include "../comedidev.h"
92
93#include "8253.h"
94#include "8255.h"
95#include "comedi_fc.h"
96
97#define DAS16_DMA_SIZE 0xff00	/*  size in bytes of allocated dma buffer */
98
99/*
100 * Register I/O map
101 */
102#define DAS16_TRIG_REG			0x00
103#define DAS16_AI_LSB_REG		0x00
104#define DAS16_AI_MSB_REG		0x01
105#define DAS16_MUX_REG			0x02
106#define DAS16_DIO_REG			0x03
107#define DAS16_AO_LSB_REG(x)		((x) ? 0x06 : 0x04)
108#define DAS16_AO_MSB_REG(x)		((x) ? 0x07 : 0x05)
109#define DAS16_STATUS_REG		0x08
110#define DAS16_STATUS_BUSY		(1 << 7)
111#define DAS16_STATUS_UNIPOLAR		(1 << 6)
112#define DAS16_STATUS_MUXBIT		(1 << 5)
113#define DAS16_STATUS_INT		(1 << 4)
114#define DAS16_CTRL_REG			0x09
115#define DAS16_CTRL_INTE			(1 << 7)
116#define DAS16_CTRL_IRQ(x)		(((x) & 0x7) << 4)
117#define DAS16_CTRL_DMAE			(1 << 2)
118#define DAS16_CTRL_PACING_MASK		(3 << 0)
119#define DAS16_CTRL_INT_PACER		(3 << 0)
120#define DAS16_CTRL_EXT_PACER		(2 << 0)
121#define DAS16_CTRL_SOFT_PACER		(0 << 0)
122#define DAS16_PACER_REG			0x0a
123#define DAS16_PACER_BURST_LEN(x)	(((x) & 0xf) << 4)
124#define DAS16_PACER_CTR0		(1 << 1)
125#define DAS16_PACER_TRIG0		(1 << 0)
126#define DAS16_GAIN_REG			0x0b
127#define DAS16_TIMER_BASE_REG		0x0c	/* to 0x0f */
128
129#define DAS1600_CONV_REG		0x404
130#define DAS1600_CONV_DISABLE		(1 << 6)
131#define DAS1600_BURST_REG		0x405
132#define DAS1600_BURST_VAL		(1 << 6)
133#define DAS1600_ENABLE_REG		0x406
134#define DAS1600_ENABLE_VAL		(1 << 6)
135#define DAS1600_STATUS_REG		0x407
136#define DAS1600_STATUS_BME		(1 << 6)
137#define DAS1600_STATUS_ME		(1 << 5)
138#define DAS1600_STATUS_CD		(1 << 4)
139#define DAS1600_STATUS_WS		(1 << 1)
140#define DAS1600_STATUS_CLK_10MHZ	(1 << 0)
141
142static const struct comedi_lrange range_das1x01_bip = {
143	4, {
144		BIP_RANGE(10),
145		BIP_RANGE(1),
146		BIP_RANGE(0.1),
147		BIP_RANGE(0.01)
148	}
149};
150
151static const struct comedi_lrange range_das1x01_unip = {
152	4, {
153		UNI_RANGE(10),
154		UNI_RANGE(1),
155		UNI_RANGE(0.1),
156		UNI_RANGE(0.01)
157	}
158};
159
160static const struct comedi_lrange range_das1x02_bip = {
161	4, {
162		BIP_RANGE(10),
163		BIP_RANGE(5),
164		BIP_RANGE(2.5),
165		BIP_RANGE(1.25)
166	}
167};
168
169static const struct comedi_lrange range_das1x02_unip = {
170	4, {
171		UNI_RANGE(10),
172		UNI_RANGE(5),
173		UNI_RANGE(2.5),
174		UNI_RANGE(1.25)
175	}
176};
177
178static const struct comedi_lrange range_das16jr = {
179	9, {
180		BIP_RANGE(10),
181		BIP_RANGE(5),
182		BIP_RANGE(2.5),
183		BIP_RANGE(1.25),
184		BIP_RANGE(0.625),
185		UNI_RANGE(10),
186		UNI_RANGE(5),
187		UNI_RANGE(2.5),
188		UNI_RANGE(1.25)
189	}
190};
191
192static const struct comedi_lrange range_das16jr_16 = {
193	8, {
194		BIP_RANGE(10),
195		BIP_RANGE(5),
196		BIP_RANGE(2.5),
197		BIP_RANGE(1.25),
198		UNI_RANGE(10),
199		UNI_RANGE(5),
200		UNI_RANGE(2.5),
201		UNI_RANGE(1.25)
202	}
203};
204
205static const int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 };
206static const int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
207static const int das1600_gainlist[] = { 0, 1, 2, 3 };
208
209enum {
210	das16_pg_none = 0,
211	das16_pg_16jr,
212	das16_pg_16jr_16,
213	das16_pg_1601,
214	das16_pg_1602,
215};
216static const int *const das16_gainlists[] = {
217	NULL,
218	das16jr_gainlist,
219	das16jr_16_gainlist,
220	das1600_gainlist,
221	das1600_gainlist,
222};
223
224static const struct comedi_lrange *const das16_ai_uni_lranges[] = {
225	&range_unknown,
226	&range_das16jr,
227	&range_das16jr_16,
228	&range_das1x01_unip,
229	&range_das1x02_unip,
230};
231
232static const struct comedi_lrange *const das16_ai_bip_lranges[] = {
233	&range_unknown,
234	&range_das16jr,
235	&range_das16jr_16,
236	&range_das1x01_bip,
237	&range_das1x02_bip,
238};
239
240struct das16_board {
241	const char *name;
242	unsigned int ai_maxdata;
243	unsigned int ai_speed;	/*  max conversion speed in nanosec */
244	unsigned int ai_pg;
245	unsigned int has_ao:1;
246	unsigned int has_8255:1;
247
248	unsigned int i8255_offset;
249
250	unsigned int size;
251	unsigned int id;
252};
253
254static const struct das16_board das16_boards[] = {
255	{
256		.name		= "das-16",
257		.ai_maxdata	= 0x0fff,
258		.ai_speed	= 15000,
259		.ai_pg		= das16_pg_none,
260		.has_ao		= 1,
261		.has_8255	= 1,
262		.i8255_offset	= 0x10,
263		.size		= 0x14,
264		.id		= 0x00,
265	}, {
266		.name		= "das-16g",
267		.ai_maxdata	= 0x0fff,
268		.ai_speed	= 15000,
269		.ai_pg		= das16_pg_none,
270		.has_ao		= 1,
271		.has_8255	= 1,
272		.i8255_offset	= 0x10,
273		.size		= 0x14,
274		.id		= 0x00,
275	}, {
276		.name		= "das-16f",
277		.ai_maxdata	= 0x0fff,
278		.ai_speed	= 8500,
279		.ai_pg		= das16_pg_none,
280		.has_ao		= 1,
281		.has_8255	= 1,
282		.i8255_offset	= 0x10,
283		.size		= 0x14,
284		.id		= 0x00,
285	}, {
286		.name		= "cio-das16",
287		.ai_maxdata	= 0x0fff,
288		.ai_speed	= 20000,
289		.ai_pg		= das16_pg_none,
290		.has_ao		= 1,
291		.has_8255	= 1,
292		.i8255_offset	= 0x10,
293		.size		= 0x14,
294		.id		= 0x80,
295	}, {
296		.name		= "cio-das16/f",
297		.ai_maxdata	= 0x0fff,
298		.ai_speed	= 10000,
299		.ai_pg		= das16_pg_none,
300		.has_ao		= 1,
301		.has_8255	= 1,
302		.i8255_offset	= 0x10,
303		.size		= 0x14,
304		.id		= 0x80,
305	}, {
306		.name		= "cio-das16/jr",
307		.ai_maxdata	= 0x0fff,
308		.ai_speed	= 7692,
309		.ai_pg		= das16_pg_16jr,
310		.size		= 0x10,
311		.id		= 0x00,
312	}, {
313		.name		= "pc104-das16jr",
314		.ai_maxdata	= 0x0fff,
315		.ai_speed	= 3300,
316		.ai_pg		= das16_pg_16jr,
317		.size		= 0x10,
318		.id		= 0x00,
319	}, {
320		.name		= "cio-das16jr/16",
321		.ai_maxdata	= 0xffff,
322		.ai_speed	= 10000,
323		.ai_pg		= das16_pg_16jr_16,
324		.size		= 0x10,
325		.id		= 0x00,
326	}, {
327		.name		= "pc104-das16jr/16",
328		.ai_maxdata	= 0xffff,
329		.ai_speed	= 10000,
330		.ai_pg		= das16_pg_16jr_16,
331		.size		= 0x10,
332		.id		= 0x00,
333	}, {
334		.name		= "das-1201",
335		.ai_maxdata	= 0x0fff,
336		.ai_speed	= 20000,
337		.ai_pg		= das16_pg_none,
338		.has_8255	= 1,
339		.i8255_offset	= 0x400,
340		.size		= 0x408,
341		.id		= 0x20,
342	}, {
343		.name		= "das-1202",
344		.ai_maxdata	= 0x0fff,
345		.ai_speed	= 10000,
346		.ai_pg		= das16_pg_none,
347		.has_8255	= 1,
348		.i8255_offset	= 0x400,
349		.size		= 0x408,
350		.id		= 0x20,
351	}, {
352		.name		= "das-1401",
353		.ai_maxdata	= 0x0fff,
354		.ai_speed	= 10000,
355		.ai_pg		= das16_pg_1601,
356		.size		= 0x408,
357		.id		= 0xc0,
358	}, {
359		.name		= "das-1402",
360		.ai_maxdata	= 0x0fff,
361		.ai_speed	= 10000,
362		.ai_pg		= das16_pg_1602,
363		.size		= 0x408,
364		.id		= 0xc0,
365	}, {
366		.name		= "das-1601",
367		.ai_maxdata	= 0x0fff,
368		.ai_speed	= 10000,
369		.ai_pg		= das16_pg_1601,
370		.has_ao		= 1,
371		.has_8255	= 1,
372		.i8255_offset	= 0x400,
373		.size		= 0x408,
374		.id		= 0xc0,
375	}, {
376		.name		= "das-1602",
377		.ai_maxdata	= 0x0fff,
378		.ai_speed	= 10000,
379		.ai_pg		= das16_pg_1602,
380		.has_ao		= 1,
381		.has_8255	= 1,
382		.i8255_offset	= 0x400,
383		.size		= 0x408,
384		.id		= 0xc0,
385	}, {
386		.name		= "cio-das1401/12",
387		.ai_maxdata	= 0x0fff,
388		.ai_speed	= 6250,
389		.ai_pg		= das16_pg_1601,
390		.size		= 0x408,
391		.id		= 0xc0,
392	}, {
393		.name		= "cio-das1402/12",
394		.ai_maxdata	= 0x0fff,
395		.ai_speed	= 6250,
396		.ai_pg		= das16_pg_1602,
397		.size		= 0x408,
398		.id		= 0xc0,
399	}, {
400		.name		= "cio-das1402/16",
401		.ai_maxdata	= 0xffff,
402		.ai_speed	= 10000,
403		.ai_pg		= das16_pg_1602,
404		.size		= 0x408,
405		.id		= 0xc0,
406	}, {
407		.name		= "cio-das1601/12",
408		.ai_maxdata	= 0x0fff,
409		.ai_speed	= 6250,
410		.ai_pg		= das16_pg_1601,
411		.has_ao		= 1,
412		.has_8255	= 1,
413		.i8255_offset	= 0x400,
414		.size		= 0x408,
415		.id		= 0xc0,
416	}, {
417		.name		= "cio-das1602/12",
418		.ai_maxdata	= 0x0fff,
419		.ai_speed	= 10000,
420		.ai_pg		= das16_pg_1602,
421		.has_ao		= 1,
422		.has_8255	= 1,
423		.i8255_offset	= 0x400,
424		.size		= 0x408,
425		.id		= 0xc0,
426	}, {
427		.name		= "cio-das1602/16",
428		.ai_maxdata	= 0xffff,
429		.ai_speed	= 10000,
430		.ai_pg		= das16_pg_1602,
431		.has_ao		= 1,
432		.has_8255	= 1,
433		.i8255_offset	= 0x400,
434		.size		= 0x408,
435		.id		= 0xc0,
436	}, {
437		.name		= "cio-das16/330",
438		.ai_maxdata	= 0x0fff,
439		.ai_speed	= 3030,
440		.ai_pg		= das16_pg_16jr,
441		.size		= 0x14,
442		.id		= 0xf0,
443	},
444};
445
446/* Period for timer interrupt in jiffies.  It's a function
447 * to deal with possibility of dynamic HZ patches  */
448static inline int timer_period(void)
449{
450	return HZ / 20;
451}
452
453struct das16_private_struct {
454	unsigned int		clockbase;
455	unsigned int		ctrl_reg;
456	unsigned long		adc_byte_count;
457	unsigned int		divisor1;
458	unsigned int		divisor2;
459	unsigned int		dma_chan;
460	uint16_t		*dma_buffer[2];
461	dma_addr_t		dma_buffer_addr[2];
462	unsigned int		current_buffer;
463	unsigned int		dma_transfer_size;
464	struct comedi_lrange	*user_ai_range_table;
465	struct comedi_lrange	*user_ao_range_table;
466	struct timer_list	timer;
467	short			timer_running;
468	unsigned long		extra_iobase;
469	unsigned int		can_burst:1;
470};
471
472static void das16_ai_enable(struct comedi_device *dev,
473			    unsigned int mode, unsigned int src)
474{
475	struct das16_private_struct *devpriv = dev->private;
476
477	devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE |
478			       DAS16_CTRL_DMAE |
479			       DAS16_CTRL_PACING_MASK);
480	devpriv->ctrl_reg |= mode;
481
482	if (src == TRIG_EXT)
483		devpriv->ctrl_reg |= DAS16_CTRL_EXT_PACER;
484	else
485		devpriv->ctrl_reg |= DAS16_CTRL_INT_PACER;
486	outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG);
487}
488
489static void das16_ai_disable(struct comedi_device *dev)
490{
491	struct das16_private_struct *devpriv = dev->private;
492
493	/* disable interrupts, dma and pacer clocked conversions */
494	devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE |
495			       DAS16_CTRL_DMAE |
496			       DAS16_CTRL_PACING_MASK);
497	outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG);
498}
499
500/* the pc104-das16jr (at least) has problems if the dma
501	transfer is interrupted in the middle of transferring
502	a 16 bit sample, so this function takes care to get
503	an even transfer count after disabling dma
504	channel.
505*/
506static int disable_dma_on_even(struct comedi_device *dev)
507{
508	struct das16_private_struct *devpriv = dev->private;
509	static const int disable_limit = 100;
510	static const int enable_timeout = 100;
511	int residue;
512	int new_residue;
513	int i;
514	int j;
515
516	disable_dma(devpriv->dma_chan);
517	residue = get_dma_residue(devpriv->dma_chan);
518	for (i = 0; i < disable_limit && (residue % 2); ++i) {
519		enable_dma(devpriv->dma_chan);
520		for (j = 0; j < enable_timeout; ++j) {
521			udelay(2);
522			new_residue = get_dma_residue(devpriv->dma_chan);
523			if (new_residue != residue)
524				break;
525		}
526		disable_dma(devpriv->dma_chan);
527		residue = get_dma_residue(devpriv->dma_chan);
528	}
529	if (i == disable_limit) {
530		dev_err(dev->class_dev,
531			"failed to get an even dma transfer, could be trouble\n");
532	}
533	return residue;
534}
535
536static void das16_interrupt(struct comedi_device *dev)
537{
538	struct das16_private_struct *devpriv = dev->private;
539	struct comedi_subdevice *s = dev->read_subdev;
540	struct comedi_async *async = s->async;
541	struct comedi_cmd *cmd = &async->cmd;
542	unsigned long spin_flags;
543	unsigned long dma_flags;
544	int num_bytes, residue;
545	int buffer_index;
546
547	spin_lock_irqsave(&dev->spinlock, spin_flags);
548	if (!(devpriv->ctrl_reg & DAS16_CTRL_DMAE)) {
549		spin_unlock_irqrestore(&dev->spinlock, spin_flags);
550		return;
551	}
552
553	dma_flags = claim_dma_lock();
554	clear_dma_ff(devpriv->dma_chan);
555	residue = disable_dma_on_even(dev);
556
557	/*  figure out how many points to read */
558	if (residue > devpriv->dma_transfer_size) {
559		dev_err(dev->class_dev, "residue > transfer size!\n");
560		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
561		num_bytes = 0;
562	} else
563		num_bytes = devpriv->dma_transfer_size - residue;
564
565	if (cmd->stop_src == TRIG_COUNT &&
566					num_bytes >= devpriv->adc_byte_count) {
567		num_bytes = devpriv->adc_byte_count;
568		async->events |= COMEDI_CB_EOA;
569	}
570
571	buffer_index = devpriv->current_buffer;
572	devpriv->current_buffer = (devpriv->current_buffer + 1) % 2;
573	devpriv->adc_byte_count -= num_bytes;
574
575	/*  re-enable  dma */
576	if ((async->events & COMEDI_CB_EOA) == 0) {
577		set_dma_addr(devpriv->dma_chan,
578			     devpriv->dma_buffer_addr[devpriv->current_buffer]);
579		set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
580		enable_dma(devpriv->dma_chan);
581	}
582	release_dma_lock(dma_flags);
583
584	spin_unlock_irqrestore(&dev->spinlock, spin_flags);
585
586	cfc_write_array_to_buffer(s,
587				  devpriv->dma_buffer[buffer_index], num_bytes);
588
589	cfc_handle_events(dev, s);
590}
591
592static void das16_timer_interrupt(unsigned long arg)
593{
594	struct comedi_device *dev = (struct comedi_device *)arg;
595	struct das16_private_struct *devpriv = dev->private;
596
597	das16_interrupt(dev);
598
599	if (devpriv->timer_running)
600		mod_timer(&devpriv->timer, jiffies + timer_period());
601}
602
603static int das16_ai_check_chanlist(struct comedi_device *dev,
604				   struct comedi_subdevice *s,
605				   struct comedi_cmd *cmd)
606{
607	unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
608	unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
609	int i;
610
611	for (i = 1; i < cmd->chanlist_len; i++) {
612		unsigned int chan = CR_CHAN(cmd->chanlist[i]);
613		unsigned int range = CR_RANGE(cmd->chanlist[i]);
614
615		if (chan != ((chan0 + i) % s->n_chan)) {
616			dev_dbg(dev->class_dev,
617				"entries in chanlist must be consecutive channels, counting upwards\n");
618			return -EINVAL;
619		}
620
621		if (range != range0) {
622			dev_dbg(dev->class_dev,
623				"entries in chanlist must all have the same gain\n");
624			return -EINVAL;
625		}
626	}
627
628	return 0;
629}
630
631static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
632			  struct comedi_cmd *cmd)
633{
634	const struct das16_board *board = dev->board_ptr;
635	struct das16_private_struct *devpriv = dev->private;
636	int err = 0;
637	unsigned int trig_mask;
638	unsigned int arg;
639
640	/* Step 1 : check if triggers are trivially valid */
641
642	err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
643
644	trig_mask = TRIG_FOLLOW;
645	if (devpriv->can_burst)
646		trig_mask |= TRIG_TIMER | TRIG_EXT;
647	err |= cfc_check_trigger_src(&cmd->scan_begin_src, trig_mask);
648
649	trig_mask = TRIG_TIMER | TRIG_EXT;
650	if (devpriv->can_burst)
651		trig_mask |= TRIG_NOW;
652	err |= cfc_check_trigger_src(&cmd->convert_src, trig_mask);
653
654	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
655	err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
656
657	if (err)
658		return 1;
659
660	/* Step 2a : make sure trigger sources are unique */
661
662	err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
663	err |= cfc_check_trigger_is_unique(cmd->convert_src);
664	err |= cfc_check_trigger_is_unique(cmd->stop_src);
665
666	/* Step 2b : and mutually compatible */
667
668	/*  make sure scan_begin_src and convert_src dont conflict */
669	if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
670		err |= -EINVAL;
671	if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
672		err |= -EINVAL;
673
674	if (err)
675		return 2;
676
677	/* Step 3: check if arguments are trivially valid */
678
679	err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
680
681	if (cmd->scan_begin_src == TRIG_FOLLOW)	/* internal trigger */
682		err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
683
684	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
685
686	/* check against maximum frequency */
687	if (cmd->scan_begin_src == TRIG_TIMER)
688		err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
689					board->ai_speed * cmd->chanlist_len);
690
691	if (cmd->convert_src == TRIG_TIMER)
692		err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
693						 board->ai_speed);
694
695	if (cmd->stop_src == TRIG_COUNT)
696		err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
697	else	/* TRIG_NONE */
698		err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
699
700	if (err)
701		return 3;
702
703	/*  step 4: fix up arguments */
704	if (cmd->scan_begin_src == TRIG_TIMER) {
705		arg = cmd->scan_begin_arg;
706		i8253_cascade_ns_to_timer(devpriv->clockbase,
707					  &devpriv->divisor1,
708					  &devpriv->divisor2,
709					  &arg, cmd->flags);
710		err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
711	}
712	if (cmd->convert_src == TRIG_TIMER) {
713		arg = cmd->convert_arg;
714		i8253_cascade_ns_to_timer(devpriv->clockbase,
715					  &devpriv->divisor1,
716					  &devpriv->divisor2,
717					  &arg, cmd->flags);
718		err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
719	}
720	if (err)
721		return 4;
722
723	/* Step 5: check channel list if it exists */
724	if (cmd->chanlist && cmd->chanlist_len > 0)
725		err |= das16_ai_check_chanlist(dev, s, cmd);
726
727	if (err)
728		return 5;
729
730	return 0;
731}
732
733static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
734				    unsigned int flags)
735{
736	struct das16_private_struct *devpriv = dev->private;
737	unsigned long timer_base = dev->iobase + DAS16_TIMER_BASE_REG;
738
739	i8253_cascade_ns_to_timer(devpriv->clockbase,
740				  &devpriv->divisor1, &devpriv->divisor2,
741				  &ns, flags);
742
743	i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
744	i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
745	i8254_write(timer_base, 0, 1, devpriv->divisor1);
746	i8254_write(timer_base, 0, 2, devpriv->divisor2);
747
748	return ns;
749}
750
751static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
752{
753	const struct das16_board *board = dev->board_ptr;
754	struct das16_private_struct *devpriv = dev->private;
755	struct comedi_async *async = s->async;
756	struct comedi_cmd *cmd = &async->cmd;
757	unsigned int byte;
758	unsigned long flags;
759	int range;
760
761	if (cmd->flags & CMDF_PRIORITY) {
762		dev_err(dev->class_dev,
763			 "isa dma transfers cannot be performed with CMDF_PRIORITY, aborting\n");
764		return -1;
765	}
766
767	devpriv->adc_byte_count = cmd->stop_arg * cfc_bytes_per_scan(s);
768
769	if (devpriv->can_burst)
770		outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV_REG);
771
772	/*  set scan limits */
773	byte = CR_CHAN(cmd->chanlist[0]);
774	byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4;
775	outb(byte, dev->iobase + DAS16_MUX_REG);
776
777	/* set gain (this is also burst rate register but according to
778	 * computer boards manual, burst rate does nothing, even on
779	 * keithley cards) */
780	if (board->ai_pg != das16_pg_none) {
781		range = CR_RANGE(cmd->chanlist[0]);
782		outb((das16_gainlists[board->ai_pg])[range],
783		     dev->iobase + DAS16_GAIN_REG);
784	}
785
786	/* set counter mode and counts */
787	cmd->convert_arg = das16_set_pacer(dev, cmd->convert_arg, cmd->flags);
788
789	/* enable counters */
790	byte = 0;
791	if (devpriv->can_burst) {
792		if (cmd->convert_src == TRIG_NOW) {
793			outb(DAS1600_BURST_VAL,
794			     dev->iobase + DAS1600_BURST_REG);
795			/*  set burst length */
796			byte |= DAS16_PACER_BURST_LEN(cmd->chanlist_len - 1);
797		} else {
798			outb(0, dev->iobase + DAS1600_BURST_REG);
799		}
800	}
801	outb(byte, dev->iobase + DAS16_PACER_REG);
802
803	/*  set up dma transfer */
804	flags = claim_dma_lock();
805	disable_dma(devpriv->dma_chan);
806	/* clear flip-flop to make sure 2-byte registers for
807	 * count and address get set correctly */
808	clear_dma_ff(devpriv->dma_chan);
809	devpriv->current_buffer = 0;
810	set_dma_addr(devpriv->dma_chan,
811		     devpriv->dma_buffer_addr[devpriv->current_buffer]);
812	devpriv->dma_transfer_size = DAS16_DMA_SIZE;
813	set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
814	enable_dma(devpriv->dma_chan);
815	release_dma_lock(flags);
816
817	/*  set up interrupt */
818	devpriv->timer_running = 1;
819	devpriv->timer.expires = jiffies + timer_period();
820	add_timer(&devpriv->timer);
821
822	das16_ai_enable(dev, DAS16_CTRL_DMAE, cmd->convert_src);
823
824	if (devpriv->can_burst)
825		outb(0, dev->iobase + DAS1600_CONV_REG);
826
827	return 0;
828}
829
830static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
831{
832	struct das16_private_struct *devpriv = dev->private;
833	unsigned long flags;
834
835	spin_lock_irqsave(&dev->spinlock, flags);
836
837	das16_ai_disable(dev);
838	disable_dma(devpriv->dma_chan);
839
840	/*  disable SW timer */
841	if (devpriv->timer_running) {
842		devpriv->timer_running = 0;
843		del_timer(&devpriv->timer);
844	}
845
846	if (devpriv->can_burst)
847		outb(0, dev->iobase + DAS1600_BURST_REG);
848
849	spin_unlock_irqrestore(&dev->spinlock, flags);
850
851	return 0;
852}
853
854static void das16_ai_munge(struct comedi_device *dev,
855			   struct comedi_subdevice *s, void *array,
856			   unsigned int num_bytes,
857			   unsigned int start_chan_index)
858{
859	unsigned int i, num_samples = num_bytes / sizeof(short);
860	unsigned short *data = array;
861
862	for (i = 0; i < num_samples; i++) {
863		data[i] = le16_to_cpu(data[i]);
864		if (s->maxdata == 0x0fff)
865			data[i] >>= 4;
866		data[i] &= s->maxdata;
867	}
868}
869
870static int das16_ai_eoc(struct comedi_device *dev,
871			struct comedi_subdevice *s,
872			struct comedi_insn *insn,
873			unsigned long context)
874{
875	unsigned int status;
876
877	status = inb(dev->iobase + DAS16_STATUS_REG);
878	if ((status & DAS16_STATUS_BUSY) == 0)
879		return 0;
880	return -EBUSY;
881}
882
883static int das16_ai_insn_read(struct comedi_device *dev,
884			      struct comedi_subdevice *s,
885			      struct comedi_insn *insn,
886			      unsigned int *data)
887{
888	const struct das16_board *board = dev->board_ptr;
889	unsigned int chan = CR_CHAN(insn->chanspec);
890	unsigned int range = CR_RANGE(insn->chanspec);
891	unsigned int val;
892	int ret;
893	int i;
894
895	das16_ai_disable(dev);
896
897	/* set multiplexer */
898	outb(chan | (chan << 4), dev->iobase + DAS16_MUX_REG);
899
900	/* set gain */
901	if (board->ai_pg != das16_pg_none) {
902		outb((das16_gainlists[board->ai_pg])[range],
903		     dev->iobase + DAS16_GAIN_REG);
904	}
905
906	for (i = 0; i < insn->n; i++) {
907		/* trigger conversion */
908		outb_p(0, dev->iobase + DAS16_TRIG_REG);
909
910		ret = comedi_timeout(dev, s, insn, das16_ai_eoc, 0);
911		if (ret)
912			return ret;
913
914		val = inb(dev->iobase + DAS16_AI_MSB_REG) << 8;
915		val |= inb(dev->iobase + DAS16_AI_LSB_REG);
916		if (s->maxdata == 0x0fff)
917			val >>= 4;
918		val &= s->maxdata;
919
920		data[i] = val;
921	}
922
923	return insn->n;
924}
925
926static int das16_ao_insn_write(struct comedi_device *dev,
927			       struct comedi_subdevice *s,
928			       struct comedi_insn *insn,
929			       unsigned int *data)
930{
931	unsigned int chan = CR_CHAN(insn->chanspec);
932	int i;
933
934	for (i = 0; i < insn->n; i++) {
935		unsigned int val = data[i];
936
937		s->readback[chan] = val;
938
939		val <<= 4;
940
941		outb(val & 0xff, dev->iobase + DAS16_AO_LSB_REG(chan));
942		outb((val >> 8) & 0xff, dev->iobase + DAS16_AO_MSB_REG(chan));
943	}
944
945	return insn->n;
946}
947
948static int das16_di_insn_bits(struct comedi_device *dev,
949			      struct comedi_subdevice *s,
950			      struct comedi_insn *insn,
951			      unsigned int *data)
952{
953	data[1] = inb(dev->iobase + DAS16_DIO_REG) & 0xf;
954
955	return insn->n;
956}
957
958static int das16_do_insn_bits(struct comedi_device *dev,
959			      struct comedi_subdevice *s,
960			      struct comedi_insn *insn,
961			      unsigned int *data)
962{
963	if (comedi_dio_update_state(s, data))
964		outb(s->state, dev->iobase + DAS16_DIO_REG);
965
966	data[1] = s->state;
967
968	return insn->n;
969}
970
971static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it)
972{
973	const struct das16_board *board = dev->board_ptr;
974	int diobits;
975
976	/* diobits indicates boards */
977	diobits = inb(dev->iobase + DAS16_DIO_REG) & 0xf0;
978	if (board->id != diobits) {
979		dev_err(dev->class_dev,
980			"requested board's id bits are incorrect (0x%x != 0x%x)\n",
981			board->id, diobits);
982		return -EINVAL;
983	}
984
985	return 0;
986}
987
988static void das16_reset(struct comedi_device *dev)
989{
990	outb(0, dev->iobase + DAS16_STATUS_REG);
991	outb(0, dev->iobase + DAS16_CTRL_REG);
992	outb(0, dev->iobase + DAS16_PACER_REG);
993	outb(0, dev->iobase + DAS16_TIMER_BASE_REG + i8254_control_reg);
994}
995
996static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
997{
998	const struct das16_board *board = dev->board_ptr;
999	struct das16_private_struct *devpriv;
1000	struct comedi_subdevice *s;
1001	struct comedi_lrange *lrange;
1002	struct comedi_krange *krange;
1003	unsigned int dma_chan = it->options[2];
1004	unsigned int status;
1005	int ret;
1006
1007	/*  check that clock setting is valid */
1008	if (it->options[3]) {
1009		if (it->options[3] != 0 &&
1010		    it->options[3] != 1 && it->options[3] != 10) {
1011			dev_err(dev->class_dev,
1012				"Invalid option. Master clock must be set to 1 or 10 (MHz)\n");
1013			return -EINVAL;
1014		}
1015	}
1016
1017	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1018	if (!devpriv)
1019		return -ENOMEM;
1020
1021	if (board->size < 0x400) {
1022		ret = comedi_request_region(dev, it->options[0], board->size);
1023		if (ret)
1024			return ret;
1025	} else {
1026		ret = comedi_request_region(dev, it->options[0], 0x10);
1027		if (ret)
1028			return ret;
1029		/* Request an additional region for the 8255 */
1030		ret = __comedi_request_region(dev, dev->iobase + 0x400,
1031					      board->size & 0x3ff);
1032		if (ret)
1033			return ret;
1034		devpriv->extra_iobase = dev->iobase + 0x400;
1035		devpriv->can_burst = 1;
1036	}
1037
1038	/*  probe id bits to make sure they are consistent */
1039	if (das16_probe(dev, it))
1040		return -EINVAL;
1041
1042	/*  get master clock speed */
1043	if (devpriv->can_burst) {
1044		status = inb(dev->iobase + DAS1600_STATUS_REG);
1045
1046		if (status & DAS1600_STATUS_CLK_10MHZ)
1047			devpriv->clockbase = I8254_OSC_BASE_10MHZ;
1048		else
1049			devpriv->clockbase = I8254_OSC_BASE_1MHZ;
1050	} else {
1051		if (it->options[3])
1052			devpriv->clockbase = I8254_OSC_BASE_1MHZ /
1053					     it->options[3];
1054		else
1055			devpriv->clockbase = I8254_OSC_BASE_1MHZ;
1056	}
1057
1058	/* initialize dma */
1059	if (dma_chan == 1 || dma_chan == 3) {
1060		unsigned long flags;
1061		int i;
1062
1063		if (request_dma(dma_chan, dev->board_name)) {
1064			dev_err(dev->class_dev,
1065				"failed to request dma channel %i\n",
1066				dma_chan);
1067			return -EINVAL;
1068		}
1069		devpriv->dma_chan = dma_chan;
1070
1071		/* allocate dma buffers */
1072		for (i = 0; i < 2; i++) {
1073			void *p;
1074
1075			p = pci_alloc_consistent(NULL, DAS16_DMA_SIZE,
1076						 &devpriv->dma_buffer_addr[i]);
1077			if (!p)
1078				return -ENOMEM;
1079			devpriv->dma_buffer[i] = p;
1080		}
1081
1082		flags = claim_dma_lock();
1083		disable_dma(devpriv->dma_chan);
1084		set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
1085		release_dma_lock(flags);
1086
1087		init_timer(&devpriv->timer);
1088		devpriv->timer.function = das16_timer_interrupt;
1089		devpriv->timer.data = (unsigned long)dev;
1090	}
1091
1092	/* get any user-defined input range */
1093	if (board->ai_pg == das16_pg_none &&
1094	    (it->options[4] || it->options[5])) {
1095		/* allocate single-range range table */
1096		lrange = kzalloc(sizeof(*lrange) + sizeof(*krange), GFP_KERNEL);
1097		if (!lrange)
1098			return -ENOMEM;
1099
1100		/* initialize ai range */
1101		devpriv->user_ai_range_table = lrange;
1102		lrange->length = 1;
1103		krange = devpriv->user_ai_range_table->range;
1104		krange->min = it->options[4];
1105		krange->max = it->options[5];
1106		krange->flags = UNIT_volt;
1107	}
1108
1109	/* get any user-defined output range */
1110	if (it->options[6] || it->options[7]) {
1111		/* allocate single-range range table */
1112		lrange = kzalloc(sizeof(*lrange) + sizeof(*krange), GFP_KERNEL);
1113		if (!lrange)
1114			return -ENOMEM;
1115
1116		/* initialize ao range */
1117		devpriv->user_ao_range_table = lrange;
1118		lrange->length = 1;
1119		krange = devpriv->user_ao_range_table->range;
1120		krange->min = it->options[6];
1121		krange->max = it->options[7];
1122		krange->flags = UNIT_volt;
1123	}
1124
1125	ret = comedi_alloc_subdevices(dev, 4 + board->has_8255);
1126	if (ret)
1127		return ret;
1128
1129	status = inb(dev->iobase + DAS16_STATUS_REG);
1130
1131	/* Analog Input subdevice */
1132	s = &dev->subdevices[0];
1133	s->type		= COMEDI_SUBD_AI;
1134	s->subdev_flags	= SDF_READABLE;
1135	if (status & DAS16_STATUS_MUXBIT) {
1136		s->subdev_flags	|= SDF_GROUND;
1137		s->n_chan	= 16;
1138	} else {
1139		s->subdev_flags	|= SDF_DIFF;
1140		s->n_chan	= 8;
1141	}
1142	s->len_chanlist	= s->n_chan;
1143	s->maxdata	= board->ai_maxdata;
1144	if (devpriv->user_ai_range_table) { /*  user defined ai range */
1145		s->range_table	= devpriv->user_ai_range_table;
1146	} else if (status & DAS16_STATUS_UNIPOLAR) {
1147		s->range_table	= das16_ai_uni_lranges[board->ai_pg];
1148	} else {
1149		s->range_table	= das16_ai_bip_lranges[board->ai_pg];
1150	}
1151	s->insn_read	= das16_ai_insn_read;
1152	if (devpriv->dma_chan) {
1153		dev->read_subdev = s;
1154		s->subdev_flags	|= SDF_CMD_READ;
1155		s->do_cmdtest	= das16_cmd_test;
1156		s->do_cmd	= das16_cmd_exec;
1157		s->cancel	= das16_cancel;
1158		s->munge	= das16_ai_munge;
1159	}
1160
1161	/* Analog Output subdevice */
1162	s = &dev->subdevices[1];
1163	if (board->has_ao) {
1164		s->type		= COMEDI_SUBD_AO;
1165		s->subdev_flags	= SDF_WRITABLE;
1166		s->n_chan	= 2;
1167		s->maxdata	= 0x0fff;
1168		s->range_table	= devpriv->user_ao_range_table;
1169		s->insn_write	= das16_ao_insn_write;
1170		s->insn_read	= comedi_readback_insn_read;
1171
1172		ret = comedi_alloc_subdev_readback(s);
1173		if (ret)
1174			return ret;
1175	} else {
1176		s->type		= COMEDI_SUBD_UNUSED;
1177	}
1178
1179	/* Digital Input subdevice */
1180	s = &dev->subdevices[2];
1181	s->type		= COMEDI_SUBD_DI;
1182	s->subdev_flags	= SDF_READABLE;
1183	s->n_chan	= 4;
1184	s->maxdata	= 1;
1185	s->range_table	= &range_digital;
1186	s->insn_bits	= das16_di_insn_bits;
1187
1188	/* Digital Output subdevice */
1189	s = &dev->subdevices[3];
1190	s->type		= COMEDI_SUBD_DO;
1191	s->subdev_flags	= SDF_WRITABLE;
1192	s->n_chan	= 4;
1193	s->maxdata	= 1;
1194	s->range_table	= &range_digital;
1195	s->insn_bits	= das16_do_insn_bits;
1196
1197	/* initialize digital output lines */
1198	outb(s->state, dev->iobase + DAS16_DIO_REG);
1199
1200	/* 8255 Digital I/O subdevice */
1201	if (board->has_8255) {
1202		s = &dev->subdevices[4];
1203		ret = subdev_8255_init(dev, s, NULL, board->i8255_offset);
1204		if (ret)
1205			return ret;
1206	}
1207
1208	das16_reset(dev);
1209	/* set the interrupt level */
1210	devpriv->ctrl_reg = DAS16_CTRL_IRQ(dev->irq);
1211	outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG);
1212
1213	if (devpriv->can_burst) {
1214		outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE_REG);
1215		outb(0, dev->iobase + DAS1600_CONV_REG);
1216		outb(0, dev->iobase + DAS1600_BURST_REG);
1217	}
1218
1219	return 0;
1220}
1221
1222static void das16_detach(struct comedi_device *dev)
1223{
1224	const struct das16_board *board = dev->board_ptr;
1225	struct das16_private_struct *devpriv = dev->private;
1226	int i;
1227
1228	if (devpriv) {
1229		if (dev->iobase)
1230			das16_reset(dev);
1231
1232		for (i = 0; i < 2; i++) {
1233			if (devpriv->dma_buffer[i])
1234				pci_free_consistent(NULL, DAS16_DMA_SIZE,
1235						    devpriv->dma_buffer[i],
1236						    devpriv->
1237						    dma_buffer_addr[i]);
1238		}
1239		if (devpriv->dma_chan)
1240			free_dma(devpriv->dma_chan);
1241		kfree(devpriv->user_ai_range_table);
1242		kfree(devpriv->user_ao_range_table);
1243
1244		if (devpriv->extra_iobase)
1245			release_region(devpriv->extra_iobase,
1246				       board->size & 0x3ff);
1247	}
1248
1249	comedi_legacy_detach(dev);
1250}
1251
1252static struct comedi_driver das16_driver = {
1253	.driver_name	= "das16",
1254	.module		= THIS_MODULE,
1255	.attach		= das16_attach,
1256	.detach		= das16_detach,
1257	.board_name	= &das16_boards[0].name,
1258	.num_names	= ARRAY_SIZE(das16_boards),
1259	.offset		= sizeof(das16_boards[0]),
1260};
1261module_comedi_driver(das16_driver);
1262
1263MODULE_AUTHOR("Comedi http://www.comedi.org");
1264MODULE_DESCRIPTION("Comedi driver for DAS16 compatible boards");
1265MODULE_LICENSE("GPL");
1266