[go: nahoru, domu]

1/*======================================================================
2
3    comedi/drivers/quatech_daqp_cs.c
4
5    Quatech DAQP PCMCIA data capture cards COMEDI client driver
6    Copyright (C) 2000, 2003 Brent Baccala <baccala@freesoft.org>
7    The DAQP interface code in this file is released into the public domain.
8
9    COMEDI - Linux Control and Measurement Device Interface
10    Copyright (C) 1998 David A. Schleef <ds@schleef.org>
11    http://www.comedi.org/
12
13    quatech_daqp_cs.c 1.10
14
15    Documentation for the DAQP PCMCIA cards can be found on Quatech's site:
16
17		ftp://ftp.quatech.com/Manuals/daqp-208.pdf
18
19    This manual is for both the DAQP-208 and the DAQP-308.
20
21    What works:
22
23	- A/D conversion
24	    - 8 channels
25	    - 4 gain ranges
26	    - ground ref or differential
27	    - single-shot and timed both supported
28	- D/A conversion, single-shot
29	- digital I/O
30
31    What doesn't:
32
33	- any kind of triggering - external or D/A channel 1
34	- the card's optional expansion board
35	- the card's timer (for anything other than A/D conversion)
36	- D/A update modes other than immediate (i.e, timed)
37	- fancier timing modes
38	- setting card's FIFO buffer thresholds to anything but default
39
40======================================================================*/
41
42/*
43Driver: quatech_daqp_cs
44Description: Quatech DAQP PCMCIA data capture cards
45Author: Brent Baccala <baccala@freesoft.org>
46Status: works
47Devices: [Quatech] DAQP-208 (daqp), DAQP-308
48*/
49
50#include <linux/module.h>
51#include "../comedidev.h"
52#include <linux/semaphore.h>
53
54#include <pcmcia/cistpl.h>
55#include <pcmcia/cisreg.h>
56#include <pcmcia/ds.h>
57
58#include <linux/completion.h>
59
60#include "comedi_fc.h"
61
62struct daqp_private {
63	int stop;
64
65	enum { semaphore, buffer } interrupt_mode;
66
67	struct completion eos;
68
69	int count;
70};
71
72/* The DAQP communicates with the system through a 16 byte I/O window. */
73
74#define DAQP_FIFO_SIZE		4096
75
76#define DAQP_FIFO		0
77#define DAQP_SCANLIST		1
78#define DAQP_CONTROL		2
79#define DAQP_STATUS		2
80#define DAQP_DIGITAL_IO		3
81#define DAQP_PACER_LOW		4
82#define DAQP_PACER_MID		5
83#define DAQP_PACER_HIGH		6
84#define DAQP_COMMAND		7
85#define DAQP_DA			8
86#define DAQP_TIMER		10
87#define DAQP_AUX		15
88
89#define DAQP_SCANLIST_DIFFERENTIAL	0x4000
90#define DAQP_SCANLIST_GAIN(x)		((x)<<12)
91#define DAQP_SCANLIST_CHANNEL(x)	((x)<<8)
92#define DAQP_SCANLIST_START		0x0080
93#define DAQP_SCANLIST_EXT_GAIN(x)	((x)<<4)
94#define DAQP_SCANLIST_EXT_CHANNEL(x)	(x)
95
96#define DAQP_CONTROL_PACER_100kHz	0xc0
97#define DAQP_CONTROL_PACER_1MHz		0x80
98#define DAQP_CONTROL_PACER_5MHz		0x40
99#define DAQP_CONTROL_PACER_EXTERNAL	0x00
100#define DAQP_CONTORL_EXPANSION		0x20
101#define DAQP_CONTROL_EOS_INT_ENABLE	0x10
102#define DAQP_CONTROL_FIFO_INT_ENABLE	0x08
103#define DAQP_CONTROL_TRIGGER_ONESHOT	0x00
104#define DAQP_CONTROL_TRIGGER_CONTINUOUS	0x04
105#define DAQP_CONTROL_TRIGGER_INTERNAL	0x00
106#define DAQP_CONTROL_TRIGGER_EXTERNAL	0x02
107#define DAQP_CONTROL_TRIGGER_RISING	0x00
108#define DAQP_CONTROL_TRIGGER_FALLING	0x01
109
110#define DAQP_STATUS_IDLE		0x80
111#define DAQP_STATUS_RUNNING		0x40
112#define DAQP_STATUS_EVENTS		0x38
113#define DAQP_STATUS_DATA_LOST		0x20
114#define DAQP_STATUS_END_OF_SCAN		0x10
115#define DAQP_STATUS_FIFO_THRESHOLD	0x08
116#define DAQP_STATUS_FIFO_FULL		0x04
117#define DAQP_STATUS_FIFO_NEARFULL	0x02
118#define DAQP_STATUS_FIFO_EMPTY		0x01
119
120#define DAQP_COMMAND_ARM		0x80
121#define DAQP_COMMAND_RSTF		0x40
122#define DAQP_COMMAND_RSTQ		0x20
123#define DAQP_COMMAND_STOP		0x10
124#define DAQP_COMMAND_LATCH		0x08
125#define DAQP_COMMAND_100kHz		0x00
126#define DAQP_COMMAND_50kHz		0x02
127#define DAQP_COMMAND_25kHz		0x04
128#define DAQP_COMMAND_FIFO_DATA		0x01
129#define DAQP_COMMAND_FIFO_PROGRAM	0x00
130
131#define DAQP_AUX_TRIGGER_TTL		0x00
132#define DAQP_AUX_TRIGGER_ANALOG		0x80
133#define DAQP_AUX_TRIGGER_PRETRIGGER	0x40
134#define DAQP_AUX_TIMER_INT_ENABLE	0x20
135#define DAQP_AUX_TIMER_RELOAD		0x00
136#define DAQP_AUX_TIMER_PAUSE		0x08
137#define DAQP_AUX_TIMER_GO		0x10
138#define DAQP_AUX_TIMER_GO_EXTERNAL	0x18
139#define DAQP_AUX_TIMER_EXTERNAL_SRC	0x04
140#define DAQP_AUX_TIMER_INTERNAL_SRC	0x00
141#define DAQP_AUX_DA_DIRECT		0x00
142#define DAQP_AUX_DA_OVERFLOW		0x01
143#define DAQP_AUX_DA_EXTERNAL		0x02
144#define DAQP_AUX_DA_PACER		0x03
145
146#define DAQP_AUX_RUNNING		0x80
147#define DAQP_AUX_TRIGGERED		0x40
148#define DAQP_AUX_DA_BUFFER		0x20
149#define DAQP_AUX_TIMER_OVERFLOW		0x10
150#define DAQP_AUX_CONVERSION		0x08
151#define DAQP_AUX_DATA_LOST		0x04
152#define DAQP_AUX_FIFO_NEARFULL		0x02
153#define DAQP_AUX_FIFO_EMPTY		0x01
154
155static const struct comedi_lrange range_daqp_ai = {
156	4, {
157		BIP_RANGE(10),
158		BIP_RANGE(5),
159		BIP_RANGE(2.5),
160		BIP_RANGE(1.25)
161	}
162};
163
164/* Cancel a running acquisition */
165
166static int daqp_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
167{
168	struct daqp_private *devpriv = dev->private;
169
170	if (devpriv->stop)
171		return -EIO;
172
173	outb(DAQP_COMMAND_STOP, dev->iobase + DAQP_COMMAND);
174
175	/* flush any linguring data in FIFO - superfluous here */
176	/* outb(DAQP_COMMAND_RSTF, dev->iobase+DAQP_COMMAND); */
177
178	devpriv->interrupt_mode = semaphore;
179
180	return 0;
181}
182
183/* Interrupt handler
184 *
185 * Operates in one of two modes.  If devpriv->interrupt_mode is
186 * 'semaphore', just signal the devpriv->eos completion and return
187 * (one-shot mode).  Otherwise (continuous mode), read data in from
188 * the card, transfer it to the buffer provided by the higher-level
189 * comedi kernel module, and signal various comedi callback routines,
190 * which run pretty quick.
191 */
192static enum irqreturn daqp_interrupt(int irq, void *dev_id)
193{
194	struct comedi_device *dev = dev_id;
195	struct daqp_private *devpriv = dev->private;
196	struct comedi_subdevice *s = dev->read_subdev;
197	int loop_limit = 10000;
198	int status;
199
200	if (!dev->attached)
201		return IRQ_NONE;
202
203	switch (devpriv->interrupt_mode) {
204	case semaphore:
205		complete(&devpriv->eos);
206		break;
207
208	case buffer:
209		while (!((status = inb(dev->iobase + DAQP_STATUS))
210			 & DAQP_STATUS_FIFO_EMPTY)) {
211			unsigned short data;
212
213			if (status & DAQP_STATUS_DATA_LOST) {
214				s->async->events |=
215				    COMEDI_CB_EOA | COMEDI_CB_OVERFLOW;
216				dev_warn(dev->class_dev, "data lost\n");
217				break;
218			}
219
220			data = inb(dev->iobase + DAQP_FIFO);
221			data |= inb(dev->iobase + DAQP_FIFO) << 8;
222			data ^= 0x8000;
223
224			comedi_buf_put(s, data);
225
226			/* If there's a limit, decrement it
227			 * and stop conversion if zero
228			 */
229
230			if (devpriv->count > 0) {
231				devpriv->count--;
232				if (devpriv->count == 0) {
233					s->async->events |= COMEDI_CB_EOA;
234					break;
235				}
236			}
237
238			if ((loop_limit--) <= 0)
239				break;
240		}
241
242		if (loop_limit <= 0) {
243			dev_warn(dev->class_dev,
244				 "loop_limit reached in daqp_interrupt()\n");
245			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
246		}
247
248		s->async->events |= COMEDI_CB_BLOCK;
249
250		cfc_handle_events(dev, s);
251	}
252	return IRQ_HANDLED;
253}
254
255static void daqp_ai_set_one_scanlist_entry(struct comedi_device *dev,
256					   unsigned int chanspec,
257					   int start)
258{
259	unsigned int chan = CR_CHAN(chanspec);
260	unsigned int range = CR_RANGE(chanspec);
261	unsigned int aref = CR_AREF(chanspec);
262	unsigned int val;
263
264	val = DAQP_SCANLIST_CHANNEL(chan) | DAQP_SCANLIST_GAIN(range);
265
266	if (aref == AREF_DIFF)
267		val |= DAQP_SCANLIST_DIFFERENTIAL;
268
269	if (start)
270		val |= DAQP_SCANLIST_START;
271
272	outb(val & 0xff, dev->iobase + DAQP_SCANLIST);
273	outb((val >> 8) & 0xff, dev->iobase + DAQP_SCANLIST);
274}
275
276/* One-shot analog data acquisition routine */
277
278static int daqp_ai_insn_read(struct comedi_device *dev,
279			     struct comedi_subdevice *s,
280			     struct comedi_insn *insn, unsigned int *data)
281{
282	struct daqp_private *devpriv = dev->private;
283	int i;
284	int v;
285	int counter = 10000;
286
287	if (devpriv->stop)
288		return -EIO;
289
290	/* Stop any running conversion */
291	daqp_ai_cancel(dev, s);
292
293	outb(0, dev->iobase + DAQP_AUX);
294
295	/* Reset scan list queue */
296	outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
297
298	/* Program one scan list entry */
299	daqp_ai_set_one_scanlist_entry(dev, insn->chanspec, 1);
300
301	/* Reset data FIFO (see page 28 of DAQP User's Manual) */
302
303	outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
304
305	/* Set trigger */
306
307	v = DAQP_CONTROL_TRIGGER_ONESHOT | DAQP_CONTROL_TRIGGER_INTERNAL
308	    | DAQP_CONTROL_PACER_100kHz | DAQP_CONTROL_EOS_INT_ENABLE;
309
310	outb(v, dev->iobase + DAQP_CONTROL);
311
312	/* Reset any pending interrupts (my card has a tendency to require
313	 * require multiple reads on the status register to achieve this)
314	 */
315
316	while (--counter
317	       && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS))
318		;
319	if (!counter) {
320		dev_err(dev->class_dev,
321			"couldn't clear interrupts in status register\n");
322		return -1;
323	}
324
325	init_completion(&devpriv->eos);
326	devpriv->interrupt_mode = semaphore;
327
328	for (i = 0; i < insn->n; i++) {
329
330		/* Start conversion */
331		outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
332		     dev->iobase + DAQP_COMMAND);
333
334		/* Wait for interrupt service routine to unblock completion */
335		/* Maybe could use a timeout here, but it's interruptible */
336		if (wait_for_completion_interruptible(&devpriv->eos))
337			return -EINTR;
338
339		data[i] = inb(dev->iobase + DAQP_FIFO);
340		data[i] |= inb(dev->iobase + DAQP_FIFO) << 8;
341		data[i] ^= 0x8000;
342	}
343
344	return insn->n;
345}
346
347/* This function converts ns nanoseconds to a counter value suitable
348 * for programming the device.  We always use the DAQP's 5 MHz clock,
349 * which with its 24-bit counter, allows values up to 84 seconds.
350 * Also, the function adjusts ns so that it cooresponds to the actual
351 * time that the device will use.
352 */
353
354static int daqp_ns_to_timer(unsigned int *ns, unsigned int flags)
355{
356	int timer;
357
358	timer = *ns / 200;
359	*ns = timer * 200;
360
361	return timer;
362}
363
364/* cmdtest tests a particular command to see if it is valid.
365 * Using the cmdtest ioctl, a user can create a valid cmd
366 * and then have it executed by the cmd ioctl.
367 *
368 * cmdtest returns 1,2,3,4 or 0, depending on which tests
369 * the command passes.
370 */
371
372static int daqp_ai_cmdtest(struct comedi_device *dev,
373			   struct comedi_subdevice *s, struct comedi_cmd *cmd)
374{
375	int err = 0;
376	unsigned int arg;
377
378	/* Step 1 : check if triggers are trivially valid */
379
380	err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
381	err |= cfc_check_trigger_src(&cmd->scan_begin_src,
382					TRIG_TIMER | TRIG_FOLLOW);
383	err |= cfc_check_trigger_src(&cmd->convert_src,
384					TRIG_TIMER | TRIG_NOW);
385	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
386	err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
387
388	if (err)
389		return 1;
390
391	/* Step 2a : make sure trigger sources are unique */
392
393	err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
394	err |= cfc_check_trigger_is_unique(cmd->convert_src);
395	err |= cfc_check_trigger_is_unique(cmd->stop_src);
396
397	/* Step 2b : and mutually compatible */
398
399	if (err)
400		return 2;
401
402	/* Step 3: check if arguments are trivially valid */
403
404	err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
405
406#define MAX_SPEED	10000	/* 100 kHz - in nanoseconds */
407
408	if (cmd->scan_begin_src == TRIG_TIMER)
409		err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
410						 MAX_SPEED);
411
412	/* If both scan_begin and convert are both timer values, the only
413	 * way that can make sense is if the scan time is the number of
414	 * conversions times the convert time
415	 */
416
417	if (cmd->scan_begin_src == TRIG_TIMER && cmd->convert_src == TRIG_TIMER
418	    && cmd->scan_begin_arg != cmd->convert_arg * cmd->scan_end_arg) {
419		err |= -EINVAL;
420	}
421
422	if (cmd->convert_src == TRIG_TIMER)
423		err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED);
424
425	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
426
427	if (cmd->stop_src == TRIG_COUNT)
428		err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff);
429	else	/* TRIG_NONE */
430		err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
431
432	if (err)
433		return 3;
434
435	/* step 4: fix up any arguments */
436
437	if (cmd->scan_begin_src == TRIG_TIMER) {
438		arg = cmd->scan_begin_arg;
439		daqp_ns_to_timer(&arg, cmd->flags);
440		err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
441	}
442
443	if (cmd->convert_src == TRIG_TIMER) {
444		arg = cmd->convert_arg;
445		daqp_ns_to_timer(&arg, cmd->flags);
446		err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
447	}
448
449	if (err)
450		return 4;
451
452	return 0;
453}
454
455static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
456{
457	struct daqp_private *devpriv = dev->private;
458	struct comedi_cmd *cmd = &s->async->cmd;
459	int counter;
460	int scanlist_start_on_every_entry;
461	int threshold;
462
463	int i;
464	int v;
465
466	if (devpriv->stop)
467		return -EIO;
468
469	/* Stop any running conversion */
470	daqp_ai_cancel(dev, s);
471
472	outb(0, dev->iobase + DAQP_AUX);
473
474	/* Reset scan list queue */
475	outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
476
477	/* Program pacer clock
478	 *
479	 * There's two modes we can operate in.  If convert_src is
480	 * TRIG_TIMER, then convert_arg specifies the time between
481	 * each conversion, so we program the pacer clock to that
482	 * frequency and set the SCANLIST_START bit on every scanlist
483	 * entry.  Otherwise, convert_src is TRIG_NOW, which means
484	 * we want the fastest possible conversions, scan_begin_src
485	 * is TRIG_TIMER, and scan_begin_arg specifies the time between
486	 * each scan, so we program the pacer clock to this frequency
487	 * and only set the SCANLIST_START bit on the first entry.
488	 */
489
490	if (cmd->convert_src == TRIG_TIMER) {
491		counter = daqp_ns_to_timer(&cmd->convert_arg, cmd->flags);
492		outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
493		outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
494		outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
495		scanlist_start_on_every_entry = 1;
496	} else {
497		counter = daqp_ns_to_timer(&cmd->scan_begin_arg, cmd->flags);
498		outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
499		outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
500		outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
501		scanlist_start_on_every_entry = 0;
502	}
503
504	/* Program scan list */
505	for (i = 0; i < cmd->chanlist_len; i++) {
506		int start = (i == 0 || scanlist_start_on_every_entry);
507
508		daqp_ai_set_one_scanlist_entry(dev, cmd->chanlist[i], start);
509	}
510
511	/* Now it's time to program the FIFO threshold, basically the
512	 * number of samples the card will buffer before it interrupts
513	 * the CPU.
514	 *
515	 * If we don't have a stop count, then use half the size of
516	 * the FIFO (the manufacturer's recommendation).  Consider
517	 * that the FIFO can hold 2K samples (4K bytes).  With the
518	 * threshold set at half the FIFO size, we have a margin of
519	 * error of 1024 samples.  At the chip's maximum sample rate
520	 * of 100,000 Hz, the CPU would have to delay interrupt
521	 * service for a full 10 milliseconds in order to lose data
522	 * here (as opposed to higher up in the kernel).  I've never
523	 * seen it happen.  However, for slow sample rates it may
524	 * buffer too much data and introduce too much delay for the
525	 * user application.
526	 *
527	 * If we have a stop count, then things get more interesting.
528	 * If the stop count is less than the FIFO size (actually
529	 * three-quarters of the FIFO size - see below), we just use
530	 * the stop count itself as the threshold, the card interrupts
531	 * us when that many samples have been taken, and we kill the
532	 * acquisition at that point and are done.  If the stop count
533	 * is larger than that, then we divide it by 2 until it's less
534	 * than three quarters of the FIFO size (we always leave the
535	 * top quarter of the FIFO as protection against sluggish CPU
536	 * interrupt response) and use that as the threshold.  So, if
537	 * the stop count is 4000 samples, we divide by two twice to
538	 * get 1000 samples, use that as the threshold, take four
539	 * interrupts to get our 4000 samples and are done.
540	 *
541	 * The algorithm could be more clever.  For example, if 81000
542	 * samples are requested, we could set the threshold to 1500
543	 * samples and take 54 interrupts to get 81000.  But 54 isn't
544	 * a power of two, so this algorithm won't find that option.
545	 * Instead, it'll set the threshold at 1266 and take 64
546	 * interrupts to get 81024 samples, of which the last 24 will
547	 * be discarded... but we won't get the last interrupt until
548	 * they've been collected.  To find the first option, the
549	 * computer could look at the prime decomposition of the
550	 * sample count (81000 = 3^4 * 5^3 * 2^3) and factor it into a
551	 * threshold (1500 = 3 * 5^3 * 2^2) and an interrupt count (54
552	 * = 3^3 * 2).  Hmmm... a one-line while loop or prime
553	 * decomposition of integers... I'll leave it the way it is.
554	 *
555	 * I'll also note a mini-race condition before ignoring it in
556	 * the code.  Let's say we're taking 4000 samples, as before.
557	 * After 1000 samples, we get an interrupt.  But before that
558	 * interrupt is completely serviced, another sample is taken
559	 * and loaded into the FIFO.  Since the interrupt handler
560	 * empties the FIFO before returning, it will read 1001 samples.
561	 * If that happens four times, we'll end up taking 4004 samples,
562	 * not 4000.  The interrupt handler will discard the extra four
563	 * samples (by halting the acquisition with four samples still
564	 * in the FIFO), but we will have to wait for them.
565	 *
566	 * In short, this code works pretty well, but for either of
567	 * the two reasons noted, might end up waiting for a few more
568	 * samples than actually requested.  Shouldn't make too much
569	 * of a difference.
570	 */
571
572	/* Save away the number of conversions we should perform, and
573	 * compute the FIFO threshold (in bytes, not samples - that's
574	 * why we multiple devpriv->count by 2 = sizeof(sample))
575	 */
576
577	if (cmd->stop_src == TRIG_COUNT) {
578		devpriv->count = cmd->stop_arg * cmd->scan_end_arg;
579		threshold = 2 * devpriv->count;
580		while (threshold > DAQP_FIFO_SIZE * 3 / 4)
581			threshold /= 2;
582	} else {
583		devpriv->count = -1;
584		threshold = DAQP_FIFO_SIZE / 2;
585	}
586
587	/* Reset data FIFO (see page 28 of DAQP User's Manual) */
588
589	outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
590
591	/* Set FIFO threshold.  First two bytes are near-empty
592	 * threshold, which is unused; next two bytes are near-full
593	 * threshold.  We computed the number of bytes we want in the
594	 * FIFO when the interrupt is generated, what the card wants
595	 * is actually the number of available bytes left in the FIFO
596	 * when the interrupt is to happen.
597	 */
598
599	outb(0x00, dev->iobase + DAQP_FIFO);
600	outb(0x00, dev->iobase + DAQP_FIFO);
601
602	outb((DAQP_FIFO_SIZE - threshold) & 0xff, dev->iobase + DAQP_FIFO);
603	outb((DAQP_FIFO_SIZE - threshold) >> 8, dev->iobase + DAQP_FIFO);
604
605	/* Set trigger */
606
607	v = DAQP_CONTROL_TRIGGER_CONTINUOUS | DAQP_CONTROL_TRIGGER_INTERNAL
608	    | DAQP_CONTROL_PACER_5MHz | DAQP_CONTROL_FIFO_INT_ENABLE;
609
610	outb(v, dev->iobase + DAQP_CONTROL);
611
612	/* Reset any pending interrupts (my card has a tendency to require
613	 * require multiple reads on the status register to achieve this)
614	 */
615	counter = 100;
616	while (--counter
617	       && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS))
618		;
619	if (!counter) {
620		dev_err(dev->class_dev,
621			"couldn't clear interrupts in status register\n");
622		return -1;
623	}
624
625	devpriv->interrupt_mode = buffer;
626
627	/* Start conversion */
628	outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
629	     dev->iobase + DAQP_COMMAND);
630
631	return 0;
632}
633
634static int daqp_ao_insn_write(struct comedi_device *dev,
635			      struct comedi_subdevice *s,
636			      struct comedi_insn *insn,
637			      unsigned int *data)
638{
639	struct daqp_private *devpriv = dev->private;
640	unsigned int chan = CR_CHAN(insn->chanspec);
641	int i;
642
643	if (devpriv->stop)
644		return -EIO;
645
646	/* Make sure D/A update mode is direct update */
647	outb(0, dev->iobase + DAQP_AUX);
648
649	for (i = 0; i > insn->n; i++) {
650		unsigned val = data[i];
651
652		s->readback[chan] = val;
653
654		val &= 0x0fff;
655		val ^= 0x0800;		/* Flip the sign */
656		val |= (chan << 12);
657
658		outw(val, dev->iobase + DAQP_DA);
659	}
660
661	return insn->n;
662}
663
664static int daqp_di_insn_bits(struct comedi_device *dev,
665			     struct comedi_subdevice *s,
666			     struct comedi_insn *insn,
667			     unsigned int *data)
668{
669	struct daqp_private *devpriv = dev->private;
670
671	if (devpriv->stop)
672		return -EIO;
673
674	data[0] = inb(dev->iobase + DAQP_DIGITAL_IO);
675
676	return insn->n;
677}
678
679static int daqp_do_insn_bits(struct comedi_device *dev,
680			     struct comedi_subdevice *s,
681			     struct comedi_insn *insn,
682			     unsigned int *data)
683{
684	struct daqp_private *devpriv = dev->private;
685
686	if (devpriv->stop)
687		return -EIO;
688
689	if (comedi_dio_update_state(s, data))
690		outb(s->state, dev->iobase + DAQP_DIGITAL_IO);
691
692	data[1] = s->state;
693
694	return insn->n;
695}
696
697static int daqp_auto_attach(struct comedi_device *dev,
698			    unsigned long context)
699{
700	struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
701	struct daqp_private *devpriv;
702	struct comedi_subdevice *s;
703	int ret;
704
705	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
706	if (!devpriv)
707		return -ENOMEM;
708
709	link->config_flags |= CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
710	ret = comedi_pcmcia_enable(dev, NULL);
711	if (ret)
712		return ret;
713	dev->iobase = link->resource[0]->start;
714
715	link->priv = dev;
716	ret = pcmcia_request_irq(link, daqp_interrupt);
717	if (ret)
718		return ret;
719
720	ret = comedi_alloc_subdevices(dev, 4);
721	if (ret)
722		return ret;
723
724	s = &dev->subdevices[0];
725	dev->read_subdev = s;
726	s->type		= COMEDI_SUBD_AI;
727	s->subdev_flags	= SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
728	s->n_chan	= 8;
729	s->len_chanlist	= 2048;
730	s->maxdata	= 0xffff;
731	s->range_table	= &range_daqp_ai;
732	s->insn_read	= daqp_ai_insn_read;
733	s->do_cmdtest	= daqp_ai_cmdtest;
734	s->do_cmd	= daqp_ai_cmd;
735	s->cancel	= daqp_ai_cancel;
736
737	s = &dev->subdevices[1];
738	s->type		= COMEDI_SUBD_AO;
739	s->subdev_flags	= SDF_WRITEABLE;
740	s->n_chan	= 2;
741	s->maxdata	= 0x0fff;
742	s->range_table	= &range_bipolar5;
743	s->insn_write	= daqp_ao_insn_write;
744	s->insn_read	= comedi_readback_insn_read;
745
746	ret = comedi_alloc_subdev_readback(s);
747	if (ret)
748		return ret;
749
750	s = &dev->subdevices[2];
751	s->type		= COMEDI_SUBD_DI;
752	s->subdev_flags	= SDF_READABLE;
753	s->n_chan	= 1;
754	s->maxdata	= 1;
755	s->insn_bits	= daqp_di_insn_bits;
756
757	s = &dev->subdevices[3];
758	s->type		= COMEDI_SUBD_DO;
759	s->subdev_flags	= SDF_WRITEABLE;
760	s->n_chan	= 1;
761	s->maxdata	= 1;
762	s->insn_bits	= daqp_do_insn_bits;
763
764	return 0;
765}
766
767static struct comedi_driver driver_daqp = {
768	.driver_name	= "quatech_daqp_cs",
769	.module		= THIS_MODULE,
770	.auto_attach	= daqp_auto_attach,
771	.detach		= comedi_pcmcia_disable,
772};
773
774static int daqp_cs_suspend(struct pcmcia_device *link)
775{
776	struct comedi_device *dev = link->priv;
777	struct daqp_private *devpriv = dev ? dev->private : NULL;
778
779	/* Mark the device as stopped, to block IO until later */
780	if (devpriv)
781		devpriv->stop = 1;
782
783	return 0;
784}
785
786static int daqp_cs_resume(struct pcmcia_device *link)
787{
788	struct comedi_device *dev = link->priv;
789	struct daqp_private *devpriv = dev ? dev->private : NULL;
790
791	if (devpriv)
792		devpriv->stop = 0;
793
794	return 0;
795}
796
797static int daqp_cs_attach(struct pcmcia_device *link)
798{
799	return comedi_pcmcia_auto_config(link, &driver_daqp);
800}
801
802static const struct pcmcia_device_id daqp_cs_id_table[] = {
803	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0027),
804	PCMCIA_DEVICE_NULL
805};
806MODULE_DEVICE_TABLE(pcmcia, daqp_cs_id_table);
807
808static struct pcmcia_driver daqp_cs_driver = {
809	.name		= "quatech_daqp_cs",
810	.owner		= THIS_MODULE,
811	.id_table	= daqp_cs_id_table,
812	.probe		= daqp_cs_attach,
813	.remove		= comedi_pcmcia_auto_unconfig,
814	.suspend	= daqp_cs_suspend,
815	.resume		= daqp_cs_resume,
816};
817module_comedi_pcmcia_driver(driver_daqp, daqp_cs_driver);
818
819MODULE_DESCRIPTION("Comedi driver for Quatech DAQP PCMCIA data capture cards");
820MODULE_AUTHOR("Brent Baccala <baccala@freesoft.org>");
821MODULE_LICENSE("GPL");
822