cb_pcidas.c revision 34c43922e62708d45e9660eee4b4f1fb7b4bf2c7
1/*
2    comedi/drivers/cb_pcidas.c
3
4    Developed by Ivan Martinez and Frank Mori Hess, with valuable help from
5    David Schleef and the rest of the Comedi developers comunity.
6
7    Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk>
8    Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
9
10    COMEDI - Linux Control and Measurement Device Interface
11    Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
12
13    This program is free software; you can redistribute it and/or modify
14    it under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2 of the License, or
16    (at your option) any later version.
17
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27************************************************************************
28*/
29/*
30Driver: cb_pcidas
31Description: MeasurementComputing PCI-DAS series with the AMCC S5933 PCI controller
32Author: Ivan Martinez <imr@oersted.dtu.dk>,
33  Frank Mori Hess <fmhess@users.sourceforge.net>
34Updated: 2003-3-11
35Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
36  PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
37  PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
38
39Status:
40  There are many reports of the driver being used with most of the
41  supported cards. Despite no detailed log is maintained, it can
42  be said that the driver is quite tested and stable.
43
44  The boards may be autocalibrated using the comedi_calibrate
45  utility.
46
47Configuration options:
48  [0] - PCI bus of device (optional)
49  [1] - PCI slot of device (optional)
50  If bus/slot is not specified, the first supported
51  PCI device found will be used.
52
53For commands, the scanned channels must be consecutive
54(i.e. 4-5-6-7, 2-3-4,...), and must all have the same
55range and aref.
56*/
57/*
58
59TODO:
60
61analog triggering on 1602 series
62*/
63
64#include "../comedidev.h"
65#include <linux/delay.h>
66
67#include "8253.h"
68#include "8255.h"
69#include "amcc_s5933.h"
70#include "comedi_pci.h"
71#include "comedi_fc.h"
72
73#undef CB_PCIDAS_DEBUG		// disable debugging code
74//#define CB_PCIDAS_DEBUG       // enable debugging code
75
76// PCI vendor number of ComputerBoards/MeasurementComputing
77#define PCI_VENDOR_ID_CB	0x1307
78#define TIMER_BASE 100		// 10MHz master clock
79#define AI_BUFFER_SIZE 1024	// maximum fifo size of any supported board
80#define AO_BUFFER_SIZE 1024	// maximum fifo size of any supported board
81#define NUM_CHANNELS_8800 8
82#define NUM_CHANNELS_7376 1
83#define NUM_CHANNELS_8402 2
84#define NUM_CHANNELS_DAC08 1
85
86/* PCI-DAS base addresses */
87
88// indices of base address regions
89#define S5933_BADRINDEX 0
90#define CONT_STAT_BADRINDEX 1
91#define ADC_FIFO_BADRINDEX 2
92#define PACER_BADRINDEX 3
93#define AO_BADRINDEX 4
94// sizes of io regions
95#define CONT_STAT_SIZE 10
96#define ADC_FIFO_SIZE 4
97#define PACER_SIZE 12
98#define AO_SIZE 4
99
100/* Control/Status registers */
101#define INT_ADCFIFO	0	// INTERRUPT / ADC FIFO register
102#define   INT_EOS 0x1		// interrupt end of scan
103#define   INT_FHF 0x2		// interrupt fifo half full
104#define   INT_FNE 0x3		// interrupt fifo not empty
105#define   INT_MASK 0x3		// mask of interrupt select bits
106#define   INTE 0x4		// interrupt enable
107#define   DAHFIE 0x8		// dac half full interrupt enable
108#define   EOAIE	0x10		// end of aquisition interrupt enable
109#define   DAHFI	0x20		// dac half full read status / write interrupt clear
110#define   EOAI 0x40		// read end of acq. interrupt status / write clear
111#define   INT 0x80		// read interrupt status / write clear
112#define   EOBI 0x200		// read end of burst interrupt status
113#define   ADHFI 0x400		// read half-full interrupt status
114#define   ADNEI 0x800		// read fifo not empty interrupt latch status
115#define   ADNE 0x1000		// read, fifo not empty (realtime, not latched) status
116#define   DAEMIE	0x1000	// write, dac empty interrupt enable
117#define   LADFUL 0x2000		// read fifo overflow / write clear
118#define   DAEMI 0x4000		// dac fifo empty interrupt status / write clear
119
120#define ADCMUX_CONT	2	// ADC CHANNEL MUX AND CONTROL register
121#define   BEGIN_SCAN(x)	((x) & 0xf)
122#define   END_SCAN(x)	(((x) & 0xf) << 4)
123#define   GAIN_BITS(x)	(((x) & 0x3) << 8)
124#define   UNIP	0x800		// Analog front-end unipolar for range
125#define   SE	0x400		// Inputs in single-ended mode
126#define   PACER_MASK	0x3000	// pacer source bits
127#define   PACER_INT 0x1000	// internal pacer
128#define   PACER_EXT_FALL	0x2000	// external falling edge
129#define   PACER_EXT_RISE	0x3000	// external rising edge
130#define   EOC	0x4000		// adc not busy
131
132#define TRIG_CONTSTAT 4		// TRIGGER CONTROL/STATUS register
133#define   SW_TRIGGER 0x1	// software start trigger
134#define   EXT_TRIGGER 0x2	// external start trigger
135#define   ANALOG_TRIGGER 0x3	// external analog trigger
136#define   TRIGGER_MASK	0x3	// mask of bits that determine start trigger
137#define   TGEN	0x10		// enable external start trigger
138#define   BURSTE 0x20		// burst mode enable
139#define   XTRCL	0x80		// clear external trigger
140
141#define CALIBRATION_REG	6	// CALIBRATION register
142#define   SELECT_8800_BIT	0x100	// select 8800 caldac
143#define   SELECT_TRIMPOT_BIT	0x200	// select ad7376 trim pot
144#define   SELECT_DAC08_BIT	0x400	// select dac08 caldac
145#define   CAL_SRC_BITS(x)	(((x) & 0x7) << 11)
146#define   CAL_EN_BIT	0x4000	// read calibration source instead of analog input channel 0
147#define   SERIAL_DATA_IN_BIT	0x8000	// serial data stream going to 8800 and 7376
148
149#define DAC_CSR	0x8		// dac control and status register
150enum dac_csr_bits {
151	DACEN = 0x2,		// dac enable
152	DAC_MODE_UPDATE_BOTH = 0x80,	// update both dacs when dac0 is written
153};
154static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
155{
156	return (range & 0x3) << (8 + 2 * (channel & 0x1));
157}
158static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
159{
160	return 0x3 << (8 + 2 * (channel & 0x1));
161};
162
163// bits for 1602 series only
164enum dac_csr_bits_1602 {
165	DAC_EMPTY = 0x1,	// dac fifo empty, read, write clear
166	DAC_START = 0x4,	// start/arm dac fifo operations
167	DAC_PACER_MASK = 0x18,	// bits that set dac pacer source
168	DAC_PACER_INT = 0x8,	// dac internal pacing
169	DAC_PACER_EXT_FALL = 0x10,	// dac external pacing, falling edge
170	DAC_PACER_EXT_RISE = 0x18,	// dac external pacing, rising edge
171};
172static inline unsigned int DAC_CHAN_EN(unsigned int channel)
173{
174	return 1 << (5 + (channel & 0x1));	// enable channel 0 or 1
175};
176
177/* analog input fifo */
178#define ADCDATA	0		// ADC DATA register
179#define ADCFIFOCLR	2	// ADC FIFO CLEAR
180
181// pacer, counter, dio registers
182#define ADC8254 0
183#define DIO_8255 4
184#define DAC8254 8
185
186// analog output registers for 100x, 1200 series
187static inline unsigned int DAC_DATA_REG(unsigned int channel)
188{
189	return 2 * (channel & 0x1);
190}
191
192/* analog output registers for 1602 series*/
193#define DACDATA	0		// DAC DATA register
194#define DACFIFOCLR	2	// DAC FIFO CLEAR
195
196// bit in hexadecimal representation of range index that indicates unipolar input range
197#define IS_UNIPOLAR 0x4
198// analog input ranges for most boards
199static const comedi_lrange cb_pcidas_ranges = {
200	8,
201	{
202			BIP_RANGE(10),
203			BIP_RANGE(5),
204			BIP_RANGE(2.5),
205			BIP_RANGE(1.25),
206			UNI_RANGE(10),
207			UNI_RANGE(5),
208			UNI_RANGE(2.5),
209			UNI_RANGE(1.25)
210		}
211};
212
213// pci-das1001 input ranges
214static const comedi_lrange cb_pcidas_alt_ranges = {
215	8,
216	{
217			BIP_RANGE(10),
218			BIP_RANGE(1),
219			BIP_RANGE(0.1),
220			BIP_RANGE(0.01),
221			UNI_RANGE(10),
222			UNI_RANGE(1),
223			UNI_RANGE(0.1),
224			UNI_RANGE(0.01)
225		}
226};
227
228// analog output ranges
229static const comedi_lrange cb_pcidas_ao_ranges = {
230	4,
231	{
232			BIP_RANGE(5),
233			BIP_RANGE(10),
234			UNI_RANGE(5),
235			UNI_RANGE(10),
236		}
237};
238
239enum trimpot_model {
240	AD7376,
241	AD8402,
242};
243
244typedef struct cb_pcidas_board_struct {
245	const char *name;
246	unsigned short device_id;
247	int ai_se_chans;	// Inputs in single-ended mode
248	int ai_diff_chans;	// Inputs in differential mode
249	int ai_bits;		// analog input resolution
250	int ai_speed;		// fastest conversion period in ns
251	int ao_nchan;		// number of analog out channels
252	int has_ao_fifo;	// analog output has fifo
253	int ao_scan_speed;	// analog output speed for 1602 series (for a scan, not conversion)
254	int fifo_size;		// number of samples fifo can hold
255	const comedi_lrange *ranges;
256	enum trimpot_model trimpot;
257	unsigned has_dac08:1;
258} cb_pcidas_board;
259
260static const cb_pcidas_board cb_pcidas_boards[] = {
261	{
262	      name:	"pci-das1602/16",
263	      device_id:0x1,
264	      ai_se_chans:16,
265	      ai_diff_chans:8,
266	      ai_bits:	16,
267	      ai_speed:5000,
268	      ao_nchan:2,
269	      has_ao_fifo:1,
270	      ao_scan_speed:10000,
271	      fifo_size:512,
272	      ranges:	&cb_pcidas_ranges,
273	      trimpot:	AD8402,
274	      has_dac08:1,
275		},
276	{
277	      name:	"pci-das1200",
278	      device_id:0xF,
279	      ai_se_chans:16,
280	      ai_diff_chans:8,
281	      ai_bits:	12,
282	      ai_speed:3200,
283	      ao_nchan:2,
284	      has_ao_fifo:0,
285	      fifo_size:1024,
286	      ranges:	&cb_pcidas_ranges,
287	      trimpot:	AD7376,
288	      has_dac08:0,
289		},
290	{
291	      name:	"pci-das1602/12",
292	      device_id:0x10,
293	      ai_se_chans:16,
294	      ai_diff_chans:8,
295	      ai_bits:	12,
296	      ai_speed:3200,
297	      ao_nchan:2,
298	      has_ao_fifo:1,
299	      ao_scan_speed:4000,
300	      fifo_size:1024,
301	      ranges:	&cb_pcidas_ranges,
302	      trimpot:	AD7376,
303	      has_dac08:0,
304		},
305	{
306	      name:	"pci-das1200/jr",
307	      device_id:0x19,
308	      ai_se_chans:16,
309	      ai_diff_chans:8,
310	      ai_bits:	12,
311	      ai_speed:3200,
312	      ao_nchan:0,
313	      has_ao_fifo:0,
314	      fifo_size:1024,
315	      ranges:	&cb_pcidas_ranges,
316	      trimpot:	AD7376,
317	      has_dac08:0,
318		},
319	{
320	      name:	"pci-das1602/16/jr",
321	      device_id:0x1C,
322	      ai_se_chans:16,
323	      ai_diff_chans:8,
324	      ai_bits:	16,
325	      ai_speed:5000,
326	      ao_nchan:0,
327	      has_ao_fifo:0,
328	      fifo_size:512,
329	      ranges:	&cb_pcidas_ranges,
330	      trimpot:	AD8402,
331	      has_dac08:1,
332		},
333	{
334	      name:	"pci-das1000",
335	      device_id:0x4C,
336	      ai_se_chans:16,
337	      ai_diff_chans:8,
338	      ai_bits:	12,
339	      ai_speed:4000,
340	      ao_nchan:0,
341	      has_ao_fifo:0,
342	      fifo_size:1024,
343	      ranges:	&cb_pcidas_ranges,
344	      trimpot:	AD7376,
345	      has_dac08:0,
346		},
347	{
348	      name:	"pci-das1001",
349	      device_id:0x1a,
350	      ai_se_chans:16,
351	      ai_diff_chans:8,
352	      ai_bits:	12,
353	      ai_speed:6800,
354	      ao_nchan:2,
355	      has_ao_fifo:0,
356	      fifo_size:1024,
357	      ranges:	&cb_pcidas_alt_ranges,
358	      trimpot:	AD7376,
359	      has_dac08:0,
360		},
361	{
362	      name:	"pci-das1002",
363	      device_id:0x1b,
364	      ai_se_chans:16,
365	      ai_diff_chans:8,
366	      ai_bits:	12,
367	      ai_speed:6800,
368	      ao_nchan:2,
369	      has_ao_fifo:0,
370	      fifo_size:1024,
371	      ranges:	&cb_pcidas_ranges,
372	      trimpot:	AD7376,
373	      has_dac08:0,
374		},
375};
376
377// Number of boards in cb_pcidas_boards
378#define N_BOARDS	(sizeof(cb_pcidas_boards) / sizeof(cb_pcidas_board))
379
380static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
381	{PCI_VENDOR_ID_CB, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
382	{PCI_VENDOR_ID_CB, 0x000f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
383	{PCI_VENDOR_ID_CB, 0x0010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
384	{PCI_VENDOR_ID_CB, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
385	{PCI_VENDOR_ID_CB, 0x001c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
386	{PCI_VENDOR_ID_CB, 0x004c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
387	{PCI_VENDOR_ID_CB, 0x001a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
388	{PCI_VENDOR_ID_CB, 0x001b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
389	{0}
390};
391
392MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
393
394/*
395 * Useful for shorthand access to the particular board structure
396 */
397#define thisboard ((const cb_pcidas_board *)dev->board_ptr)
398
399/* this structure is for data unique to this hardware driver.  If
400   several hardware drivers keep similar information in this structure,
401   feel free to suggest moving the variable to the struct comedi_device struct.  */
402typedef struct {
403	/* would be useful for a PCI device */
404	struct pci_dev *pci_dev;
405	// base addresses
406	unsigned long s5933_config;
407	unsigned long control_status;
408	unsigned long adc_fifo;
409	unsigned long pacer_counter_dio;
410	unsigned long ao_registers;
411	// divisors of master clock for analog input pacing
412	unsigned int divisor1;
413	unsigned int divisor2;
414	volatile unsigned int count;	// number of analog input samples remaining
415	volatile unsigned int adc_fifo_bits;	// bits to write to interupt/adcfifo register
416	volatile unsigned int s5933_intcsr_bits;	// bits to write to amcc s5933 interrupt control/status register
417	volatile unsigned int ao_control_bits;	// bits to write to ao control and status register
418	short ai_buffer[AI_BUFFER_SIZE];
419	short ao_buffer[AO_BUFFER_SIZE];
420	// divisors of master clock for analog output pacing
421	unsigned int ao_divisor1;
422	unsigned int ao_divisor2;
423	volatile unsigned int ao_count;	// number of analog output samples remaining
424	int ao_value[2];	// remember what the analog outputs are set to, to allow readback
425	unsigned int caldac_value[NUM_CHANNELS_8800];	// for readback of caldac
426	unsigned int trimpot_value[NUM_CHANNELS_8402];	// for readback of trimpot
427	unsigned int dac08_value;
428	unsigned int calibration_source;
429} cb_pcidas_private;
430
431/*
432 * most drivers define the following macro to make it easy to
433 * access the private structure.
434 */
435#define devpriv ((cb_pcidas_private *)dev->private)
436
437/*
438 * The comedi_driver structure tells the Comedi core module
439 * which functions to call to configure/deconfigure (attach/detach)
440 * the board, and also about the kernel module that contains
441 * the device code.
442 */
443static int cb_pcidas_attach(struct comedi_device * dev, comedi_devconfig * it);
444static int cb_pcidas_detach(struct comedi_device * dev);
445static comedi_driver driver_cb_pcidas = {
446      driver_name:"cb_pcidas",
447      module:THIS_MODULE,
448      attach:cb_pcidas_attach,
449      detach:cb_pcidas_detach,
450};
451
452static int cb_pcidas_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
453	comedi_insn * insn, unsigned int * data);
454static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
455	comedi_insn * insn, unsigned int * data);
456static int cb_pcidas_ao_nofifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
457	comedi_insn * insn, unsigned int * data);
458static int cb_pcidas_ao_fifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
459	comedi_insn * insn, unsigned int * data);
460static int cb_pcidas_ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
461	comedi_insn * insn, unsigned int * data);
462static int cb_pcidas_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
463static int cb_pcidas_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
464	comedi_cmd * cmd);
465static int cb_pcidas_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
466static int cb_pcidas_ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * subdev,
467	unsigned int trig_num);
468static int cb_pcidas_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
469	comedi_cmd * cmd);
470static irqreturn_t cb_pcidas_interrupt(int irq, void *d PT_REGS_ARG);
471static void handle_ao_interrupt(struct comedi_device * dev, unsigned int status);
472static int cb_pcidas_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
473static int cb_pcidas_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
474static void cb_pcidas_load_counters(struct comedi_device * dev, unsigned int *ns,
475	int round_flags);
476static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
477	comedi_insn * insn, unsigned int * data);
478static int caldac_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
479	comedi_insn * insn, unsigned int * data);
480static int caldac_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
481	comedi_insn * insn, unsigned int * data);
482static int trimpot_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
483	comedi_insn * insn, unsigned int * data);
484static int cb_pcidas_trimpot_write(struct comedi_device * dev, unsigned int channel,
485	unsigned int value);
486static int trimpot_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
487	comedi_insn * insn, unsigned int * data);
488static int dac08_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
489	comedi_insn * insn, unsigned int * data);
490static int dac08_write(struct comedi_device * dev, unsigned int value);
491static int dac08_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
492	comedi_insn * insn, unsigned int * data);
493static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
494	uint8_t value);
495static int trimpot_7376_write(struct comedi_device * dev, uint8_t value);
496static int trimpot_8402_write(struct comedi_device * dev, unsigned int channel,
497	uint8_t value);
498static int nvram_read(struct comedi_device * dev, unsigned int address,
499	uint8_t * data);
500
501static inline unsigned int cal_enable_bits(struct comedi_device * dev)
502{
503	return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
504}
505
506/*
507 * Attach is called by the Comedi core to configure the driver
508 * for a particular board.
509 */
510static int cb_pcidas_attach(struct comedi_device * dev, comedi_devconfig * it)
511{
512	struct comedi_subdevice *s;
513	struct pci_dev *pcidev;
514	int index;
515	int i;
516
517	printk("comedi%d: cb_pcidas: ", dev->minor);
518
519/*
520 * Allocate the private structure area.
521 */
522	if (alloc_private(dev, sizeof(cb_pcidas_private)) < 0)
523		return -ENOMEM;
524
525/*
526 * Probe the device to determine what device in the series it is.
527 */
528	printk("\n");
529
530	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
531		pcidev != NULL;
532		pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
533		// is it not a computer boards card?
534		if (pcidev->vendor != PCI_VENDOR_ID_CB)
535			continue;
536		// loop through cards supported by this driver
537		for (index = 0; index < N_BOARDS; index++) {
538			if (cb_pcidas_boards[index].device_id != pcidev->device)
539				continue;
540			// was a particular bus/slot requested?
541			if (it->options[0] || it->options[1]) {
542				// are we on the wrong bus/slot?
543				if (pcidev->bus->number != it->options[0] ||
544					PCI_SLOT(pcidev->devfn) !=
545					it->options[1]) {
546					continue;
547				}
548			}
549			devpriv->pci_dev = pcidev;
550			dev->board_ptr = cb_pcidas_boards + index;
551			goto found;
552		}
553	}
554
555	printk("No supported ComputerBoards/MeasurementComputing card found on "
556		"requested position\n");
557	return -EIO;
558
559      found:
560
561	printk("Found %s on bus %i, slot %i\n", cb_pcidas_boards[index].name,
562		pcidev->bus->number, PCI_SLOT(pcidev->devfn));
563
564	/*
565	 * Enable PCI device and reserve I/O ports.
566	 */
567	if (comedi_pci_enable(pcidev, "cb_pcidas")) {
568		printk(" Failed to enable PCI device and request regions\n");
569		return -EIO;
570	}
571	/*
572	 * Initialize devpriv->control_status and devpriv->adc_fifo to point to
573	 * their base address.
574	 */
575	devpriv->s5933_config =
576		pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX);
577	devpriv->control_status =
578		pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX);
579	devpriv->adc_fifo =
580		pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX);
581	devpriv->pacer_counter_dio =
582		pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX);
583	if (thisboard->ao_nchan) {
584		devpriv->ao_registers =
585			pci_resource_start(devpriv->pci_dev, AO_BADRINDEX);
586	}
587	// disable and clear interrupts on amcc s5933
588	outl(INTCSR_INBOX_INTR_STATUS,
589		devpriv->s5933_config + AMCC_OP_REG_INTCSR);
590
591	// get irq
592	if (comedi_request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt,
593			IRQF_SHARED, "cb_pcidas", dev)) {
594		printk(" unable to allocate irq %d\n", devpriv->pci_dev->irq);
595		return -EINVAL;
596	}
597	dev->irq = devpriv->pci_dev->irq;
598
599	//Initialize dev->board_name
600	dev->board_name = thisboard->name;
601
602/*
603 * Allocate the subdevice structures.
604 */
605	if (alloc_subdevices(dev, 7) < 0)
606		return -ENOMEM;
607
608	s = dev->subdevices + 0;
609	/* analog input subdevice */
610	dev->read_subdev = s;
611	s->type = COMEDI_SUBD_AI;
612	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
613	/* WARNING: Number of inputs in differential mode is ignored */
614	s->n_chan = thisboard->ai_se_chans;
615	s->len_chanlist = thisboard->ai_se_chans;
616	s->maxdata = (1 << thisboard->ai_bits) - 1;
617	s->range_table = thisboard->ranges;
618	s->insn_read = cb_pcidas_ai_rinsn;
619	s->insn_config = ai_config_insn;
620	s->do_cmd = cb_pcidas_ai_cmd;
621	s->do_cmdtest = cb_pcidas_ai_cmdtest;
622	s->cancel = cb_pcidas_cancel;
623
624	/* analog output subdevice */
625	s = dev->subdevices + 1;
626	if (thisboard->ao_nchan) {
627		s->type = COMEDI_SUBD_AO;
628		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
629		s->n_chan = thisboard->ao_nchan;
630		// analog out resolution is the same as analog input resolution, so use ai_bits
631		s->maxdata = (1 << thisboard->ai_bits) - 1;
632		s->range_table = &cb_pcidas_ao_ranges;
633		s->insn_read = cb_pcidas_ao_readback_insn;
634		if (thisboard->has_ao_fifo) {
635			dev->write_subdev = s;
636			s->subdev_flags |= SDF_CMD_WRITE;
637			s->insn_write = cb_pcidas_ao_fifo_winsn;
638			s->do_cmdtest = cb_pcidas_ao_cmdtest;
639			s->do_cmd = cb_pcidas_ao_cmd;
640			s->cancel = cb_pcidas_ao_cancel;
641		} else {
642			s->insn_write = cb_pcidas_ao_nofifo_winsn;
643		}
644	} else {
645		s->type = COMEDI_SUBD_UNUSED;
646	}
647
648	/* 8255 */
649	s = dev->subdevices + 2;
650	subdev_8255_init(dev, s, NULL, devpriv->pacer_counter_dio + DIO_8255);
651
652	// serial EEPROM,
653	s = dev->subdevices + 3;
654	s->type = COMEDI_SUBD_MEMORY;
655	s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
656	s->n_chan = 256;
657	s->maxdata = 0xff;
658	s->insn_read = eeprom_read_insn;
659
660	// 8800 caldac
661	s = dev->subdevices + 4;
662	s->type = COMEDI_SUBD_CALIB;
663	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
664	s->n_chan = NUM_CHANNELS_8800;
665	s->maxdata = 0xff;
666	s->insn_read = caldac_read_insn;
667	s->insn_write = caldac_write_insn;
668	for (i = 0; i < s->n_chan; i++)
669		caldac_8800_write(dev, i, s->maxdata / 2);
670
671	// trim potentiometer
672	s = dev->subdevices + 5;
673	s->type = COMEDI_SUBD_CALIB;
674	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
675	if (thisboard->trimpot == AD7376) {
676		s->n_chan = NUM_CHANNELS_7376;
677		s->maxdata = 0x7f;
678	} else {
679		s->n_chan = NUM_CHANNELS_8402;
680		s->maxdata = 0xff;
681	}
682	s->insn_read = trimpot_read_insn;
683	s->insn_write = trimpot_write_insn;
684	for (i = 0; i < s->n_chan; i++)
685		cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
686
687	// dac08 caldac
688	s = dev->subdevices + 6;
689	if (thisboard->has_dac08) {
690		s->type = COMEDI_SUBD_CALIB;
691		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
692		s->n_chan = NUM_CHANNELS_DAC08;
693		s->insn_read = dac08_read_insn;
694		s->insn_write = dac08_write_insn;
695		s->maxdata = 0xff;
696		dac08_write(dev, s->maxdata / 2);
697	} else
698		s->type = COMEDI_SUBD_UNUSED;
699
700	// make sure mailbox 4 is empty
701	inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
702	/* Set bits to enable incoming mailbox interrupts on amcc s5933. */
703	devpriv->s5933_intcsr_bits =
704		INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
705		INTCSR_INBOX_FULL_INT;
706	// clear and enable interrupt on amcc s5933
707	outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
708		devpriv->s5933_config + AMCC_OP_REG_INTCSR);
709
710	return 1;
711}
712
713/*
714 * cb_pcidas_detach is called to deconfigure a device.  It should deallocate
715 * resources.
716 * This function is also called when _attach() fails, so it should be
717 * careful not to release resources that were not necessarily
718 * allocated by _attach().  dev->private and dev->subdevices are
719 * deallocated automatically by the core.
720 */
721static int cb_pcidas_detach(struct comedi_device * dev)
722{
723	printk("comedi%d: cb_pcidas: remove\n", dev->minor);
724
725	if (devpriv) {
726		if (devpriv->s5933_config) {
727			// disable and clear interrupts on amcc s5933
728			outl(INTCSR_INBOX_INTR_STATUS,
729				devpriv->s5933_config + AMCC_OP_REG_INTCSR);
730#ifdef CB_PCIDAS_DEBUG
731			rt_printk("detaching, incsr is 0x%x\n",
732				inl(devpriv->s5933_config +
733					AMCC_OP_REG_INTCSR));
734#endif
735		}
736	}
737	if (dev->irq)
738		comedi_free_irq(dev->irq, dev);
739	if (dev->subdevices)
740		subdev_8255_cleanup(dev, dev->subdevices + 2);
741	if (devpriv && devpriv->pci_dev) {
742		if (devpriv->s5933_config) {
743			comedi_pci_disable(devpriv->pci_dev);
744		}
745		pci_dev_put(devpriv->pci_dev);
746	}
747
748	return 0;
749}
750
751/*
752 * "instructions" read/write data in "one-shot" or "software-triggered"
753 * mode.
754 */
755static int cb_pcidas_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
756	comedi_insn * insn, unsigned int * data)
757{
758	int n, i;
759	unsigned int bits;
760	static const int timeout = 10000;
761	int channel;
762	// enable calibration input if appropriate
763	if (insn->chanspec & CR_ALT_SOURCE) {
764		outw(cal_enable_bits(dev),
765			devpriv->control_status + CALIBRATION_REG);
766		channel = 0;
767	} else {
768		outw(0, devpriv->control_status + CALIBRATION_REG);
769		channel = CR_CHAN(insn->chanspec);
770	}
771	// set mux limits and gain
772	bits = BEGIN_SCAN(channel) |
773		END_SCAN(channel) | GAIN_BITS(CR_RANGE(insn->chanspec));
774	// set unipolar/bipolar
775	if (CR_RANGE(insn->chanspec) & IS_UNIPOLAR)
776		bits |= UNIP;
777	// set singleended/differential
778	if (CR_AREF(insn->chanspec) != AREF_DIFF)
779		bits |= SE;
780	outw(bits, devpriv->control_status + ADCMUX_CONT);
781
782	/* clear fifo */
783	outw(0, devpriv->adc_fifo + ADCFIFOCLR);
784
785	/* convert n samples */
786	for (n = 0; n < insn->n; n++) {
787		/* trigger conversion */
788		outw(0, devpriv->adc_fifo + ADCDATA);
789
790		/* wait for conversion to end */
791		/* return -ETIMEDOUT if there is a timeout */
792		for (i = 0; i < timeout; i++) {
793			if (inw(devpriv->control_status + ADCMUX_CONT) & EOC)
794				break;
795		}
796		if (i == timeout)
797			return -ETIMEDOUT;
798
799		/* read data */
800		data[n] = inw(devpriv->adc_fifo + ADCDATA);
801	}
802
803	/* return the number of samples read/written */
804	return n;
805}
806
807static int ai_config_calibration_source(struct comedi_device * dev, unsigned int * data)
808{
809	static const int num_calibration_sources = 8;
810	unsigned int source = data[1];
811
812	if (source >= num_calibration_sources) {
813		printk("invalid calibration source: %i\n", source);
814		return -EINVAL;
815	}
816
817	devpriv->calibration_source = source;
818
819	return 2;
820}
821
822static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
823	comedi_insn * insn, unsigned int * data)
824{
825	int id = data[0];
826
827	switch (id) {
828	case INSN_CONFIG_ALT_SOURCE:
829		return ai_config_calibration_source(dev, data);
830		break;
831	default:
832		return -EINVAL;
833		break;
834	}
835	return -EINVAL;
836}
837
838// analog output insn for pcidas-1000 and 1200 series
839static int cb_pcidas_ao_nofifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
840	comedi_insn * insn, unsigned int * data)
841{
842	int channel;
843	unsigned long flags;
844
845	// set channel and range
846	channel = CR_CHAN(insn->chanspec);
847	comedi_spin_lock_irqsave(&dev->spinlock, flags);
848	devpriv->ao_control_bits &=
849		~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel);
850	devpriv->ao_control_bits |=
851		DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec));
852	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
853	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
854
855	// remember value for readback
856	devpriv->ao_value[channel] = data[0];
857	// send data
858	outw(data[0], devpriv->ao_registers + DAC_DATA_REG(channel));
859
860	return 1;
861}
862
863// analog output insn for pcidas-1602 series
864static int cb_pcidas_ao_fifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
865	comedi_insn * insn, unsigned int * data)
866{
867	int channel;
868	unsigned long flags;
869
870	// clear dac fifo
871	outw(0, devpriv->ao_registers + DACFIFOCLR);
872
873	// set channel and range
874	channel = CR_CHAN(insn->chanspec);
875	comedi_spin_lock_irqsave(&dev->spinlock, flags);
876	devpriv->ao_control_bits &=
877		~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) & ~DAC_RANGE_MASK(channel) &
878		~DAC_PACER_MASK;
879	devpriv->ao_control_bits |=
880		DACEN | DAC_RANGE(channel,
881		CR_RANGE(insn->chanspec)) | DAC_CHAN_EN(channel) | DAC_START;
882	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
883	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
884
885	// remember value for readback
886	devpriv->ao_value[channel] = data[0];
887	// send data
888	outw(data[0], devpriv->ao_registers + DACDATA);
889
890	return 1;
891}
892
893// analog output readback insn
894// XXX loses track of analog output value back after an analog ouput command is executed
895static int cb_pcidas_ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
896	comedi_insn * insn, unsigned int * data)
897{
898	data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
899
900	return 1;
901}
902
903static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
904	comedi_insn * insn, unsigned int * data)
905{
906	uint8_t nvram_data;
907	int retval;
908
909	retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
910	if (retval < 0)
911		return retval;
912
913	data[0] = nvram_data;
914
915	return 1;
916}
917
918static int caldac_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
919	comedi_insn * insn, unsigned int * data)
920{
921	const unsigned int channel = CR_CHAN(insn->chanspec);
922
923	return caldac_8800_write(dev, channel, data[0]);
924}
925
926static int caldac_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
927	comedi_insn * insn, unsigned int * data)
928{
929	data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
930
931	return 1;
932}
933
934/* 1602/16 pregain offset */
935static int dac08_write(struct comedi_device * dev, unsigned int value)
936{
937	if (devpriv->dac08_value == value)
938		return 1;
939
940	devpriv->dac08_value = value;
941
942	outw(cal_enable_bits(dev) | (value & 0xff),
943		devpriv->control_status + CALIBRATION_REG);
944	comedi_udelay(1);
945	outw(cal_enable_bits(dev) | SELECT_DAC08_BIT | (value & 0xff),
946		devpriv->control_status + CALIBRATION_REG);
947	comedi_udelay(1);
948	outw(cal_enable_bits(dev) | (value & 0xff),
949		devpriv->control_status + CALIBRATION_REG);
950	comedi_udelay(1);
951
952	return 1;
953}
954
955static int dac08_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
956	comedi_insn * insn, unsigned int * data)
957{
958	return dac08_write(dev, data[0]);
959}
960
961static int dac08_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
962	comedi_insn * insn, unsigned int * data)
963{
964	data[0] = devpriv->dac08_value;
965
966	return 1;
967}
968
969static int cb_pcidas_trimpot_write(struct comedi_device * dev,
970	unsigned int channel, unsigned int value)
971{
972	if (devpriv->trimpot_value[channel] == value)
973		return 1;
974
975	devpriv->trimpot_value[channel] = value;
976	switch (thisboard->trimpot) {
977	case AD7376:
978		trimpot_7376_write(dev, value);
979		break;
980	case AD8402:
981		trimpot_8402_write(dev, channel, value);
982		break;
983	default:
984		comedi_error(dev, "driver bug?");
985		return -1;
986		break;
987	}
988
989	return 1;
990}
991
992static int trimpot_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
993	comedi_insn * insn, unsigned int * data)
994{
995	unsigned int channel = CR_CHAN(insn->chanspec);
996
997	return cb_pcidas_trimpot_write(dev, channel, data[0]);
998}
999
1000static int trimpot_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
1001	comedi_insn * insn, unsigned int * data)
1002{
1003	unsigned int channel = CR_CHAN(insn->chanspec);
1004
1005	data[0] = devpriv->trimpot_value[channel];
1006
1007	return 1;
1008}
1009
1010static int cb_pcidas_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
1011	comedi_cmd * cmd)
1012{
1013	int err = 0;
1014	int tmp;
1015	int i, gain, start_chan;
1016
1017	/* cmdtest tests a particular command to see if it is valid.
1018	 * Using the cmdtest ioctl, a user can create a valid cmd
1019	 * and then have it executes by the cmd ioctl.
1020	 *
1021	 * cmdtest returns 1,2,3,4 or 0, depending on which tests
1022	 * the command passes. */
1023
1024	/* step 1: make sure trigger sources are trivially valid */
1025
1026	tmp = cmd->start_src;
1027	cmd->start_src &= TRIG_NOW | TRIG_EXT;
1028	if (!cmd->start_src || tmp != cmd->start_src)
1029		err++;
1030
1031	tmp = cmd->scan_begin_src;
1032	cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
1033	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1034		err++;
1035
1036	tmp = cmd->convert_src;
1037	cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT;
1038	if (!cmd->convert_src || tmp != cmd->convert_src)
1039		err++;
1040
1041	tmp = cmd->scan_end_src;
1042	cmd->scan_end_src &= TRIG_COUNT;
1043	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1044		err++;
1045
1046	tmp = cmd->stop_src;
1047	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1048	if (!cmd->stop_src || tmp != cmd->stop_src)
1049		err++;
1050
1051	if (err)
1052		return 1;
1053
1054	/* step 2: make sure trigger sources are unique and mutually compatible */
1055
1056	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
1057		err++;
1058	if (cmd->scan_begin_src != TRIG_FOLLOW &&
1059		cmd->scan_begin_src != TRIG_TIMER &&
1060		cmd->scan_begin_src != TRIG_EXT)
1061		err++;
1062	if (cmd->convert_src != TRIG_TIMER &&
1063		cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
1064		err++;
1065	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1066		err++;
1067
1068	// make sure trigger sources are compatible with each other
1069	if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
1070		err++;
1071	if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
1072		err++;
1073	if (cmd->start_src == TRIG_EXT &&
1074		(cmd->convert_src == TRIG_EXT
1075			|| cmd->scan_begin_src == TRIG_EXT))
1076		err++;
1077
1078	if (err)
1079		return 2;
1080
1081	/* step 3: make sure arguments are trivially compatible */
1082
1083	if (cmd->start_arg != 0) {
1084		cmd->start_arg = 0;
1085		err++;
1086	}
1087
1088	if (cmd->scan_begin_src == TRIG_TIMER) {
1089		if (cmd->scan_begin_arg <
1090			thisboard->ai_speed * cmd->chanlist_len) {
1091			cmd->scan_begin_arg =
1092				thisboard->ai_speed * cmd->chanlist_len;
1093			err++;
1094		}
1095	}
1096	if (cmd->convert_src == TRIG_TIMER) {
1097		if (cmd->convert_arg < thisboard->ai_speed) {
1098			cmd->convert_arg = thisboard->ai_speed;
1099			err++;
1100		}
1101	}
1102
1103	if (cmd->scan_end_arg != cmd->chanlist_len) {
1104		cmd->scan_end_arg = cmd->chanlist_len;
1105		err++;
1106	}
1107	if (cmd->stop_src == TRIG_NONE) {
1108		/* TRIG_NONE */
1109		if (cmd->stop_arg != 0) {
1110			cmd->stop_arg = 0;
1111			err++;
1112		}
1113	}
1114
1115	if (err)
1116		return 3;
1117
1118	/* step 4: fix up any arguments */
1119
1120	if (cmd->scan_begin_src == TRIG_TIMER) {
1121		tmp = cmd->scan_begin_arg;
1122		i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1123			&(devpriv->divisor1), &(devpriv->divisor2),
1124			&(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
1125		if (tmp != cmd->scan_begin_arg)
1126			err++;
1127	}
1128	if (cmd->convert_src == TRIG_TIMER) {
1129		tmp = cmd->convert_arg;
1130		i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1131			&(devpriv->divisor1), &(devpriv->divisor2),
1132			&(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
1133		if (tmp != cmd->convert_arg)
1134			err++;
1135	}
1136
1137	if (err)
1138		return 4;
1139
1140	// check channel/gain list against card's limitations
1141	if (cmd->chanlist) {
1142		gain = CR_RANGE(cmd->chanlist[0]);
1143		start_chan = CR_CHAN(cmd->chanlist[0]);
1144		for (i = 1; i < cmd->chanlist_len; i++) {
1145			if (CR_CHAN(cmd->chanlist[i]) !=
1146				(start_chan + i) % s->n_chan) {
1147				comedi_error(dev,
1148					"entries in chanlist must be consecutive channels, counting upwards\n");
1149				err++;
1150			}
1151			if (CR_RANGE(cmd->chanlist[i]) != gain) {
1152				comedi_error(dev,
1153					"entries in chanlist must all have the same gain\n");
1154				err++;
1155			}
1156		}
1157	}
1158
1159	if (err)
1160		return 5;
1161
1162	return 0;
1163}
1164
1165static int cb_pcidas_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
1166{
1167	comedi_async *async = s->async;
1168	comedi_cmd *cmd = &async->cmd;
1169	unsigned int bits;
1170	unsigned long flags;
1171
1172	// make sure CAL_EN_BIT is disabled
1173	outw(0, devpriv->control_status + CALIBRATION_REG);
1174	// initialize before settings pacer source and count values
1175	outw(0, devpriv->control_status + TRIG_CONTSTAT);
1176	// clear fifo
1177	outw(0, devpriv->adc_fifo + ADCFIFOCLR);
1178
1179	// set mux limits, gain and pacer source
1180	bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
1181		END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
1182		GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
1183	// set unipolar/bipolar
1184	if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
1185		bits |= UNIP;
1186	// set singleended/differential
1187	if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
1188		bits |= SE;
1189	// set pacer source
1190	if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
1191		bits |= PACER_EXT_RISE;
1192	else
1193		bits |= PACER_INT;
1194	outw(bits, devpriv->control_status + ADCMUX_CONT);
1195
1196#ifdef CB_PCIDAS_DEBUG
1197	rt_printk("comedi: sent 0x%x to adcmux control\n", bits);
1198#endif
1199
1200	// load counters
1201	if (cmd->convert_src == TRIG_TIMER)
1202		cb_pcidas_load_counters(dev, &cmd->convert_arg,
1203			cmd->flags & TRIG_ROUND_MASK);
1204	else if (cmd->scan_begin_src == TRIG_TIMER)
1205		cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
1206			cmd->flags & TRIG_ROUND_MASK);
1207
1208	// set number of conversions
1209	if (cmd->stop_src == TRIG_COUNT) {
1210		devpriv->count = cmd->chanlist_len * cmd->stop_arg;
1211	}
1212	// enable interrupts
1213	comedi_spin_lock_irqsave(&dev->spinlock, flags);
1214	devpriv->adc_fifo_bits |= INTE;
1215	devpriv->adc_fifo_bits &= ~INT_MASK;
1216	if (cmd->flags & TRIG_WAKE_EOS) {
1217		if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1218			devpriv->adc_fifo_bits |= INT_EOS;	// interrupt end of burst
1219		else
1220			devpriv->adc_fifo_bits |= INT_FNE;	// interrupt fifo not empty
1221	} else {
1222		devpriv->adc_fifo_bits |= INT_FHF;	//interrupt fifo half full
1223	}
1224#ifdef CB_PCIDAS_DEBUG
1225	rt_printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits);
1226#endif
1227	// enable (and clear) interrupts
1228	outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1229		devpriv->control_status + INT_ADCFIFO);
1230	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1231
1232	// set start trigger and burst mode
1233	bits = 0;
1234	if (cmd->start_src == TRIG_NOW)
1235		bits |= SW_TRIGGER;
1236	else if (cmd->start_src == TRIG_EXT)
1237		bits |= EXT_TRIGGER | TGEN | XTRCL;
1238	else {
1239		comedi_error(dev, "bug!");
1240		return -1;
1241	}
1242	if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1243		bits |= BURSTE;
1244	outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1245#ifdef CB_PCIDAS_DEBUG
1246	rt_printk("comedi: sent 0x%x to trig control\n", bits);
1247#endif
1248
1249	return 0;
1250}
1251
1252static int cb_pcidas_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
1253	comedi_cmd * cmd)
1254{
1255	int err = 0;
1256	int tmp;
1257
1258	/* cmdtest tests a particular command to see if it is valid.
1259	 * Using the cmdtest ioctl, a user can create a valid cmd
1260	 * and then have it executes by the cmd ioctl.
1261	 *
1262	 * cmdtest returns 1,2,3,4 or 0, depending on which tests
1263	 * the command passes. */
1264
1265	/* step 1: make sure trigger sources are trivially valid */
1266
1267	tmp = cmd->start_src;
1268	cmd->start_src &= TRIG_INT;
1269	if (!cmd->start_src || tmp != cmd->start_src)
1270		err++;
1271
1272	tmp = cmd->scan_begin_src;
1273	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
1274	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1275		err++;
1276
1277	tmp = cmd->convert_src;
1278	cmd->convert_src &= TRIG_NOW;
1279	if (!cmd->convert_src || tmp != cmd->convert_src)
1280		err++;
1281
1282	tmp = cmd->scan_end_src;
1283	cmd->scan_end_src &= TRIG_COUNT;
1284	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1285		err++;
1286
1287	tmp = cmd->stop_src;
1288	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1289	if (!cmd->stop_src || tmp != cmd->stop_src)
1290		err++;
1291
1292	if (err)
1293		return 1;
1294
1295	/* step 2: make sure trigger sources are unique and mutually compatible */
1296
1297	if (cmd->scan_begin_src != TRIG_TIMER &&
1298		cmd->scan_begin_src != TRIG_EXT)
1299		err++;
1300	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1301		err++;
1302
1303	if (err)
1304		return 2;
1305
1306	/* step 3: make sure arguments are trivially compatible */
1307
1308	if (cmd->start_arg != 0) {
1309		cmd->start_arg = 0;
1310		err++;
1311	}
1312
1313	if (cmd->scan_begin_src == TRIG_TIMER) {
1314		if (cmd->scan_begin_arg < thisboard->ao_scan_speed) {
1315			cmd->scan_begin_arg = thisboard->ao_scan_speed;
1316			err++;
1317		}
1318	}
1319
1320	if (cmd->scan_end_arg != cmd->chanlist_len) {
1321		cmd->scan_end_arg = cmd->chanlist_len;
1322		err++;
1323	}
1324	if (cmd->stop_src == TRIG_NONE) {
1325		/* TRIG_NONE */
1326		if (cmd->stop_arg != 0) {
1327			cmd->stop_arg = 0;
1328			err++;
1329		}
1330	}
1331
1332	if (err)
1333		return 3;
1334
1335	/* step 4: fix up any arguments */
1336
1337	if (cmd->scan_begin_src == TRIG_TIMER) {
1338		tmp = cmd->scan_begin_arg;
1339		i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1340			&(devpriv->ao_divisor1), &(devpriv->ao_divisor2),
1341			&(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
1342		if (tmp != cmd->scan_begin_arg)
1343			err++;
1344	}
1345
1346	if (err)
1347		return 4;
1348
1349	// check channel/gain list against card's limitations
1350	if (cmd->chanlist && cmd->chanlist_len > 1) {
1351		if (CR_CHAN(cmd->chanlist[0]) != 0 ||
1352			CR_CHAN(cmd->chanlist[1]) != 1) {
1353			comedi_error(dev,
1354				"channels must be ordered channel 0, channel 1 in chanlist\n");
1355			err++;
1356		}
1357	}
1358
1359	if (err)
1360		return 5;
1361
1362	return 0;
1363}
1364
1365static int cb_pcidas_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
1366{
1367	comedi_async *async = s->async;
1368	comedi_cmd *cmd = &async->cmd;
1369	unsigned int i;
1370	unsigned long flags;
1371
1372	// set channel limits, gain
1373	comedi_spin_lock_irqsave(&dev->spinlock, flags);
1374	for (i = 0; i < cmd->chanlist_len; i++) {
1375		// enable channel
1376		devpriv->ao_control_bits |=
1377			DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1378		// set range
1379		devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1380			CR_RANGE(cmd->chanlist[i]));
1381	}
1382
1383	// disable analog out before settings pacer source and count values
1384	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1385	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1386
1387	// clear fifo
1388	outw(0, devpriv->ao_registers + DACFIFOCLR);
1389
1390	// load counters
1391	if (cmd->scan_begin_src == TRIG_TIMER) {
1392		i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1393			&(devpriv->ao_divisor1), &(devpriv->ao_divisor2),
1394			&(cmd->scan_begin_arg), cmd->flags);
1395
1396		/* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1397		i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
1398			devpriv->ao_divisor1, 2);
1399		i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
1400			devpriv->ao_divisor2, 2);
1401	}
1402	// set number of conversions
1403	if (cmd->stop_src == TRIG_COUNT) {
1404		devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1405	}
1406	// set pacer source
1407	comedi_spin_lock_irqsave(&dev->spinlock, flags);
1408	switch (cmd->scan_begin_src) {
1409	case TRIG_TIMER:
1410		devpriv->ao_control_bits |= DAC_PACER_INT;
1411		break;
1412	case TRIG_EXT:
1413		devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1414		break;
1415	default:
1416		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1417		comedi_error(dev, "error setting dac pacer source");
1418		return -1;
1419		break;
1420	}
1421	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1422
1423	async->inttrig = cb_pcidas_ao_inttrig;
1424
1425	return 0;
1426}
1427
1428static int cb_pcidas_ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
1429	unsigned int trig_num)
1430{
1431	unsigned int num_bytes, num_points = thisboard->fifo_size;
1432	comedi_async *async = s->async;
1433	comedi_cmd *cmd = &s->async->cmd;
1434	unsigned long flags;
1435
1436	if (trig_num != 0)
1437		return -EINVAL;
1438
1439	// load up fifo
1440	if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1441		num_points = devpriv->ao_count;
1442
1443	num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1444		num_points * sizeof(short));
1445	num_points = num_bytes / sizeof(short);
1446
1447	if (cmd->stop_src == TRIG_COUNT) {
1448		devpriv->ao_count -= num_points;
1449	}
1450	// write data to board's fifo
1451	outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1452
1453	// enable dac half-full and empty interrupts
1454	comedi_spin_lock_irqsave(&dev->spinlock, flags);
1455	devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1456#ifdef CB_PCIDAS_DEBUG
1457	rt_printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits);
1458#endif
1459	// enable and clear interrupts
1460	outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1461		devpriv->control_status + INT_ADCFIFO);
1462
1463	// start dac
1464	devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1465	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1466#ifdef CB_PCIDAS_DEBUG
1467	rt_printk("comedi: sent 0x%x to dac control\n",
1468		devpriv->ao_control_bits);
1469#endif
1470	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1471
1472	async->inttrig = NULL;
1473
1474	return 0;
1475}
1476
1477static irqreturn_t cb_pcidas_interrupt(int irq, void *d PT_REGS_ARG)
1478{
1479	struct comedi_device *dev = (struct comedi_device *) d;
1480	struct comedi_subdevice *s = dev->read_subdev;
1481	comedi_async *async;
1482	int status, s5933_status;
1483	int half_fifo = thisboard->fifo_size / 2;
1484	unsigned int num_samples, i;
1485	static const int timeout = 10000;
1486	unsigned long flags;
1487
1488	if (dev->attached == 0) {
1489		return IRQ_NONE;
1490	}
1491
1492	async = s->async;
1493	async->events = 0;
1494
1495	s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1496#ifdef CB_PCIDAS_DEBUG
1497	rt_printk("intcsr 0x%x\n", s5933_status);
1498	rt_printk("mbef 0x%x\n", inl(devpriv->s5933_config + AMCC_OP_REG_MBEF));
1499#endif
1500
1501	if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1502		return IRQ_NONE;
1503
1504	// make sure mailbox 4 is empty
1505	inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1506	// clear interrupt on amcc s5933
1507	outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1508		devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1509
1510	status = inw(devpriv->control_status + INT_ADCFIFO);
1511#ifdef CB_PCIDAS_DEBUG
1512	if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) {
1513		comedi_error(dev, "spurious interrupt");
1514	}
1515#endif
1516
1517	// check for analog output interrupt
1518	if (status & (DAHFI | DAEMI)) {
1519		handle_ao_interrupt(dev, status);
1520	}
1521	// check for analog input interrupts
1522	// if fifo half-full
1523	if (status & ADHFI) {
1524		// read data
1525		num_samples = half_fifo;
1526		if (async->cmd.stop_src == TRIG_COUNT &&
1527			num_samples > devpriv->count) {
1528			num_samples = devpriv->count;
1529		}
1530		insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1531			num_samples);
1532		cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1533			num_samples * sizeof(short));
1534		devpriv->count -= num_samples;
1535		if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
1536			async->events |= COMEDI_CB_EOA;
1537			cb_pcidas_cancel(dev, s);
1538		}
1539		// clear half-full interrupt latch
1540		comedi_spin_lock_irqsave(&dev->spinlock, flags);
1541		outw(devpriv->adc_fifo_bits | INT,
1542			devpriv->control_status + INT_ADCFIFO);
1543		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1544		// else if fifo not empty
1545	} else if (status & (ADNEI | EOBI)) {
1546		for (i = 0; i < timeout; i++) {
1547			// break if fifo is empty
1548			if ((ADNE & inw(devpriv->control_status +
1549						INT_ADCFIFO)) == 0)
1550				break;
1551			cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1552			if (async->cmd.stop_src == TRIG_COUNT && --devpriv->count == 0) {	/* end of acquisition */
1553				cb_pcidas_cancel(dev, s);
1554				async->events |= COMEDI_CB_EOA;
1555				break;
1556			}
1557		}
1558		// clear not-empty interrupt latch
1559		comedi_spin_lock_irqsave(&dev->spinlock, flags);
1560		outw(devpriv->adc_fifo_bits | INT,
1561			devpriv->control_status + INT_ADCFIFO);
1562		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1563	} else if (status & EOAI) {
1564		comedi_error(dev,
1565			"bug! encountered end of aquisition interrupt?");
1566		// clear EOA interrupt latch
1567		comedi_spin_lock_irqsave(&dev->spinlock, flags);
1568		outw(devpriv->adc_fifo_bits | EOAI,
1569			devpriv->control_status + INT_ADCFIFO);
1570		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1571	}
1572	//check for fifo overflow
1573	if (status & LADFUL) {
1574		comedi_error(dev, "fifo overflow");
1575		// clear overflow interrupt latch
1576		comedi_spin_lock_irqsave(&dev->spinlock, flags);
1577		outw(devpriv->adc_fifo_bits | LADFUL,
1578			devpriv->control_status + INT_ADCFIFO);
1579		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1580		cb_pcidas_cancel(dev, s);
1581		async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1582	}
1583
1584	comedi_event(dev, s);
1585
1586	return IRQ_HANDLED;
1587}
1588
1589static void handle_ao_interrupt(struct comedi_device * dev, unsigned int status)
1590{
1591	struct comedi_subdevice *s = dev->write_subdev;
1592	comedi_async *async = s->async;
1593	comedi_cmd *cmd = &async->cmd;
1594	unsigned int half_fifo = thisboard->fifo_size / 2;
1595	unsigned int num_points;
1596	unsigned int flags;
1597
1598	async->events = 0;
1599
1600	if (status & DAEMI) {
1601		// clear dac empty interrupt latch
1602		comedi_spin_lock_irqsave(&dev->spinlock, flags);
1603		outw(devpriv->adc_fifo_bits | DAEMI,
1604			devpriv->control_status + INT_ADCFIFO);
1605		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1606		if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1607			if (cmd->stop_src == TRIG_NONE ||
1608				(cmd->stop_src == TRIG_COUNT
1609					&& devpriv->ao_count)) {
1610				comedi_error(dev, "dac fifo underflow");
1611				cb_pcidas_ao_cancel(dev, s);
1612				async->events |= COMEDI_CB_ERROR;
1613			}
1614			async->events |= COMEDI_CB_EOA;
1615		}
1616	} else if (status & DAHFI) {
1617		unsigned int num_bytes;
1618
1619		// figure out how many points we are writing to fifo
1620		num_points = half_fifo;
1621		if (cmd->stop_src == TRIG_COUNT &&
1622			devpriv->ao_count < num_points)
1623			num_points = devpriv->ao_count;
1624		num_bytes =
1625			cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1626			num_points * sizeof(short));
1627		num_points = num_bytes / sizeof(short);
1628
1629		if (async->cmd.stop_src == TRIG_COUNT) {
1630			devpriv->ao_count -= num_points;
1631		}
1632		// write data to board's fifo
1633		outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1634			num_points);
1635		// clear half-full interrupt latch
1636		comedi_spin_lock_irqsave(&dev->spinlock, flags);
1637		outw(devpriv->adc_fifo_bits | DAHFI,
1638			devpriv->control_status + INT_ADCFIFO);
1639		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1640	}
1641
1642	comedi_event(dev, s);
1643}
1644
1645// cancel analog input command
1646static int cb_pcidas_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
1647{
1648	unsigned long flags;
1649
1650	comedi_spin_lock_irqsave(&dev->spinlock, flags);
1651	// disable interrupts
1652	devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1653	outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1654	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1655
1656	// disable start trigger source and burst mode
1657	outw(0, devpriv->control_status + TRIG_CONTSTAT);
1658	// software pacer source
1659	outw(0, devpriv->control_status + ADCMUX_CONT);
1660
1661	return 0;
1662}
1663
1664// cancel analog output command
1665static int cb_pcidas_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
1666{
1667	unsigned long flags;
1668
1669	comedi_spin_lock_irqsave(&dev->spinlock, flags);
1670	// disable interrupts
1671	devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1672	outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1673
1674	// disable output
1675	devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1676	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1677	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1678
1679	return 0;
1680}
1681
1682static void cb_pcidas_load_counters(struct comedi_device * dev, unsigned int *ns,
1683	int rounding_flags)
1684{
1685	i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
1686		&(devpriv->divisor2), ns, rounding_flags & TRIG_ROUND_MASK);
1687
1688	/* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1689	i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
1690		devpriv->divisor1, 2);
1691	i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
1692		devpriv->divisor2, 2);
1693}
1694
1695static void write_calibration_bitstream(struct comedi_device * dev,
1696	unsigned int register_bits, unsigned int bitstream,
1697	unsigned int bitstream_length)
1698{
1699	static const int write_delay = 1;
1700	unsigned int bit;
1701
1702	for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
1703		if (bitstream & bit)
1704			register_bits |= SERIAL_DATA_IN_BIT;
1705		else
1706			register_bits &= ~SERIAL_DATA_IN_BIT;
1707		comedi_udelay(write_delay);
1708		outw(register_bits, devpriv->control_status + CALIBRATION_REG);
1709	}
1710}
1711
1712static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
1713	uint8_t value)
1714{
1715	static const int num_caldac_channels = 8;
1716	static const int bitstream_length = 11;
1717	unsigned int bitstream = ((address & 0x7) << 8) | value;
1718	static const int caldac_8800_comedi_udelay = 1;
1719
1720	if (address >= num_caldac_channels) {
1721		comedi_error(dev, "illegal caldac channel");
1722		return -1;
1723	}
1724
1725	if (value == devpriv->caldac_value[address])
1726		return 1;
1727
1728	devpriv->caldac_value[address] = value;
1729
1730	write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
1731		bitstream_length);
1732
1733	comedi_udelay(caldac_8800_comedi_udelay);
1734	outw(cal_enable_bits(dev) | SELECT_8800_BIT,
1735		devpriv->control_status + CALIBRATION_REG);
1736	comedi_udelay(caldac_8800_comedi_udelay);
1737	outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
1738
1739	return 1;
1740}
1741
1742static int trimpot_7376_write(struct comedi_device * dev, uint8_t value)
1743{
1744	static const int bitstream_length = 7;
1745	unsigned int bitstream = value & 0x7f;
1746	unsigned int register_bits;
1747	static const int ad7376_comedi_udelay = 1;
1748
1749	register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
1750	comedi_udelay(ad7376_comedi_udelay);
1751	outw(register_bits, devpriv->control_status + CALIBRATION_REG);
1752
1753	write_calibration_bitstream(dev, register_bits, bitstream,
1754		bitstream_length);
1755
1756	comedi_udelay(ad7376_comedi_udelay);
1757	outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
1758
1759	return 0;
1760}
1761
1762/* For 1602/16 only
1763 * ch 0 : adc gain
1764 * ch 1 : adc postgain offset */
1765static int trimpot_8402_write(struct comedi_device * dev, unsigned int channel,
1766	uint8_t value)
1767{
1768	static const int bitstream_length = 10;
1769	unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
1770	unsigned int register_bits;
1771	static const int ad8402_comedi_udelay = 1;
1772
1773	register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
1774	comedi_udelay(ad8402_comedi_udelay);
1775	outw(register_bits, devpriv->control_status + CALIBRATION_REG);
1776
1777	write_calibration_bitstream(dev, register_bits, bitstream,
1778		bitstream_length);
1779
1780	comedi_udelay(ad8402_comedi_udelay);
1781	outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
1782
1783	return 0;
1784}
1785
1786static int wait_for_nvram_ready(unsigned long s5933_base_addr)
1787{
1788	static const int timeout = 1000;
1789	unsigned int i;
1790
1791	for (i = 0; i < timeout; i++) {
1792		if ((inb(s5933_base_addr +
1793					AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
1794			== 0)
1795			return 0;
1796		comedi_udelay(1);
1797	}
1798	return -1;
1799}
1800
1801static int nvram_read(struct comedi_device * dev, unsigned int address, uint8_t * data)
1802{
1803	unsigned long iobase = devpriv->s5933_config;
1804
1805	if (wait_for_nvram_ready(iobase) < 0)
1806		return -ETIMEDOUT;
1807
1808	outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
1809		iobase + AMCC_OP_REG_MCSR_NVCMD);
1810	outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
1811	outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
1812		iobase + AMCC_OP_REG_MCSR_NVCMD);
1813	outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
1814	outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
1815
1816	if (wait_for_nvram_ready(iobase) < 0)
1817		return -ETIMEDOUT;
1818
1819	*data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
1820
1821	return 0;
1822}
1823
1824/*
1825 * A convenient macro that defines init_module() and cleanup_module(),
1826 * as necessary.
1827 */
1828COMEDI_PCI_INITCLEANUP(driver_cb_pcidas, cb_pcidas_pci_table);
1829