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 /*
24 Driver: cb_pcidas
25 Description: MeasurementComputing PCI-DAS series
26   with the AMCC S5933 PCI controller
27 Author: Ivan Martinez <imr@oersted.dtu.dk>,
28   Frank Mori Hess <fmhess@users.sourceforge.net>
29 Updated: 2003-3-11
30 Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
31   PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
32   PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
33 
34 Status:
35   There are many reports of the driver being used with most of the
36   supported cards. Despite no detailed log is maintained, it can
37   be said that the driver is quite tested and stable.
38 
39   The boards may be autocalibrated using the comedi_calibrate
40   utility.
41 
42 Configuration options: not applicable, uses PCI auto config
43 
44 For commands, the scanned channels must be consecutive
45 (i.e. 4-5-6-7, 2-3-4,...), and must all have the same
46 range and aref.
47 
48 AI Triggering:
49    For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used.
50    For 1602 series, the start_arg is interpreted as follows:
51      start_arg == 0                   => gated trigger (level high)
52      start_arg == CR_INVERT           => gated trigger (level low)
53      start_arg == CR_EDGE             => Rising edge
54      start_arg == CR_EDGE | CR_INVERT => Falling edge
55    For the other boards the trigger will be done on rising edge
56 */
57 /*
58 
59 TODO:
60 
61 analog triggering on 1602 series
62 */
63 
64 #include <linux/module.h>
65 #include <linux/delay.h>
66 #include <linux/interrupt.h>
67 
68 #include "../comedi_pci.h"
69 
70 #include "comedi_8254.h"
71 #include "8255.h"
72 #include "amcc_s5933.h"
73 
74 #define AI_BUFFER_SIZE		1024	/* max ai fifo size */
75 #define AO_BUFFER_SIZE		1024	/* max ao fifo size */
76 #define NUM_CHANNELS_8800	8
77 #define NUM_CHANNELS_7376	1
78 #define NUM_CHANNELS_8402	2
79 #define NUM_CHANNELS_DAC08	1
80 
81 /* Control/Status registers */
82 #define INT_ADCFIFO		0	/* INTERRUPT / ADC FIFO register */
83 #define   INT_EOS		0x1	/* int end of scan */
84 #define   INT_FHF		0x2	/* int fifo half full */
85 #define   INT_FNE		0x3	/* int fifo not empty */
86 #define   INT_MASK		0x3	/* mask of int select bits */
87 #define   INTE			0x4	/* int enable */
88 #define   DAHFIE		0x8	/* dac half full int enable */
89 #define   EOAIE			0x10	/* end of acq. int enable */
90 #define   DAHFI			0x20	/* dac half full status / clear */
91 #define   EOAI			0x40	/* end of acq. int status / clear */
92 #define   INT			0x80	/* int status / clear */
93 #define   EOBI			0x200	/* end of burst int status */
94 #define   ADHFI			0x400	/* half-full int status */
95 #define   ADNEI			0x800	/* fifo not empty int status (latch) */
96 #define   ADNE			0x1000	/* fifo not empty status (realtime) */
97 #define   DAEMIE		0x1000	/* dac empty int enable */
98 #define   LADFUL		0x2000	/* fifo overflow / clear */
99 #define   DAEMI			0x4000	/* dac fifo empty int status / clear */
100 
101 #define ADCMUX_CONT		2	/* ADC CHANNEL MUX AND CONTROL reg */
102 #define   BEGIN_SCAN(x)		((x) & 0xf)
103 #define   END_SCAN(x)		(((x) & 0xf) << 4)
104 #define   GAIN_BITS(x)		(((x) & 0x3) << 8)
105 #define   UNIP			0x800	/* Analog front-end unipolar mode */
106 #define   SE			0x400	/* Inputs in single-ended mode */
107 #define   PACER_MASK		0x3000	/* pacer source bits */
108 #define   PACER_INT		0x1000	/* int. pacer */
109 #define   PACER_EXT_FALL	0x2000	/* ext. falling edge */
110 #define   PACER_EXT_RISE	0x3000	/* ext. rising edge */
111 #define   EOC			0x4000	/* adc not busy */
112 
113 #define TRIG_CONTSTAT		 4	/* TRIGGER CONTROL/STATUS register */
114 #define   SW_TRIGGER		0x1	/* software start trigger */
115 #define   EXT_TRIGGER		0x2	/* ext. start trigger */
116 #define   ANALOG_TRIGGER	0x3	/* ext. analog trigger */
117 #define   TRIGGER_MASK		0x3	/* start trigger mask */
118 #define   TGPOL			0x04	/* invert trigger (1602 only) */
119 #define   TGSEL			0x08	/* edge/level trigerred (1602 only) */
120 #define   TGEN			0x10	/* enable external start trigger */
121 #define   BURSTE		0x20	/* burst mode enable */
122 #define   XTRCL			0x80	/* clear external trigger */
123 
124 #define CALIBRATION_REG		6	/* CALIBRATION register */
125 #define   SELECT_8800_BIT	0x100	/* select 8800 caldac */
126 #define   SELECT_TRIMPOT_BIT	0x200	/* select ad7376 trim pot */
127 #define   SELECT_DAC08_BIT	0x400	/* select dac08 caldac */
128 #define   CAL_SRC_BITS(x)	(((x) & 0x7) << 11)
129 #define   CAL_EN_BIT		0x4000	/* calibration source enable */
130 #define   SERIAL_DATA_IN_BIT	0x8000	/* serial data bit going to caldac */
131 
132 #define DAC_CSR			0x8	/* dac control and status register */
133 #define   DACEN			0x02	/* dac enable */
134 #define   DAC_MODE_UPDATE_BOTH	0x80	/* update both dacs */
135 
DAC_RANGE(unsigned int channel,unsigned int range)136 static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
137 {
138 	return (range & 0x3) << (8 + 2 * (channel & 0x1));
139 }
140 
DAC_RANGE_MASK(unsigned int channel)141 static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
142 {
143 	return 0x3 << (8 + 2 * (channel & 0x1));
144 };
145 
146 /* bits for 1602 series only */
147 #define   DAC_EMPTY		0x1	/* fifo empty, read, write clear */
148 #define   DAC_START		0x4	/* start/arm fifo operations */
149 #define   DAC_PACER_MASK	0x18	/* bits that set pacer source */
150 #define   DAC_PACER_INT		0x8	/* int. pacing */
151 #define   DAC_PACER_EXT_FALL	0x10	/* ext. pacing, falling edge */
152 #define   DAC_PACER_EXT_RISE	0x18	/* ext. pacing, rising edge */
153 
DAC_CHAN_EN(unsigned int channel)154 static inline unsigned int DAC_CHAN_EN(unsigned int channel)
155 {
156 	return 1 << (5 + (channel & 0x1));	/*  enable channel 0 or 1 */
157 };
158 
159 /* analog input fifo */
160 #define ADCDATA			0	/* ADC DATA register */
161 #define ADCFIFOCLR		2	/* ADC FIFO CLEAR */
162 
163 /* pacer, counter, dio registers */
164 #define ADC8254			0
165 #define DIO_8255		4
166 #define DAC8254			8
167 
168 /* analog output registers for 100x, 1200 series */
DAC_DATA_REG(unsigned int channel)169 static inline unsigned int DAC_DATA_REG(unsigned int channel)
170 {
171 	return 2 * (channel & 0x1);
172 }
173 
174 /* analog output registers for 1602 series*/
175 #define DACDATA			0	/* DAC DATA register */
176 #define DACFIFOCLR		2	/* DAC FIFO CLEAR */
177 
178 #define IS_UNIPOLAR		0x4	/* unipolar range mask */
179 
180 /* analog input ranges for most boards */
181 static const struct comedi_lrange cb_pcidas_ranges = {
182 	8, {
183 		BIP_RANGE(10),
184 		BIP_RANGE(5),
185 		BIP_RANGE(2.5),
186 		BIP_RANGE(1.25),
187 		UNI_RANGE(10),
188 		UNI_RANGE(5),
189 		UNI_RANGE(2.5),
190 		UNI_RANGE(1.25)
191 	}
192 };
193 
194 /* pci-das1001 input ranges */
195 static const struct comedi_lrange cb_pcidas_alt_ranges = {
196 	8, {
197 		BIP_RANGE(10),
198 		BIP_RANGE(1),
199 		BIP_RANGE(0.1),
200 		BIP_RANGE(0.01),
201 		UNI_RANGE(10),
202 		UNI_RANGE(1),
203 		UNI_RANGE(0.1),
204 		UNI_RANGE(0.01)
205 	}
206 };
207 
208 /* analog output ranges */
209 static const struct comedi_lrange cb_pcidas_ao_ranges = {
210 	4, {
211 		BIP_RANGE(5),
212 		BIP_RANGE(10),
213 		UNI_RANGE(5),
214 		UNI_RANGE(10)
215 	}
216 };
217 
218 enum trimpot_model {
219 	AD7376,
220 	AD8402,
221 };
222 
223 enum cb_pcidas_boardid {
224 	BOARD_PCIDAS1602_16,
225 	BOARD_PCIDAS1200,
226 	BOARD_PCIDAS1602_12,
227 	BOARD_PCIDAS1200_JR,
228 	BOARD_PCIDAS1602_16_JR,
229 	BOARD_PCIDAS1000,
230 	BOARD_PCIDAS1001,
231 	BOARD_PCIDAS1002,
232 };
233 
234 struct cb_pcidas_board {
235 	const char *name;
236 	int ai_nchan;		/*  Inputs in single-ended mode */
237 	int ai_bits;		/*  analog input resolution */
238 	int ai_speed;		/*  fastest conversion period in ns */
239 	int ao_nchan;		/*  number of analog out channels */
240 	int has_ao_fifo;	/*  analog output has fifo */
241 	int ao_scan_speed;	/*  analog output scan speed for 1602 series */
242 	int fifo_size;		/*  number of samples fifo can hold */
243 	const struct comedi_lrange *ranges;
244 	enum trimpot_model trimpot;
245 	unsigned has_dac08:1;
246 	unsigned is_1602:1;
247 };
248 
249 static const struct cb_pcidas_board cb_pcidas_boards[] = {
250 	[BOARD_PCIDAS1602_16] = {
251 		.name		= "pci-das1602/16",
252 		.ai_nchan	= 16,
253 		.ai_bits	= 16,
254 		.ai_speed	= 5000,
255 		.ao_nchan	= 2,
256 		.has_ao_fifo	= 1,
257 		.ao_scan_speed	= 10000,
258 		.fifo_size	= 512,
259 		.ranges		= &cb_pcidas_ranges,
260 		.trimpot	= AD8402,
261 		.has_dac08	= 1,
262 		.is_1602	= 1,
263 	},
264 	[BOARD_PCIDAS1200] = {
265 		.name		= "pci-das1200",
266 		.ai_nchan	= 16,
267 		.ai_bits	= 12,
268 		.ai_speed	= 3200,
269 		.ao_nchan	= 2,
270 		.fifo_size	= 1024,
271 		.ranges		= &cb_pcidas_ranges,
272 		.trimpot	= AD7376,
273 	},
274 	[BOARD_PCIDAS1602_12] = {
275 		.name		= "pci-das1602/12",
276 		.ai_nchan	= 16,
277 		.ai_bits	= 12,
278 		.ai_speed	= 3200,
279 		.ao_nchan	= 2,
280 		.has_ao_fifo	= 1,
281 		.ao_scan_speed	= 4000,
282 		.fifo_size	= 1024,
283 		.ranges		= &cb_pcidas_ranges,
284 		.trimpot	= AD7376,
285 		.is_1602	= 1,
286 	},
287 	[BOARD_PCIDAS1200_JR] = {
288 		.name		= "pci-das1200/jr",
289 		.ai_nchan	= 16,
290 		.ai_bits	= 12,
291 		.ai_speed	= 3200,
292 		.fifo_size	= 1024,
293 		.ranges		= &cb_pcidas_ranges,
294 		.trimpot	= AD7376,
295 	},
296 	[BOARD_PCIDAS1602_16_JR] = {
297 		.name		= "pci-das1602/16/jr",
298 		.ai_nchan	= 16,
299 		.ai_bits	= 16,
300 		.ai_speed	= 5000,
301 		.fifo_size	= 512,
302 		.ranges		= &cb_pcidas_ranges,
303 		.trimpot	= AD8402,
304 		.has_dac08	= 1,
305 		.is_1602	= 1,
306 	},
307 	[BOARD_PCIDAS1000] = {
308 		.name		= "pci-das1000",
309 		.ai_nchan	= 16,
310 		.ai_bits	= 12,
311 		.ai_speed	= 4000,
312 		.fifo_size	= 1024,
313 		.ranges		= &cb_pcidas_ranges,
314 		.trimpot	= AD7376,
315 	},
316 	[BOARD_PCIDAS1001] = {
317 		.name		= "pci-das1001",
318 		.ai_nchan	= 16,
319 		.ai_bits	= 12,
320 		.ai_speed	= 6800,
321 		.ao_nchan	= 2,
322 		.fifo_size	= 1024,
323 		.ranges		= &cb_pcidas_alt_ranges,
324 		.trimpot	= AD7376,
325 	},
326 	[BOARD_PCIDAS1002] = {
327 		.name		= "pci-das1002",
328 		.ai_nchan	= 16,
329 		.ai_bits	= 12,
330 		.ai_speed	= 6800,
331 		.ao_nchan	= 2,
332 		.fifo_size	= 1024,
333 		.ranges		= &cb_pcidas_ranges,
334 		.trimpot	= AD7376,
335 	},
336 };
337 
338 struct cb_pcidas_private {
339 	struct comedi_8254 *ao_pacer;
340 	/* base addresses */
341 	unsigned long s5933_config;
342 	unsigned long control_status;
343 	unsigned long adc_fifo;
344 	unsigned long ao_registers;
345 	/* bits to write to registers */
346 	unsigned int adc_fifo_bits;
347 	unsigned int s5933_intcsr_bits;
348 	unsigned int ao_control_bits;
349 	/* fifo buffers */
350 	unsigned short ai_buffer[AI_BUFFER_SIZE];
351 	unsigned short ao_buffer[AO_BUFFER_SIZE];
352 	unsigned int calibration_source;
353 };
354 
cal_enable_bits(struct comedi_device * dev)355 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
356 {
357 	struct cb_pcidas_private *devpriv = dev->private;
358 
359 	return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
360 }
361 
cb_pcidas_ai_eoc(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned long context)362 static int cb_pcidas_ai_eoc(struct comedi_device *dev,
363 			    struct comedi_subdevice *s,
364 			    struct comedi_insn *insn,
365 			    unsigned long context)
366 {
367 	struct cb_pcidas_private *devpriv = dev->private;
368 	unsigned int status;
369 
370 	status = inw(devpriv->control_status + ADCMUX_CONT);
371 	if (status & EOC)
372 		return 0;
373 	return -EBUSY;
374 }
375 
cb_pcidas_ai_rinsn(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)376 static int cb_pcidas_ai_rinsn(struct comedi_device *dev,
377 			      struct comedi_subdevice *s,
378 			      struct comedi_insn *insn, unsigned int *data)
379 {
380 	struct cb_pcidas_private *devpriv = dev->private;
381 	unsigned int chan = CR_CHAN(insn->chanspec);
382 	unsigned int range = CR_RANGE(insn->chanspec);
383 	unsigned int aref = CR_AREF(insn->chanspec);
384 	unsigned int bits;
385 	int ret;
386 	int n;
387 
388 	/* enable calibration input if appropriate */
389 	if (insn->chanspec & CR_ALT_SOURCE) {
390 		outw(cal_enable_bits(dev),
391 		     devpriv->control_status + CALIBRATION_REG);
392 		chan = 0;
393 	} else {
394 		outw(0, devpriv->control_status + CALIBRATION_REG);
395 	}
396 
397 	/* set mux limits and gain */
398 	bits = BEGIN_SCAN(chan) | END_SCAN(chan) | GAIN_BITS(range);
399 	/* set unipolar/bipolar */
400 	if (range & IS_UNIPOLAR)
401 		bits |= UNIP;
402 	/* set single-ended/differential */
403 	if (aref != AREF_DIFF)
404 		bits |= SE;
405 	outw(bits, devpriv->control_status + ADCMUX_CONT);
406 
407 	/* clear fifo */
408 	outw(0, devpriv->adc_fifo + ADCFIFOCLR);
409 
410 	/* convert n samples */
411 	for (n = 0; n < insn->n; n++) {
412 		/* trigger conversion */
413 		outw(0, devpriv->adc_fifo + ADCDATA);
414 
415 		/* wait for conversion to end */
416 		ret = comedi_timeout(dev, s, insn, cb_pcidas_ai_eoc, 0);
417 		if (ret)
418 			return ret;
419 
420 		/* read data */
421 		data[n] = inw(devpriv->adc_fifo + ADCDATA);
422 	}
423 
424 	/* return the number of samples read/written */
425 	return n;
426 }
427 
ai_config_insn(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)428 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
429 			  struct comedi_insn *insn, unsigned int *data)
430 {
431 	struct cb_pcidas_private *devpriv = dev->private;
432 	int id = data[0];
433 	unsigned int source = data[1];
434 
435 	switch (id) {
436 	case INSN_CONFIG_ALT_SOURCE:
437 		if (source >= 8) {
438 			dev_err(dev->class_dev,
439 				"invalid calibration source: %i\n",
440 				source);
441 			return -EINVAL;
442 		}
443 		devpriv->calibration_source = source;
444 		break;
445 	default:
446 		return -EINVAL;
447 	}
448 	return insn->n;
449 }
450 
451 /* analog output insn for pcidas-1000 and 1200 series */
cb_pcidas_ao_nofifo_winsn(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)452 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
453 				     struct comedi_subdevice *s,
454 				     struct comedi_insn *insn,
455 				     unsigned int *data)
456 {
457 	struct cb_pcidas_private *devpriv = dev->private;
458 	unsigned int chan = CR_CHAN(insn->chanspec);
459 	unsigned int range = CR_RANGE(insn->chanspec);
460 	unsigned long flags;
461 
462 	/* set channel and range */
463 	spin_lock_irqsave(&dev->spinlock, flags);
464 	devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH &
465 				     ~DAC_RANGE_MASK(chan));
466 	devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range));
467 	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
468 	spin_unlock_irqrestore(&dev->spinlock, flags);
469 
470 	/* remember value for readback */
471 	s->readback[chan] = data[0];
472 
473 	/* send data */
474 	outw(data[0], devpriv->ao_registers + DAC_DATA_REG(chan));
475 
476 	return insn->n;
477 }
478 
479 /* analog output insn for pcidas-1602 series */
cb_pcidas_ao_fifo_winsn(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)480 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
481 				   struct comedi_subdevice *s,
482 				   struct comedi_insn *insn, unsigned int *data)
483 {
484 	struct cb_pcidas_private *devpriv = dev->private;
485 	unsigned int chan = CR_CHAN(insn->chanspec);
486 	unsigned int range = CR_RANGE(insn->chanspec);
487 	unsigned long flags;
488 
489 	/* clear dac fifo */
490 	outw(0, devpriv->ao_registers + DACFIFOCLR);
491 
492 	/* set channel and range */
493 	spin_lock_irqsave(&dev->spinlock, flags);
494 	devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
495 				     ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK);
496 	devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) |
497 				     DAC_CHAN_EN(chan) | DAC_START);
498 	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
499 	spin_unlock_irqrestore(&dev->spinlock, flags);
500 
501 	/* remember value for readback */
502 	s->readback[chan] = data[0];
503 
504 	/* send data */
505 	outw(data[0], devpriv->ao_registers + DACDATA);
506 
507 	return insn->n;
508 }
509 
wait_for_nvram_ready(unsigned long s5933_base_addr)510 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
511 {
512 	static const int timeout = 1000;
513 	unsigned int i;
514 
515 	for (i = 0; i < timeout; i++) {
516 		if ((inb(s5933_base_addr +
517 			 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
518 		    == 0)
519 			return 0;
520 		udelay(1);
521 	}
522 	return -1;
523 }
524 
nvram_read(struct comedi_device * dev,unsigned int address,uint8_t * data)525 static int nvram_read(struct comedi_device *dev, unsigned int address,
526 		      uint8_t *data)
527 {
528 	struct cb_pcidas_private *devpriv = dev->private;
529 	unsigned long iobase = devpriv->s5933_config;
530 
531 	if (wait_for_nvram_ready(iobase) < 0)
532 		return -ETIMEDOUT;
533 
534 	outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
535 	     iobase + AMCC_OP_REG_MCSR_NVCMD);
536 	outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
537 	outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
538 	     iobase + AMCC_OP_REG_MCSR_NVCMD);
539 	outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
540 	outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
541 
542 	if (wait_for_nvram_ready(iobase) < 0)
543 		return -ETIMEDOUT;
544 
545 	*data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
546 
547 	return 0;
548 }
549 
eeprom_read_insn(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)550 static int eeprom_read_insn(struct comedi_device *dev,
551 			    struct comedi_subdevice *s,
552 			    struct comedi_insn *insn, unsigned int *data)
553 {
554 	uint8_t nvram_data;
555 	int retval;
556 
557 	retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
558 	if (retval < 0)
559 		return retval;
560 
561 	data[0] = nvram_data;
562 
563 	return 1;
564 }
565 
write_calibration_bitstream(struct comedi_device * dev,unsigned int register_bits,unsigned int bitstream,unsigned int bitstream_length)566 static void write_calibration_bitstream(struct comedi_device *dev,
567 					unsigned int register_bits,
568 					unsigned int bitstream,
569 					unsigned int bitstream_length)
570 {
571 	struct cb_pcidas_private *devpriv = dev->private;
572 	static const int write_delay = 1;
573 	unsigned int bit;
574 
575 	for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
576 		if (bitstream & bit)
577 			register_bits |= SERIAL_DATA_IN_BIT;
578 		else
579 			register_bits &= ~SERIAL_DATA_IN_BIT;
580 		udelay(write_delay);
581 		outw(register_bits, devpriv->control_status + CALIBRATION_REG);
582 	}
583 }
584 
caldac_8800_write(struct comedi_device * dev,unsigned int chan,uint8_t val)585 static void caldac_8800_write(struct comedi_device *dev,
586 			      unsigned int chan, uint8_t val)
587 {
588 	struct cb_pcidas_private *devpriv = dev->private;
589 	static const int bitstream_length = 11;
590 	unsigned int bitstream = ((chan & 0x7) << 8) | val;
591 	static const int caldac_8800_udelay = 1;
592 
593 	write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
594 				    bitstream_length);
595 
596 	udelay(caldac_8800_udelay);
597 	outw(cal_enable_bits(dev) | SELECT_8800_BIT,
598 	     devpriv->control_status + CALIBRATION_REG);
599 	udelay(caldac_8800_udelay);
600 	outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
601 }
602 
cb_pcidas_caldac_insn_write(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)603 static int cb_pcidas_caldac_insn_write(struct comedi_device *dev,
604 				       struct comedi_subdevice *s,
605 				       struct comedi_insn *insn,
606 				       unsigned int *data)
607 {
608 	unsigned int chan = CR_CHAN(insn->chanspec);
609 
610 	if (insn->n) {
611 		unsigned int val = data[insn->n - 1];
612 
613 		if (s->readback[chan] != val) {
614 			caldac_8800_write(dev, chan, val);
615 			s->readback[chan] = val;
616 		}
617 	}
618 
619 	return insn->n;
620 }
621 
622 /* 1602/16 pregain offset */
dac08_write(struct comedi_device * dev,unsigned int value)623 static void dac08_write(struct comedi_device *dev, unsigned int value)
624 {
625 	struct cb_pcidas_private *devpriv = dev->private;
626 
627 	value &= 0xff;
628 	value |= cal_enable_bits(dev);
629 
630 	/* latch the new value into the caldac */
631 	outw(value, devpriv->control_status + CALIBRATION_REG);
632 	udelay(1);
633 	outw(value | SELECT_DAC08_BIT,
634 	     devpriv->control_status + CALIBRATION_REG);
635 	udelay(1);
636 	outw(value, devpriv->control_status + CALIBRATION_REG);
637 	udelay(1);
638 }
639 
cb_pcidas_dac08_insn_write(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)640 static int cb_pcidas_dac08_insn_write(struct comedi_device *dev,
641 				      struct comedi_subdevice *s,
642 				      struct comedi_insn *insn,
643 				      unsigned int *data)
644 {
645 	unsigned int chan = CR_CHAN(insn->chanspec);
646 
647 	if (insn->n) {
648 		unsigned int val = data[insn->n - 1];
649 
650 		if (s->readback[chan] != val) {
651 			dac08_write(dev, val);
652 			s->readback[chan] = val;
653 		}
654 	}
655 
656 	return insn->n;
657 }
658 
trimpot_7376_write(struct comedi_device * dev,uint8_t value)659 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
660 {
661 	struct cb_pcidas_private *devpriv = dev->private;
662 	static const int bitstream_length = 7;
663 	unsigned int bitstream = value & 0x7f;
664 	unsigned int register_bits;
665 	static const int ad7376_udelay = 1;
666 
667 	register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
668 	udelay(ad7376_udelay);
669 	outw(register_bits, devpriv->control_status + CALIBRATION_REG);
670 
671 	write_calibration_bitstream(dev, register_bits, bitstream,
672 				    bitstream_length);
673 
674 	udelay(ad7376_udelay);
675 	outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
676 
677 	return 0;
678 }
679 
680 /* For 1602/16 only
681  * ch 0 : adc gain
682  * ch 1 : adc postgain offset */
trimpot_8402_write(struct comedi_device * dev,unsigned int channel,uint8_t value)683 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
684 			      uint8_t value)
685 {
686 	struct cb_pcidas_private *devpriv = dev->private;
687 	static const int bitstream_length = 10;
688 	unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
689 	unsigned int register_bits;
690 	static const int ad8402_udelay = 1;
691 
692 	register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
693 	udelay(ad8402_udelay);
694 	outw(register_bits, devpriv->control_status + CALIBRATION_REG);
695 
696 	write_calibration_bitstream(dev, register_bits, bitstream,
697 				    bitstream_length);
698 
699 	udelay(ad8402_udelay);
700 	outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
701 
702 	return 0;
703 }
704 
cb_pcidas_trimpot_write(struct comedi_device * dev,unsigned int chan,unsigned int val)705 static void cb_pcidas_trimpot_write(struct comedi_device *dev,
706 				    unsigned int chan, unsigned int val)
707 {
708 	const struct cb_pcidas_board *thisboard = dev->board_ptr;
709 
710 	switch (thisboard->trimpot) {
711 	case AD7376:
712 		trimpot_7376_write(dev, val);
713 		break;
714 	case AD8402:
715 		trimpot_8402_write(dev, chan, val);
716 		break;
717 	default:
718 		dev_err(dev->class_dev, "driver bug?\n");
719 		break;
720 	}
721 }
722 
cb_pcidas_trimpot_insn_write(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)723 static int cb_pcidas_trimpot_insn_write(struct comedi_device *dev,
724 					struct comedi_subdevice *s,
725 					struct comedi_insn *insn,
726 					unsigned int *data)
727 {
728 	unsigned int chan = CR_CHAN(insn->chanspec);
729 
730 	if (insn->n) {
731 		unsigned int val = data[insn->n - 1];
732 
733 		if (s->readback[chan] != val) {
734 			cb_pcidas_trimpot_write(dev, chan, val);
735 			s->readback[chan] = val;
736 		}
737 	}
738 
739 	return insn->n;
740 }
741 
cb_pcidas_ai_check_chanlist(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)742 static int cb_pcidas_ai_check_chanlist(struct comedi_device *dev,
743 				       struct comedi_subdevice *s,
744 				       struct comedi_cmd *cmd)
745 {
746 	unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
747 	unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
748 	int i;
749 
750 	for (i = 1; i < cmd->chanlist_len; i++) {
751 		unsigned int chan = CR_CHAN(cmd->chanlist[i]);
752 		unsigned int range = CR_RANGE(cmd->chanlist[i]);
753 
754 		if (chan != (chan0 + i) % s->n_chan) {
755 			dev_dbg(dev->class_dev,
756 				"entries in chanlist must be consecutive channels, counting upwards\n");
757 			return -EINVAL;
758 		}
759 
760 		if (range != range0) {
761 			dev_dbg(dev->class_dev,
762 				"entries in chanlist must all have the same gain\n");
763 			return -EINVAL;
764 		}
765 	}
766 	return 0;
767 }
768 
cb_pcidas_ai_cmdtest(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)769 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
770 				struct comedi_subdevice *s,
771 				struct comedi_cmd *cmd)
772 {
773 	const struct cb_pcidas_board *thisboard = dev->board_ptr;
774 	int err = 0;
775 	unsigned int arg;
776 
777 	/* Step 1 : check if triggers are trivially valid */
778 
779 	err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
780 	err |= comedi_check_trigger_src(&cmd->scan_begin_src,
781 					TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
782 	err |= comedi_check_trigger_src(&cmd->convert_src,
783 					TRIG_TIMER | TRIG_NOW | TRIG_EXT);
784 	err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
785 	err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
786 
787 	if (err)
788 		return 1;
789 
790 	/* Step 2a : make sure trigger sources are unique */
791 
792 	err |= comedi_check_trigger_is_unique(cmd->start_src);
793 	err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
794 	err |= comedi_check_trigger_is_unique(cmd->convert_src);
795 	err |= comedi_check_trigger_is_unique(cmd->stop_src);
796 
797 	/* Step 2b : and mutually compatible */
798 
799 	if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
800 		err |= -EINVAL;
801 	if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
802 		err |= -EINVAL;
803 	if (cmd->start_src == TRIG_EXT &&
804 	    (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
805 		err |= -EINVAL;
806 
807 	if (err)
808 		return 2;
809 
810 	/* Step 3: check if arguments are trivially valid */
811 
812 	switch (cmd->start_src) {
813 	case TRIG_NOW:
814 		err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
815 		break;
816 	case TRIG_EXT:
817 		/* External trigger, only CR_EDGE and CR_INVERT flags allowed */
818 		if ((cmd->start_arg
819 		     & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
820 			cmd->start_arg &= ~(CR_FLAGS_MASK &
821 						~(CR_EDGE | CR_INVERT));
822 			err |= -EINVAL;
823 		}
824 		if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
825 			cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
826 			err |= -EINVAL;
827 		}
828 		break;
829 	}
830 
831 	if (cmd->scan_begin_src == TRIG_TIMER) {
832 		err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
833 						    thisboard->ai_speed *
834 						    cmd->chanlist_len);
835 	}
836 
837 	if (cmd->convert_src == TRIG_TIMER) {
838 		err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
839 						    thisboard->ai_speed);
840 	}
841 
842 	err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
843 					   cmd->chanlist_len);
844 
845 	if (cmd->stop_src == TRIG_COUNT)
846 		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
847 	else	/* TRIG_NONE */
848 		err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
849 
850 	if (err)
851 		return 3;
852 
853 	/* step 4: fix up any arguments */
854 
855 	if (cmd->scan_begin_src == TRIG_TIMER) {
856 		arg = cmd->scan_begin_arg;
857 		comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
858 		err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
859 	}
860 	if (cmd->convert_src == TRIG_TIMER) {
861 		arg = cmd->convert_arg;
862 		comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
863 		err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
864 	}
865 
866 	if (err)
867 		return 4;
868 
869 	/* Step 5: check channel list if it exists */
870 	if (cmd->chanlist && cmd->chanlist_len > 0)
871 		err |= cb_pcidas_ai_check_chanlist(dev, s, cmd);
872 
873 	if (err)
874 		return 5;
875 
876 	return 0;
877 }
878 
cb_pcidas_ai_cmd(struct comedi_device * dev,struct comedi_subdevice * s)879 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
880 			    struct comedi_subdevice *s)
881 {
882 	const struct cb_pcidas_board *thisboard = dev->board_ptr;
883 	struct cb_pcidas_private *devpriv = dev->private;
884 	struct comedi_async *async = s->async;
885 	struct comedi_cmd *cmd = &async->cmd;
886 	unsigned int bits;
887 	unsigned long flags;
888 
889 	/*  make sure CAL_EN_BIT is disabled */
890 	outw(0, devpriv->control_status + CALIBRATION_REG);
891 	/*  initialize before settings pacer source and count values */
892 	outw(0, devpriv->control_status + TRIG_CONTSTAT);
893 	/*  clear fifo */
894 	outw(0, devpriv->adc_fifo + ADCFIFOCLR);
895 
896 	/*  set mux limits, gain and pacer source */
897 	bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
898 	    END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
899 	    GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
900 	/*  set unipolar/bipolar */
901 	if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
902 		bits |= UNIP;
903 	/*  set singleended/differential */
904 	if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
905 		bits |= SE;
906 	/*  set pacer source */
907 	if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
908 		bits |= PACER_EXT_RISE;
909 	else
910 		bits |= PACER_INT;
911 	outw(bits, devpriv->control_status + ADCMUX_CONT);
912 
913 	/*  load counters */
914 	if (cmd->scan_begin_src == TRIG_TIMER ||
915 	    cmd->convert_src == TRIG_TIMER) {
916 		comedi_8254_update_divisors(dev->pacer);
917 		comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
918 	}
919 
920 	/*  enable interrupts */
921 	spin_lock_irqsave(&dev->spinlock, flags);
922 	devpriv->adc_fifo_bits |= INTE;
923 	devpriv->adc_fifo_bits &= ~INT_MASK;
924 	if (cmd->flags & CMDF_WAKE_EOS) {
925 		if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
926 			/* interrupt end of burst */
927 			devpriv->adc_fifo_bits |= INT_EOS;
928 		} else {
929 			/* interrupt fifo not empty */
930 			devpriv->adc_fifo_bits |= INT_FNE;
931 		}
932 	} else {
933 		/* interrupt fifo half full */
934 		devpriv->adc_fifo_bits |= INT_FHF;
935 	}
936 
937 	/*  enable (and clear) interrupts */
938 	outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
939 	     devpriv->control_status + INT_ADCFIFO);
940 	spin_unlock_irqrestore(&dev->spinlock, flags);
941 
942 	/*  set start trigger and burst mode */
943 	bits = 0;
944 	if (cmd->start_src == TRIG_NOW) {
945 		bits |= SW_TRIGGER;
946 	} else {	/* TRIG_EXT */
947 		bits |= EXT_TRIGGER | TGEN | XTRCL;
948 		if (thisboard->is_1602) {
949 			if (cmd->start_arg & CR_INVERT)
950 				bits |= TGPOL;
951 			if (cmd->start_arg & CR_EDGE)
952 				bits |= TGSEL;
953 		}
954 	}
955 	if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
956 		bits |= BURSTE;
957 	outw(bits, devpriv->control_status + TRIG_CONTSTAT);
958 
959 	return 0;
960 }
961 
cb_pcidas_ao_check_chanlist(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)962 static int cb_pcidas_ao_check_chanlist(struct comedi_device *dev,
963 				       struct comedi_subdevice *s,
964 				       struct comedi_cmd *cmd)
965 {
966 	unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
967 
968 	if (cmd->chanlist_len > 1) {
969 		unsigned int chan1 = CR_CHAN(cmd->chanlist[1]);
970 
971 		if (chan0 != 0 || chan1 != 1) {
972 			dev_dbg(dev->class_dev,
973 				"channels must be ordered channel 0, channel 1 in chanlist\n");
974 			return -EINVAL;
975 		}
976 	}
977 
978 	return 0;
979 }
980 
cb_pcidas_ao_cmdtest(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)981 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
982 				struct comedi_subdevice *s,
983 				struct comedi_cmd *cmd)
984 {
985 	const struct cb_pcidas_board *thisboard = dev->board_ptr;
986 	struct cb_pcidas_private *devpriv = dev->private;
987 	int err = 0;
988 
989 	/* Step 1 : check if triggers are trivially valid */
990 
991 	err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
992 	err |= comedi_check_trigger_src(&cmd->scan_begin_src,
993 					TRIG_TIMER | TRIG_EXT);
994 	err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
995 	err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
996 	err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
997 
998 	if (err)
999 		return 1;
1000 
1001 	/* Step 2a : make sure trigger sources are unique */
1002 
1003 	err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
1004 	err |= comedi_check_trigger_is_unique(cmd->stop_src);
1005 
1006 	/* Step 2b : and mutually compatible */
1007 
1008 	if (err)
1009 		return 2;
1010 
1011 	/* Step 3: check if arguments are trivially valid */
1012 
1013 	err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
1014 
1015 	if (cmd->scan_begin_src == TRIG_TIMER) {
1016 		err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
1017 						    thisboard->ao_scan_speed);
1018 	}
1019 
1020 	err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
1021 					   cmd->chanlist_len);
1022 
1023 	if (cmd->stop_src == TRIG_COUNT)
1024 		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
1025 	else	/* TRIG_NONE */
1026 		err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
1027 
1028 	if (err)
1029 		return 3;
1030 
1031 	/* step 4: fix up any arguments */
1032 
1033 	if (cmd->scan_begin_src == TRIG_TIMER) {
1034 		unsigned int arg = cmd->scan_begin_arg;
1035 
1036 		comedi_8254_cascade_ns_to_timer(devpriv->ao_pacer,
1037 						&arg, cmd->flags);
1038 		err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
1039 	}
1040 
1041 	if (err)
1042 		return 4;
1043 
1044 	/* Step 5: check channel list if it exists */
1045 	if (cmd->chanlist && cmd->chanlist_len > 0)
1046 		err |= cb_pcidas_ao_check_chanlist(dev, s, cmd);
1047 
1048 	if (err)
1049 		return 5;
1050 
1051 	return 0;
1052 }
1053 
1054 /* cancel analog input command */
cb_pcidas_cancel(struct comedi_device * dev,struct comedi_subdevice * s)1055 static int cb_pcidas_cancel(struct comedi_device *dev,
1056 			    struct comedi_subdevice *s)
1057 {
1058 	struct cb_pcidas_private *devpriv = dev->private;
1059 	unsigned long flags;
1060 
1061 	spin_lock_irqsave(&dev->spinlock, flags);
1062 	/*  disable interrupts */
1063 	devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1064 	outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1065 	spin_unlock_irqrestore(&dev->spinlock, flags);
1066 
1067 	/*  disable start trigger source and burst mode */
1068 	outw(0, devpriv->control_status + TRIG_CONTSTAT);
1069 	/*  software pacer source */
1070 	outw(0, devpriv->control_status + ADCMUX_CONT);
1071 
1072 	return 0;
1073 }
1074 
cb_pcidas_ao_load_fifo(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int nsamples)1075 static void cb_pcidas_ao_load_fifo(struct comedi_device *dev,
1076 				   struct comedi_subdevice *s,
1077 				   unsigned int nsamples)
1078 {
1079 	struct cb_pcidas_private *devpriv = dev->private;
1080 	unsigned int nbytes;
1081 
1082 	nsamples = comedi_nsamples_left(s, nsamples);
1083 	nbytes = comedi_buf_read_samples(s, devpriv->ao_buffer, nsamples);
1084 
1085 	nsamples = comedi_bytes_to_samples(s, nbytes);
1086 	outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, nsamples);
1087 }
1088 
cb_pcidas_ao_inttrig(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int trig_num)1089 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1090 				struct comedi_subdevice *s,
1091 				unsigned int trig_num)
1092 {
1093 	const struct cb_pcidas_board *thisboard = dev->board_ptr;
1094 	struct cb_pcidas_private *devpriv = dev->private;
1095 	struct comedi_async *async = s->async;
1096 	struct comedi_cmd *cmd = &async->cmd;
1097 	unsigned long flags;
1098 
1099 	if (trig_num != cmd->start_arg)
1100 		return -EINVAL;
1101 
1102 	cb_pcidas_ao_load_fifo(dev, s, thisboard->fifo_size);
1103 
1104 	/*  enable dac half-full and empty interrupts */
1105 	spin_lock_irqsave(&dev->spinlock, flags);
1106 	devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1107 
1108 	/*  enable and clear interrupts */
1109 	outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1110 	     devpriv->control_status + INT_ADCFIFO);
1111 
1112 	/*  start dac */
1113 	devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1114 	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1115 
1116 	spin_unlock_irqrestore(&dev->spinlock, flags);
1117 
1118 	async->inttrig = NULL;
1119 
1120 	return 0;
1121 }
1122 
cb_pcidas_ao_cmd(struct comedi_device * dev,struct comedi_subdevice * s)1123 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1124 			    struct comedi_subdevice *s)
1125 {
1126 	struct cb_pcidas_private *devpriv = dev->private;
1127 	struct comedi_async *async = s->async;
1128 	struct comedi_cmd *cmd = &async->cmd;
1129 	unsigned int i;
1130 	unsigned long flags;
1131 
1132 	/*  set channel limits, gain */
1133 	spin_lock_irqsave(&dev->spinlock, flags);
1134 	for (i = 0; i < cmd->chanlist_len; i++) {
1135 		/*  enable channel */
1136 		devpriv->ao_control_bits |=
1137 		    DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1138 		/*  set range */
1139 		devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1140 						      CR_RANGE(cmd->
1141 							       chanlist[i]));
1142 	}
1143 
1144 	/*  disable analog out before settings pacer source and count values */
1145 	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1146 	spin_unlock_irqrestore(&dev->spinlock, flags);
1147 
1148 	/*  clear fifo */
1149 	outw(0, devpriv->ao_registers + DACFIFOCLR);
1150 
1151 	/*  load counters */
1152 	if (cmd->scan_begin_src == TRIG_TIMER) {
1153 		comedi_8254_update_divisors(devpriv->ao_pacer);
1154 		comedi_8254_pacer_enable(devpriv->ao_pacer, 1, 2, true);
1155 	}
1156 
1157 	/*  set pacer source */
1158 	spin_lock_irqsave(&dev->spinlock, flags);
1159 	switch (cmd->scan_begin_src) {
1160 	case TRIG_TIMER:
1161 		devpriv->ao_control_bits |= DAC_PACER_INT;
1162 		break;
1163 	case TRIG_EXT:
1164 		devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1165 		break;
1166 	default:
1167 		spin_unlock_irqrestore(&dev->spinlock, flags);
1168 		dev_err(dev->class_dev, "error setting dac pacer source\n");
1169 		return -1;
1170 	}
1171 	spin_unlock_irqrestore(&dev->spinlock, flags);
1172 
1173 	async->inttrig = cb_pcidas_ao_inttrig;
1174 
1175 	return 0;
1176 }
1177 
1178 /* cancel analog output command */
cb_pcidas_ao_cancel(struct comedi_device * dev,struct comedi_subdevice * s)1179 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1180 			       struct comedi_subdevice *s)
1181 {
1182 	struct cb_pcidas_private *devpriv = dev->private;
1183 	unsigned long flags;
1184 
1185 	spin_lock_irqsave(&dev->spinlock, flags);
1186 	/*  disable interrupts */
1187 	devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1188 	outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1189 
1190 	/*  disable output */
1191 	devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1192 	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1193 	spin_unlock_irqrestore(&dev->spinlock, flags);
1194 
1195 	return 0;
1196 }
1197 
handle_ao_interrupt(struct comedi_device * dev,unsigned int status)1198 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1199 {
1200 	const struct cb_pcidas_board *thisboard = dev->board_ptr;
1201 	struct cb_pcidas_private *devpriv = dev->private;
1202 	struct comedi_subdevice *s = dev->write_subdev;
1203 	struct comedi_async *async = s->async;
1204 	struct comedi_cmd *cmd = &async->cmd;
1205 	unsigned long flags;
1206 
1207 	if (status & DAEMI) {
1208 		/*  clear dac empty interrupt latch */
1209 		spin_lock_irqsave(&dev->spinlock, flags);
1210 		outw(devpriv->adc_fifo_bits | DAEMI,
1211 		     devpriv->control_status + INT_ADCFIFO);
1212 		spin_unlock_irqrestore(&dev->spinlock, flags);
1213 		if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1214 			if (cmd->stop_src == TRIG_COUNT &&
1215 			    async->scans_done >= cmd->stop_arg) {
1216 				async->events |= COMEDI_CB_EOA;
1217 			} else {
1218 				dev_err(dev->class_dev, "dac fifo underflow\n");
1219 				async->events |= COMEDI_CB_ERROR;
1220 			}
1221 		}
1222 	} else if (status & DAHFI) {
1223 		cb_pcidas_ao_load_fifo(dev, s, thisboard->fifo_size / 2);
1224 
1225 		/*  clear half-full interrupt latch */
1226 		spin_lock_irqsave(&dev->spinlock, flags);
1227 		outw(devpriv->adc_fifo_bits | DAHFI,
1228 		     devpriv->control_status + INT_ADCFIFO);
1229 		spin_unlock_irqrestore(&dev->spinlock, flags);
1230 	}
1231 
1232 	comedi_handle_events(dev, s);
1233 }
1234 
cb_pcidas_interrupt(int irq,void * d)1235 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1236 {
1237 	struct comedi_device *dev = (struct comedi_device *)d;
1238 	const struct cb_pcidas_board *thisboard = dev->board_ptr;
1239 	struct cb_pcidas_private *devpriv = dev->private;
1240 	struct comedi_subdevice *s = dev->read_subdev;
1241 	struct comedi_async *async;
1242 	struct comedi_cmd *cmd;
1243 	int status, s5933_status;
1244 	int half_fifo = thisboard->fifo_size / 2;
1245 	unsigned int num_samples, i;
1246 	static const int timeout = 10000;
1247 	unsigned long flags;
1248 
1249 	if (!dev->attached)
1250 		return IRQ_NONE;
1251 
1252 	async = s->async;
1253 	cmd = &async->cmd;
1254 
1255 	s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1256 
1257 	if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1258 		return IRQ_NONE;
1259 
1260 	/*  make sure mailbox 4 is empty */
1261 	inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1262 	/*  clear interrupt on amcc s5933 */
1263 	outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1264 	     devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1265 
1266 	status = inw(devpriv->control_status + INT_ADCFIFO);
1267 
1268 	/*  check for analog output interrupt */
1269 	if (status & (DAHFI | DAEMI))
1270 		handle_ao_interrupt(dev, status);
1271 	/*  check for analog input interrupts */
1272 	/*  if fifo half-full */
1273 	if (status & ADHFI) {
1274 		/*  read data */
1275 		num_samples = comedi_nsamples_left(s, half_fifo);
1276 		insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1277 		     num_samples);
1278 		comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples);
1279 
1280 		if (cmd->stop_src == TRIG_COUNT &&
1281 		    async->scans_done >= cmd->stop_arg)
1282 			async->events |= COMEDI_CB_EOA;
1283 
1284 		/*  clear half-full interrupt latch */
1285 		spin_lock_irqsave(&dev->spinlock, flags);
1286 		outw(devpriv->adc_fifo_bits | INT,
1287 		     devpriv->control_status + INT_ADCFIFO);
1288 		spin_unlock_irqrestore(&dev->spinlock, flags);
1289 		/*  else if fifo not empty */
1290 	} else if (status & (ADNEI | EOBI)) {
1291 		for (i = 0; i < timeout; i++) {
1292 			unsigned short val;
1293 
1294 			/*  break if fifo is empty */
1295 			if ((ADNE & inw(devpriv->control_status +
1296 					INT_ADCFIFO)) == 0)
1297 				break;
1298 			val = inw(devpriv->adc_fifo);
1299 			comedi_buf_write_samples(s, &val, 1);
1300 
1301 			if (cmd->stop_src == TRIG_COUNT &&
1302 			    async->scans_done >= cmd->stop_arg) {
1303 				async->events |= COMEDI_CB_EOA;
1304 				break;
1305 			}
1306 		}
1307 		/*  clear not-empty interrupt latch */
1308 		spin_lock_irqsave(&dev->spinlock, flags);
1309 		outw(devpriv->adc_fifo_bits | INT,
1310 		     devpriv->control_status + INT_ADCFIFO);
1311 		spin_unlock_irqrestore(&dev->spinlock, flags);
1312 	} else if (status & EOAI) {
1313 		dev_err(dev->class_dev,
1314 			"bug! encountered end of acquisition interrupt?\n");
1315 		/*  clear EOA interrupt latch */
1316 		spin_lock_irqsave(&dev->spinlock, flags);
1317 		outw(devpriv->adc_fifo_bits | EOAI,
1318 		     devpriv->control_status + INT_ADCFIFO);
1319 		spin_unlock_irqrestore(&dev->spinlock, flags);
1320 	}
1321 	/* check for fifo overflow */
1322 	if (status & LADFUL) {
1323 		dev_err(dev->class_dev, "fifo overflow\n");
1324 		/*  clear overflow interrupt latch */
1325 		spin_lock_irqsave(&dev->spinlock, flags);
1326 		outw(devpriv->adc_fifo_bits | LADFUL,
1327 		     devpriv->control_status + INT_ADCFIFO);
1328 		spin_unlock_irqrestore(&dev->spinlock, flags);
1329 		async->events |= COMEDI_CB_ERROR;
1330 	}
1331 
1332 	comedi_handle_events(dev, s);
1333 
1334 	return IRQ_HANDLED;
1335 }
1336 
cb_pcidas_auto_attach(struct comedi_device * dev,unsigned long context)1337 static int cb_pcidas_auto_attach(struct comedi_device *dev,
1338 				 unsigned long context)
1339 {
1340 	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1341 	const struct cb_pcidas_board *thisboard = NULL;
1342 	struct cb_pcidas_private *devpriv;
1343 	struct comedi_subdevice *s;
1344 	int i;
1345 	int ret;
1346 
1347 	if (context < ARRAY_SIZE(cb_pcidas_boards))
1348 		thisboard = &cb_pcidas_boards[context];
1349 	if (!thisboard)
1350 		return -ENODEV;
1351 	dev->board_ptr  = thisboard;
1352 	dev->board_name = thisboard->name;
1353 
1354 	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1355 	if (!devpriv)
1356 		return -ENOMEM;
1357 
1358 	ret = comedi_pci_enable(dev);
1359 	if (ret)
1360 		return ret;
1361 
1362 	devpriv->s5933_config = pci_resource_start(pcidev, 0);
1363 	devpriv->control_status = pci_resource_start(pcidev, 1);
1364 	devpriv->adc_fifo = pci_resource_start(pcidev, 2);
1365 	dev->iobase = pci_resource_start(pcidev, 3);
1366 	if (thisboard->ao_nchan)
1367 		devpriv->ao_registers = pci_resource_start(pcidev, 4);
1368 
1369 	/*  disable and clear interrupts on amcc s5933 */
1370 	outl(INTCSR_INBOX_INTR_STATUS,
1371 	     devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1372 
1373 	ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED,
1374 			  dev->board_name, dev);
1375 	if (ret) {
1376 		dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1377 			pcidev->irq);
1378 		return ret;
1379 	}
1380 	dev->irq = pcidev->irq;
1381 
1382 	dev->pacer = comedi_8254_init(dev->iobase + ADC8254,
1383 				      I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
1384 	if (!dev->pacer)
1385 		return -ENOMEM;
1386 
1387 	devpriv->ao_pacer = comedi_8254_init(dev->iobase + DAC8254,
1388 					     I8254_OSC_BASE_10MHZ,
1389 					     I8254_IO8, 0);
1390 	if (!devpriv->ao_pacer)
1391 		return -ENOMEM;
1392 
1393 	ret = comedi_alloc_subdevices(dev, 7);
1394 	if (ret)
1395 		return ret;
1396 
1397 	s = &dev->subdevices[0];
1398 	/* analog input subdevice */
1399 	dev->read_subdev = s;
1400 	s->type = COMEDI_SUBD_AI;
1401 	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1402 	/* WARNING: Number of inputs in differential mode is ignored */
1403 	s->n_chan = thisboard->ai_nchan;
1404 	s->len_chanlist = thisboard->ai_nchan;
1405 	s->maxdata = (1 << thisboard->ai_bits) - 1;
1406 	s->range_table = thisboard->ranges;
1407 	s->insn_read = cb_pcidas_ai_rinsn;
1408 	s->insn_config = ai_config_insn;
1409 	s->do_cmd = cb_pcidas_ai_cmd;
1410 	s->do_cmdtest = cb_pcidas_ai_cmdtest;
1411 	s->cancel = cb_pcidas_cancel;
1412 
1413 	/* analog output subdevice */
1414 	s = &dev->subdevices[1];
1415 	if (thisboard->ao_nchan) {
1416 		s->type = COMEDI_SUBD_AO;
1417 		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1418 		s->n_chan = thisboard->ao_nchan;
1419 		/*
1420 		 * analog out resolution is the same as
1421 		 * analog input resolution, so use ai_bits
1422 		 */
1423 		s->maxdata = (1 << thisboard->ai_bits) - 1;
1424 		s->range_table = &cb_pcidas_ao_ranges;
1425 		/* default to no fifo (*insn_write) */
1426 		s->insn_write = cb_pcidas_ao_nofifo_winsn;
1427 
1428 		ret = comedi_alloc_subdev_readback(s);
1429 		if (ret)
1430 			return ret;
1431 
1432 		if (thisboard->has_ao_fifo) {
1433 			dev->write_subdev = s;
1434 			s->subdev_flags |= SDF_CMD_WRITE;
1435 			/* use fifo (*insn_write) instead */
1436 			s->insn_write = cb_pcidas_ao_fifo_winsn;
1437 			s->do_cmdtest = cb_pcidas_ao_cmdtest;
1438 			s->do_cmd = cb_pcidas_ao_cmd;
1439 			s->cancel = cb_pcidas_ao_cancel;
1440 		}
1441 	} else {
1442 		s->type = COMEDI_SUBD_UNUSED;
1443 	}
1444 
1445 	/* 8255 */
1446 	s = &dev->subdevices[2];
1447 	ret = subdev_8255_init(dev, s, NULL, DIO_8255);
1448 	if (ret)
1449 		return ret;
1450 
1451 	/*  serial EEPROM, */
1452 	s = &dev->subdevices[3];
1453 	s->type = COMEDI_SUBD_MEMORY;
1454 	s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1455 	s->n_chan = 256;
1456 	s->maxdata = 0xff;
1457 	s->insn_read = eeprom_read_insn;
1458 
1459 	/*  8800 caldac */
1460 	s = &dev->subdevices[4];
1461 	s->type = COMEDI_SUBD_CALIB;
1462 	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1463 	s->n_chan = NUM_CHANNELS_8800;
1464 	s->maxdata = 0xff;
1465 	s->insn_write = cb_pcidas_caldac_insn_write;
1466 
1467 	ret = comedi_alloc_subdev_readback(s);
1468 	if (ret)
1469 		return ret;
1470 
1471 	for (i = 0; i < s->n_chan; i++) {
1472 		caldac_8800_write(dev, i, s->maxdata / 2);
1473 		s->readback[i] = s->maxdata / 2;
1474 	}
1475 
1476 	/*  trim potentiometer */
1477 	s = &dev->subdevices[5];
1478 	s->type = COMEDI_SUBD_CALIB;
1479 	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1480 	if (thisboard->trimpot == AD7376) {
1481 		s->n_chan = NUM_CHANNELS_7376;
1482 		s->maxdata = 0x7f;
1483 	} else {
1484 		s->n_chan = NUM_CHANNELS_8402;
1485 		s->maxdata = 0xff;
1486 	}
1487 	s->insn_write = cb_pcidas_trimpot_insn_write;
1488 
1489 	ret = comedi_alloc_subdev_readback(s);
1490 	if (ret)
1491 		return ret;
1492 
1493 	for (i = 0; i < s->n_chan; i++) {
1494 		cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1495 		s->readback[i] = s->maxdata / 2;
1496 	}
1497 
1498 	/*  dac08 caldac */
1499 	s = &dev->subdevices[6];
1500 	if (thisboard->has_dac08) {
1501 		s->type = COMEDI_SUBD_CALIB;
1502 		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1503 		s->n_chan = NUM_CHANNELS_DAC08;
1504 		s->maxdata = 0xff;
1505 		s->insn_write = cb_pcidas_dac08_insn_write;
1506 
1507 		ret = comedi_alloc_subdev_readback(s);
1508 		if (ret)
1509 			return ret;
1510 
1511 		for (i = 0; i < s->n_chan; i++) {
1512 			dac08_write(dev, s->maxdata / 2);
1513 			s->readback[i] = s->maxdata / 2;
1514 		}
1515 	} else {
1516 		s->type = COMEDI_SUBD_UNUSED;
1517 	}
1518 
1519 	/*  make sure mailbox 4 is empty */
1520 	inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1521 	/* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1522 	devpriv->s5933_intcsr_bits =
1523 	    INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1524 	    INTCSR_INBOX_FULL_INT;
1525 	/*  clear and enable interrupt on amcc s5933 */
1526 	outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1527 	     devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1528 
1529 	return 0;
1530 }
1531 
cb_pcidas_detach(struct comedi_device * dev)1532 static void cb_pcidas_detach(struct comedi_device *dev)
1533 {
1534 	struct cb_pcidas_private *devpriv = dev->private;
1535 
1536 	if (devpriv) {
1537 		if (devpriv->s5933_config)
1538 			outl(INTCSR_INBOX_INTR_STATUS,
1539 			     devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1540 		kfree(devpriv->ao_pacer);
1541 	}
1542 	comedi_pci_detach(dev);
1543 }
1544 
1545 static struct comedi_driver cb_pcidas_driver = {
1546 	.driver_name	= "cb_pcidas",
1547 	.module		= THIS_MODULE,
1548 	.auto_attach	= cb_pcidas_auto_attach,
1549 	.detach		= cb_pcidas_detach,
1550 };
1551 
cb_pcidas_pci_probe(struct pci_dev * dev,const struct pci_device_id * id)1552 static int cb_pcidas_pci_probe(struct pci_dev *dev,
1553 			       const struct pci_device_id *id)
1554 {
1555 	return comedi_pci_auto_config(dev, &cb_pcidas_driver,
1556 				      id->driver_data);
1557 }
1558 
1559 static const struct pci_device_id cb_pcidas_pci_table[] = {
1560 	{ PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 },
1561 	{ PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 },
1562 	{ PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 },
1563 	{ PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR },
1564 	{ PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR },
1565 	{ PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 },
1566 	{ PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 },
1567 	{ PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 },
1568 	{ 0 }
1569 };
1570 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1571 
1572 static struct pci_driver cb_pcidas_pci_driver = {
1573 	.name		= "cb_pcidas",
1574 	.id_table	= cb_pcidas_pci_table,
1575 	.probe		= cb_pcidas_pci_probe,
1576 	.remove		= comedi_pci_auto_unconfig,
1577 };
1578 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1579 
1580 MODULE_AUTHOR("Comedi http://www.comedi.org");
1581 MODULE_DESCRIPTION("Comedi low-level driver");
1582 MODULE_LICENSE("GPL");
1583