1 /*
2     comedi/drivers/cb_pcidda.c
3     This intends to be a driver for the ComputerBoards / MeasurementComputing
4     PCI-DDA series.
5 
6 	 Copyright (C) 2001 Ivan Martinez <ivanmr@altavista.com>
7     Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net>
8 
9     COMEDI - Linux Control and Measurement Device Interface
10     Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
11 
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; either version 2 of the License, or
15     (at your option) any later version.
16 
17     This program is distributed in the hope that it will be useful,
18     but WITHOUT ANY WARRANTY; without even the implied warranty of
19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20     GNU General Public License for more details.
21 
22     You should have received a copy of the GNU General Public License
23     along with this program; if not, write to the Free Software
24     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 
26 */
27 /*
28 Driver: cb_pcidda
29 Description: MeasurementComputing PCI-DDA series
30 Author: Ivan Martinez <ivanmr@altavista.com>, Frank Mori Hess <fmhess@users.sourceforge.net>
31 Status: Supports 08/16, 04/16, 02/16, 08/12, 04/12, and 02/12
32 Devices: [Measurement Computing] PCI-DDA08/12 (cb_pcidda), PCI-DDA04/12,
33   PCI-DDA02/12, PCI-DDA08/16, PCI-DDA04/16, PCI-DDA02/16
34 
35 Configuration options:
36   [0] - PCI bus of device (optional)
37   [1] - PCI slot of device (optional)
38   If bus/slot is not specified, the first available PCI
39   device will be used.
40 
41 Only simple analog output writing is supported.
42 
43 So far it has only been tested with:
44   - PCI-DDA08/12
45 Please report success/failure with other different cards to
46 <comedi@comedi.org>.
47 */
48 
49 #include "../comedidev.h"
50 
51 #include "comedi_pci.h"
52 #include "8255.h"
53 
54 #define PCI_VENDOR_ID_CB	0x1307	/*  PCI vendor number of ComputerBoards */
55 #define EEPROM_SIZE	128	/*  number of entries in eeprom */
56 #define MAX_AO_CHANNELS 8	/*  maximum number of ao channels for supported boards */
57 
58 /* PCI-DDA base addresses */
59 #define DIGITALIO_BADRINDEX	2
60 	/*  DIGITAL I/O is pci_dev->resource[2] */
61 #define DIGITALIO_SIZE 8
62 	/*  DIGITAL I/O uses 8 I/O port addresses */
63 #define DAC_BADRINDEX	3
64 	/*  DAC is pci_dev->resource[3] */
65 
66 /* Digital I/O registers */
67 #define PORT1A 0		/*  PORT 1A DATA */
68 
69 #define PORT1B 1		/*  PORT 1B DATA */
70 
71 #define PORT1C 2		/*  PORT 1C DATA */
72 
73 #define CONTROL1 3		/*  CONTROL REGISTER 1 */
74 
75 #define PORT2A 4		/*  PORT 2A DATA */
76 
77 #define PORT2B 5		/*  PORT 2B DATA */
78 
79 #define PORT2C 6		/*  PORT 2C DATA */
80 
81 #define CONTROL2 7		/*  CONTROL REGISTER 2 */
82 
83 /* DAC registers */
84 #define DACONTROL	0	/*  D/A CONTROL REGISTER */
85 #define	SU	0000001		/*  Simultaneous update enabled */
86 #define NOSU	0000000		/*  Simultaneous update disabled */
87 #define	ENABLEDAC	0000002	/*  Enable specified DAC */
88 #define	DISABLEDAC	0000000	/*  Disable specified DAC */
89 #define RANGE2V5	0000000	/*  2.5V */
90 #define RANGE5V	0000200		/*  5V */
91 #define RANGE10V	0000300	/*  10V */
92 #define UNIP	0000400		/*  Unipolar outputs */
93 #define BIP	0000000		/*  Bipolar outputs */
94 
95 #define DACALIBRATION1	4	/*  D/A CALIBRATION REGISTER 1 */
96 /* write bits */
97 #define	SERIAL_IN_BIT	0x1	/*  serial data input for eeprom, caldacs, reference dac */
98 #define	CAL_CHANNEL_MASK	(0x7 << 1)
99 #define	CAL_CHANNEL_BITS(channel)	(((channel) << 1) & CAL_CHANNEL_MASK)
100 /* read bits */
101 #define	CAL_COUNTER_MASK	0x1f
102 #define	CAL_COUNTER_OVERFLOW_BIT	0x20	/*  calibration counter overflow status bit */
103 #define	AO_BELOW_REF_BIT	0x40	/*  analog output is less than reference dac voltage */
104 #define	SERIAL_OUT_BIT	0x80	/*  serial data out, for reading from eeprom */
105 
106 #define DACALIBRATION2	6	/*  D/A CALIBRATION REGISTER 2 */
107 #define	SELECT_EEPROM_BIT	0x1	/*  send serial data in to eeprom */
108 #define	DESELECT_REF_DAC_BIT	0x2	/*  don't send serial data to MAX542 reference dac */
109 #define	DESELECT_CALDAC_BIT(n)	(0x4 << (n))	/*  don't send serial data to caldac n */
110 #define	DUMMY_BIT	0x40	/*  manual says to set this bit with no explanation */
111 
112 #define DADATA	8		/*  FIRST D/A DATA REGISTER (0) */
113 
114 static const struct comedi_lrange cb_pcidda_ranges = {
115 	6,
116 	{
117 	 BIP_RANGE(10),
118 	 BIP_RANGE(5),
119 	 BIP_RANGE(2.5),
120 	 UNI_RANGE(10),
121 	 UNI_RANGE(5),
122 	 UNI_RANGE(2.5),
123 	 }
124 };
125 
126 /*
127  * Board descriptions for two imaginary boards.  Describing the
128  * boards in this way is optional, and completely driver-dependent.
129  * Some drivers use arrays such as this, other do not.
130  */
131 struct cb_pcidda_board {
132 	const char *name;
133 	char status;		/*  Driver status: */
134 
135 	/*
136 	 * 0 - tested
137 	 * 1 - manual read, not tested
138 	 * 2 - manual not read
139 	 */
140 
141 	unsigned short device_id;
142 	int ao_chans;
143 	int ao_bits;
144 	const struct comedi_lrange *ranges;
145 };
146 
147 static const struct cb_pcidda_board cb_pcidda_boards[] = {
148 	{
149 	 .name = "pci-dda02/12",
150 	 .status = 1,
151 	 .device_id = 0x20,
152 	 .ao_chans = 2,
153 	 .ao_bits = 12,
154 	 .ranges = &cb_pcidda_ranges,
155 	 },
156 	{
157 	 .name = "pci-dda04/12",
158 	 .status = 1,
159 	 .device_id = 0x21,
160 	 .ao_chans = 4,
161 	 .ao_bits = 12,
162 	 .ranges = &cb_pcidda_ranges,
163 	 },
164 	{
165 	 .name = "pci-dda08/12",
166 	 .status = 0,
167 	 .device_id = 0x22,
168 	 .ao_chans = 8,
169 	 .ao_bits = 12,
170 	 .ranges = &cb_pcidda_ranges,
171 	 },
172 	{
173 	 .name = "pci-dda02/16",
174 	 .status = 2,
175 	 .device_id = 0x23,
176 	 .ao_chans = 2,
177 	 .ao_bits = 16,
178 	 .ranges = &cb_pcidda_ranges,
179 	 },
180 	{
181 	 .name = "pci-dda04/16",
182 	 .status = 2,
183 	 .device_id = 0x24,
184 	 .ao_chans = 4,
185 	 .ao_bits = 16,
186 	 .ranges = &cb_pcidda_ranges,
187 	 },
188 	{
189 	 .name = "pci-dda08/16",
190 	 .status = 0,
191 	 .device_id = 0x25,
192 	 .ao_chans = 8,
193 	 .ao_bits = 16,
194 	 .ranges = &cb_pcidda_ranges,
195 	 },
196 };
197 
198 static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = {
199 	{ PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0020) },
200 	{ PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0021) },
201 	{ PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0022) },
202 	{ PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0023) },
203 	{ PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0024) },
204 	{ PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0025) },
205 	{ 0 }
206 };
207 
208 MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
209 
210 /*
211  * Useful for shorthand access to the particular board structure
212  */
213 #define thisboard ((const struct cb_pcidda_board *)dev->board_ptr)
214 
215 /* this structure is for data unique to this hardware driver.  If
216    several hardware drivers keep similar information in this structure,
217    feel free to suggest moving the variable to the struct comedi_device struct.  */
218 struct cb_pcidda_private {
219 	int data;
220 
221 	/* would be useful for a PCI device */
222 	struct pci_dev *pci_dev;
223 
224 	unsigned long digitalio;
225 	unsigned long dac;
226 
227 	/* unsigned long control_status; */
228 	/* unsigned long adc_fifo; */
229 
230 	unsigned int dac_cal1_bits;	/*  bits last written to da calibration register 1 */
231 	unsigned int ao_range[MAX_AO_CHANNELS];	/*  current range settings for output channels */
232 	u16 eeprom_data[EEPROM_SIZE];	/*  software copy of board's eeprom */
233 };
234 
235 /*
236  * most drivers define the following macro to make it easy to
237  * access the private structure.
238  */
239 #define devpriv ((struct cb_pcidda_private *)dev->private)
240 
241 static int cb_pcidda_attach(struct comedi_device *dev,
242 			    struct comedi_devconfig *it);
243 static int cb_pcidda_detach(struct comedi_device *dev);
244 /* static int cb_pcidda_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data); */
245 static int cb_pcidda_ao_winsn(struct comedi_device *dev,
246 			      struct comedi_subdevice *s,
247 			      struct comedi_insn *insn, unsigned int *data);
248 
249 /* static int cb_pcidda_ai_cmd(struct comedi_device *dev, struct *comedi_subdevice *s);*/
250 /* static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd); */
251 /* static int cb_pcidda_ns_to_timer(unsigned int *ns,int *round); */
252 
253 static unsigned int cb_pcidda_serial_in(struct comedi_device *dev);
254 static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
255 				 unsigned int num_bits);
256 static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
257 					  unsigned int address);
258 static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
259 				unsigned int range);
260 
261 /*
262  * The struct comedi_driver structure tells the Comedi core module
263  * which functions to call to configure/deconfigure (attach/detach)
264  * the board, and also about the kernel module that contains
265  * the device code.
266  */
267 static struct comedi_driver driver_cb_pcidda = {
268 	.driver_name = "cb_pcidda",
269 	.module = THIS_MODULE,
270 	.attach = cb_pcidda_attach,
271 	.detach = cb_pcidda_detach,
272 };
273 
274 /*
275  * Attach is called by the Comedi core to configure the driver
276  * for a particular board.
277  */
cb_pcidda_attach(struct comedi_device * dev,struct comedi_devconfig * it)278 static int cb_pcidda_attach(struct comedi_device *dev,
279 			    struct comedi_devconfig *it)
280 {
281 	struct comedi_subdevice *s;
282 	struct pci_dev *pcidev = NULL;
283 	int index;
284 
285 
286 /*
287  * Allocate the private structure area.
288  */
289 	if (alloc_private(dev, sizeof(struct cb_pcidda_private)) < 0)
290 		return -ENOMEM;
291 
292 /*
293  * Probe the device to determine what device in the series it is.
294  */
295 
296 	for_each_pci_dev(pcidev) {
297 		if (pcidev->vendor == PCI_VENDOR_ID_CB) {
298 			if (it->options[0] || it->options[1]) {
299 				if (pcidev->bus->number != it->options[0] ||
300 				    PCI_SLOT(pcidev->devfn) != it->options[1]) {
301 					continue;
302 				}
303 			}
304 			for (index = 0; index < ARRAY_SIZE(cb_pcidda_boards); index++) {
305 				if (cb_pcidda_boards[index].device_id ==
306 				    pcidev->device) {
307 					goto found;
308 				}
309 			}
310 		}
311 	}
312 	if (!pcidev) {
313 		dev_err(dev->hw_dev, "Not a ComputerBoards/MeasurementComputing card on requested position\n");
314 		return -EIO;
315 	}
316 found:
317 	devpriv->pci_dev = pcidev;
318 	dev->board_ptr = cb_pcidda_boards + index;
319 	/*  "thisboard" macro can be used from here. */
320 	dev_dbg(dev->hw_dev, "Found %s at requested position\n",
321 		thisboard->name);
322 
323 	/*
324 	 * Enable PCI device and request regions.
325 	 */
326 	if (comedi_pci_enable(pcidev, thisboard->name)) {
327 		dev_err(dev->hw_dev, "cb_pcidda: failed to enable PCI device and request regions\n");
328 		return -EIO;
329 	}
330 
331 /*
332  * Allocate the I/O ports.
333  */
334 	devpriv->digitalio =
335 	    pci_resource_start(devpriv->pci_dev, DIGITALIO_BADRINDEX);
336 	devpriv->dac = pci_resource_start(devpriv->pci_dev, DAC_BADRINDEX);
337 
338 /*
339  * Warn about the status of the driver.
340  */
341 	if (thisboard->status == 2)
342 		printk
343 		    ("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. "
344 		     "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. "
345 		     "PLEASE REPORT USAGE TO <ivanmr@altavista.com>.\n");
346 
347 /*
348  * Initialize dev->board_name.
349  */
350 	dev->board_name = thisboard->name;
351 
352 /*
353  * Allocate the subdevice structures.
354  */
355 	if (alloc_subdevices(dev, 3) < 0)
356 		return -ENOMEM;
357 
358 	s = dev->subdevices + 0;
359 	/* analog output subdevice */
360 	s->type = COMEDI_SUBD_AO;
361 	s->subdev_flags = SDF_WRITABLE;
362 	s->n_chan = thisboard->ao_chans;
363 	s->maxdata = (1 << thisboard->ao_bits) - 1;
364 	s->range_table = thisboard->ranges;
365 	s->insn_write = cb_pcidda_ao_winsn;
366 
367 	/* s->subdev_flags |= SDF_CMD_READ; */
368 	/* s->do_cmd = cb_pcidda_ai_cmd; */
369 	/* s->do_cmdtest = cb_pcidda_ai_cmdtest; */
370 
371 	/*  two 8255 digital io subdevices */
372 	s = dev->subdevices + 1;
373 	subdev_8255_init(dev, s, NULL, devpriv->digitalio);
374 	s = dev->subdevices + 2;
375 	subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A);
376 
377 	dev_dbg(dev->hw_dev, "eeprom:\n");
378 	for (index = 0; index < EEPROM_SIZE; index++) {
379 		devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index);
380 		dev_dbg(dev->hw_dev, "%i:0x%x\n", index, devpriv->eeprom_data[index]);
381 	}
382 
383 	/*  set calibrations dacs */
384 	for (index = 0; index < thisboard->ao_chans; index++)
385 		cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]);
386 
387 	return 1;
388 }
389 
390 /*
391  * _detach is called to deconfigure a device.  It should deallocate
392  * resources.
393  * This function is also called when _attach() fails, so it should be
394  * careful not to release resources that were not necessarily
395  * allocated by _attach().  dev->private and dev->subdevices are
396  * deallocated automatically by the core.
397  */
cb_pcidda_detach(struct comedi_device * dev)398 static int cb_pcidda_detach(struct comedi_device *dev)
399 {
400 /*
401  * Deallocate the I/O ports.
402  */
403 	if (devpriv) {
404 		if (devpriv->pci_dev) {
405 			if (devpriv->dac)
406 				comedi_pci_disable(devpriv->pci_dev);
407 			pci_dev_put(devpriv->pci_dev);
408 		}
409 	}
410 	/*  cleanup 8255 */
411 	if (dev->subdevices) {
412 		subdev_8255_cleanup(dev, dev->subdevices + 1);
413 		subdev_8255_cleanup(dev, dev->subdevices + 2);
414 	}
415 
416 	return 0;
417 }
418 
419 /*
420  * I will program this later... ;-)
421  */
422 #if 0
423 static int cb_pcidda_ai_cmd(struct comedi_device *dev,
424 			    struct comedi_subdevice *s)
425 {
426 	printk("cb_pcidda_ai_cmd\n");
427 	printk("subdev: %d\n", cmd->subdev);
428 	printk("flags: %d\n", cmd->flags);
429 	printk("start_src: %d\n", cmd->start_src);
430 	printk("start_arg: %d\n", cmd->start_arg);
431 	printk("scan_begin_src: %d\n", cmd->scan_begin_src);
432 	printk("convert_src: %d\n", cmd->convert_src);
433 	printk("convert_arg: %d\n", cmd->convert_arg);
434 	printk("scan_end_src: %d\n", cmd->scan_end_src);
435 	printk("scan_end_arg: %d\n", cmd->scan_end_arg);
436 	printk("stop_src: %d\n", cmd->stop_src);
437 	printk("stop_arg: %d\n", cmd->stop_arg);
438 	printk("chanlist_len: %d\n", cmd->chanlist_len);
439 }
440 #endif
441 
442 #if 0
443 static int cb_pcidda_ai_cmdtest(struct comedi_device *dev,
444 				struct comedi_subdevice *s,
445 				struct comedi_cmd *cmd)
446 {
447 	int err = 0;
448 	int tmp;
449 
450 	/* cmdtest tests a particular command to see if it is valid.
451 	 * Using the cmdtest ioctl, a user can create a valid cmd
452 	 * and then have it executes by the cmd ioctl.
453 	 *
454 	 * cmdtest returns 1,2,3,4 or 0, depending on which tests
455 	 * the command passes. */
456 
457 	/* step 1: make sure trigger sources are trivially valid */
458 
459 	tmp = cmd->start_src;
460 	cmd->start_src &= TRIG_NOW;
461 	if (!cmd->start_src || tmp != cmd->start_src)
462 		err++;
463 
464 	tmp = cmd->scan_begin_src;
465 	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
466 	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
467 		err++;
468 
469 	tmp = cmd->convert_src;
470 	cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
471 	if (!cmd->convert_src || tmp != cmd->convert_src)
472 		err++;
473 
474 	tmp = cmd->scan_end_src;
475 	cmd->scan_end_src &= TRIG_COUNT;
476 	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
477 		err++;
478 
479 	tmp = cmd->stop_src;
480 	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
481 	if (!cmd->stop_src || tmp != cmd->stop_src)
482 		err++;
483 
484 	if (err)
485 		return 1;
486 
487 	/* step 2: make sure trigger sources are unique and mutually compatible */
488 
489 	/* note that mutual compatibility is not an issue here */
490 	if (cmd->scan_begin_src != TRIG_TIMER
491 	    && cmd->scan_begin_src != TRIG_EXT)
492 		err++;
493 	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
494 		err++;
495 	if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT)
496 		err++;
497 
498 	if (err)
499 		return 2;
500 
501 	/* step 3: make sure arguments are trivially compatible */
502 
503 	if (cmd->start_arg != 0) {
504 		cmd->start_arg = 0;
505 		err++;
506 	}
507 #define MAX_SPEED	10000	/* in nanoseconds */
508 #define MIN_SPEED	1000000000	/* in nanoseconds */
509 
510 	if (cmd->scan_begin_src == TRIG_TIMER) {
511 		if (cmd->scan_begin_arg < MAX_SPEED) {
512 			cmd->scan_begin_arg = MAX_SPEED;
513 			err++;
514 		}
515 		if (cmd->scan_begin_arg > MIN_SPEED) {
516 			cmd->scan_begin_arg = MIN_SPEED;
517 			err++;
518 		}
519 	} else {
520 		/* external trigger */
521 		/* should be level/edge, hi/lo specification here */
522 		/* should specify multiple external triggers */
523 		if (cmd->scan_begin_arg > 9) {
524 			cmd->scan_begin_arg = 9;
525 			err++;
526 		}
527 	}
528 	if (cmd->convert_src == TRIG_TIMER) {
529 		if (cmd->convert_arg < MAX_SPEED) {
530 			cmd->convert_arg = MAX_SPEED;
531 			err++;
532 		}
533 		if (cmd->convert_arg > MIN_SPEED) {
534 			cmd->convert_arg = MIN_SPEED;
535 			err++;
536 		}
537 	} else {
538 		/* external trigger */
539 		/* see above */
540 		if (cmd->convert_arg > 9) {
541 			cmd->convert_arg = 9;
542 			err++;
543 		}
544 	}
545 
546 	if (cmd->scan_end_arg != cmd->chanlist_len) {
547 		cmd->scan_end_arg = cmd->chanlist_len;
548 		err++;
549 	}
550 	if (cmd->stop_src == TRIG_COUNT) {
551 		if (cmd->stop_arg > 0x00ffffff) {
552 			cmd->stop_arg = 0x00ffffff;
553 			err++;
554 		}
555 	} else {
556 		/* TRIG_NONE */
557 		if (cmd->stop_arg != 0) {
558 			cmd->stop_arg = 0;
559 			err++;
560 		}
561 	}
562 
563 	if (err)
564 		return 3;
565 
566 	/* step 4: fix up any arguments */
567 
568 	if (cmd->scan_begin_src == TRIG_TIMER) {
569 		tmp = cmd->scan_begin_arg;
570 		cb_pcidda_ns_to_timer(&cmd->scan_begin_arg,
571 				      cmd->flags & TRIG_ROUND_MASK);
572 		if (tmp != cmd->scan_begin_arg)
573 			err++;
574 	}
575 	if (cmd->convert_src == TRIG_TIMER) {
576 		tmp = cmd->convert_arg;
577 		cb_pcidda_ns_to_timer(&cmd->convert_arg,
578 				      cmd->flags & TRIG_ROUND_MASK);
579 		if (tmp != cmd->convert_arg)
580 			err++;
581 		if (cmd->scan_begin_src == TRIG_TIMER &&
582 		    cmd->scan_begin_arg <
583 		    cmd->convert_arg * cmd->scan_end_arg) {
584 			cmd->scan_begin_arg =
585 			    cmd->convert_arg * cmd->scan_end_arg;
586 			err++;
587 		}
588 	}
589 
590 	if (err)
591 		return 4;
592 
593 	return 0;
594 }
595 #endif
596 
597 /* This function doesn't require a particular form, this is just
598  * what happens to be used in some of the drivers.  It should
599  * convert ns nanoseconds to a counter value suitable for programming
600  * the device.  Also, it should adjust ns so that it cooresponds to
601  * the actual time that the device will use. */
602 #if 0
603 static int cb_pcidda_ns_to_timer(unsigned int *ns, int round)
604 {
605 	/* trivial timer */
606 	return *ns;
607 }
608 #endif
609 
cb_pcidda_ao_winsn(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)610 static int cb_pcidda_ao_winsn(struct comedi_device *dev,
611 			      struct comedi_subdevice *s,
612 			      struct comedi_insn *insn, unsigned int *data)
613 {
614 	unsigned int command;
615 	unsigned int channel, range;
616 
617 	channel = CR_CHAN(insn->chanspec);
618 	range = CR_RANGE(insn->chanspec);
619 
620 	/*  adjust calibration dacs if range has changed */
621 	if (range != devpriv->ao_range[channel])
622 		cb_pcidda_calibrate(dev, channel, range);
623 
624 	/* output channel configuration */
625 	command = NOSU | ENABLEDAC;
626 
627 	/* output channel range */
628 	switch (range) {
629 	case 0:
630 		command |= BIP | RANGE10V;
631 		break;
632 	case 1:
633 		command |= BIP | RANGE5V;
634 		break;
635 	case 2:
636 		command |= BIP | RANGE2V5;
637 		break;
638 	case 3:
639 		command |= UNIP | RANGE10V;
640 		break;
641 	case 4:
642 		command |= UNIP | RANGE5V;
643 		break;
644 	case 5:
645 		command |= UNIP | RANGE2V5;
646 		break;
647 	}
648 
649 	/* output channel specification */
650 	command |= channel << 2;
651 	outw(command, devpriv->dac + DACONTROL);
652 
653 	/* write data */
654 	outw(data[0], devpriv->dac + DADATA + channel * 2);
655 
656 	/* return the number of samples read/written */
657 	return 1;
658 }
659 
660 /* lowlevel read from eeprom */
cb_pcidda_serial_in(struct comedi_device * dev)661 static unsigned int cb_pcidda_serial_in(struct comedi_device *dev)
662 {
663 	unsigned int value = 0;
664 	int i;
665 	const int value_width = 16;	/*  number of bits wide values are */
666 
667 	for (i = 1; i <= value_width; i++) {
668 		/*  read bits most significant bit first */
669 		if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT)
670 			value |= 1 << (value_width - i);
671 	}
672 
673 	return value;
674 }
675 
676 /* lowlevel write to eeprom/dac */
cb_pcidda_serial_out(struct comedi_device * dev,unsigned int value,unsigned int num_bits)677 static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
678 				 unsigned int num_bits)
679 {
680 	int i;
681 
682 	for (i = 1; i <= num_bits; i++) {
683 		/*  send bits most significant bit first */
684 		if (value & (1 << (num_bits - i)))
685 			devpriv->dac_cal1_bits |= SERIAL_IN_BIT;
686 		else
687 			devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT;
688 		outw_p(devpriv->dac_cal1_bits, devpriv->dac + DACALIBRATION1);
689 	}
690 }
691 
692 /* reads a 16 bit value from board's eeprom */
cb_pcidda_read_eeprom(struct comedi_device * dev,unsigned int address)693 static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
694 					  unsigned int address)
695 {
696 	unsigned int i;
697 	unsigned int cal2_bits;
698 	unsigned int value;
699 	const int max_num_caldacs = 4;	/*  one caldac for every two dac channels */
700 	const int read_instruction = 0x6;	/*  bits to send to tell eeprom we want to read */
701 	const int instruction_length = 3;
702 	const int address_length = 8;
703 
704 	/*  send serial output stream to eeprom */
705 	cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
706 	/*  deactivate caldacs (one caldac for every two channels) */
707 	for (i = 0; i < max_num_caldacs; i++)
708 		cal2_bits |= DESELECT_CALDAC_BIT(i);
709 	outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
710 
711 	/*  tell eeprom we want to read */
712 	cb_pcidda_serial_out(dev, read_instruction, instruction_length);
713 	/*  send address we want to read from */
714 	cb_pcidda_serial_out(dev, address, address_length);
715 
716 	value = cb_pcidda_serial_in(dev);
717 
718 	/*  deactivate eeprom */
719 	cal2_bits &= ~SELECT_EEPROM_BIT;
720 	outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
721 
722 	return value;
723 }
724 
725 /* writes to 8 bit calibration dacs */
cb_pcidda_write_caldac(struct comedi_device * dev,unsigned int caldac,unsigned int channel,unsigned int value)726 static void cb_pcidda_write_caldac(struct comedi_device *dev,
727 				   unsigned int caldac, unsigned int channel,
728 				   unsigned int value)
729 {
730 	unsigned int cal2_bits;
731 	unsigned int i;
732 	const int num_channel_bits = 3;	/*  caldacs use 3 bit channel specification */
733 	const int num_caldac_bits = 8;	/*  8 bit calibration dacs */
734 	const int max_num_caldacs = 4;	/*  one caldac for every two dac channels */
735 
736 	/* write 3 bit channel */
737 	cb_pcidda_serial_out(dev, channel, num_channel_bits);
738 	/*  write 8 bit caldac value */
739 	cb_pcidda_serial_out(dev, value, num_caldac_bits);
740 
741 /*
742 * latch stream into appropriate caldac deselect reference dac
743 */
744 	cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
745 	/*  deactivate caldacs (one caldac for every two channels) */
746 	for (i = 0; i < max_num_caldacs; i++)
747 		cal2_bits |= DESELECT_CALDAC_BIT(i);
748 	/*  activate the caldac we want */
749 	cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
750 	outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
751 	/*  deactivate caldac */
752 	cal2_bits |= DESELECT_CALDAC_BIT(caldac);
753 	outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
754 }
755 
756 /* returns caldac that calibrates given analog out channel */
caldac_number(unsigned int channel)757 static unsigned int caldac_number(unsigned int channel)
758 {
759 	return channel / 2;
760 }
761 
762 /* returns caldac channel that provides fine gain for given ao channel */
fine_gain_channel(unsigned int ao_channel)763 static unsigned int fine_gain_channel(unsigned int ao_channel)
764 {
765 	return 4 * (ao_channel % 2);
766 }
767 
768 /* returns caldac channel that provides coarse gain for given ao channel */
coarse_gain_channel(unsigned int ao_channel)769 static unsigned int coarse_gain_channel(unsigned int ao_channel)
770 {
771 	return 1 + 4 * (ao_channel % 2);
772 }
773 
774 /* returns caldac channel that provides coarse offset for given ao channel */
coarse_offset_channel(unsigned int ao_channel)775 static unsigned int coarse_offset_channel(unsigned int ao_channel)
776 {
777 	return 2 + 4 * (ao_channel % 2);
778 }
779 
780 /* returns caldac channel that provides fine offset for given ao channel */
fine_offset_channel(unsigned int ao_channel)781 static unsigned int fine_offset_channel(unsigned int ao_channel)
782 {
783 	return 3 + 4 * (ao_channel % 2);
784 }
785 
786 /* returns eeprom address that provides offset for given ao channel and range */
offset_eeprom_address(unsigned int ao_channel,unsigned int range)787 static unsigned int offset_eeprom_address(unsigned int ao_channel,
788 					  unsigned int range)
789 {
790 	return 0x7 + 2 * range + 12 * ao_channel;
791 }
792 
793 /* returns eeprom address that provides gain calibration for given ao channel and range */
gain_eeprom_address(unsigned int ao_channel,unsigned int range)794 static unsigned int gain_eeprom_address(unsigned int ao_channel,
795 					unsigned int range)
796 {
797 	return 0x8 + 2 * range + 12 * ao_channel;
798 }
799 
800 /* returns upper byte of eeprom entry, which gives the coarse adjustment values */
eeprom_coarse_byte(unsigned int word)801 static unsigned int eeprom_coarse_byte(unsigned int word)
802 {
803 	return (word >> 8) & 0xff;
804 }
805 
806 /* returns lower byte of eeprom entry, which gives the fine adjustment values */
eeprom_fine_byte(unsigned int word)807 static unsigned int eeprom_fine_byte(unsigned int word)
808 {
809 	return word & 0xff;
810 }
811 
812 /* set caldacs to eeprom values for given channel and range */
cb_pcidda_calibrate(struct comedi_device * dev,unsigned int channel,unsigned int range)813 static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
814 				unsigned int range)
815 {
816 	unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain;
817 
818 	/*  remember range so we can tell when we need to readjust calibration */
819 	devpriv->ao_range[channel] = range;
820 
821 	/*  get values from eeprom data */
822 	coarse_offset =
823 	    eeprom_coarse_byte(devpriv->eeprom_data
824 			       [offset_eeprom_address(channel, range)]);
825 	fine_offset =
826 	    eeprom_fine_byte(devpriv->eeprom_data
827 			     [offset_eeprom_address(channel, range)]);
828 	coarse_gain =
829 	    eeprom_coarse_byte(devpriv->eeprom_data
830 			       [gain_eeprom_address(channel, range)]);
831 	fine_gain =
832 	    eeprom_fine_byte(devpriv->eeprom_data
833 			     [gain_eeprom_address(channel, range)]);
834 
835 	/*  set caldacs */
836 	cb_pcidda_write_caldac(dev, caldac_number(channel),
837 			       coarse_offset_channel(channel), coarse_offset);
838 	cb_pcidda_write_caldac(dev, caldac_number(channel),
839 			       fine_offset_channel(channel), fine_offset);
840 	cb_pcidda_write_caldac(dev, caldac_number(channel),
841 			       coarse_gain_channel(channel), coarse_gain);
842 	cb_pcidda_write_caldac(dev, caldac_number(channel),
843 			       fine_gain_channel(channel), fine_gain);
844 }
845 
846 /*
847  * A convenient macro that defines init_module() and cleanup_module(),
848  * as necessary.
849  */
driver_cb_pcidda_pci_probe(struct pci_dev * dev,const struct pci_device_id * ent)850 static int __devinit driver_cb_pcidda_pci_probe(struct pci_dev *dev,
851 						const struct pci_device_id *ent)
852 {
853 	return comedi_pci_auto_config(dev, driver_cb_pcidda.driver_name);
854 }
855 
driver_cb_pcidda_pci_remove(struct pci_dev * dev)856 static void __devexit driver_cb_pcidda_pci_remove(struct pci_dev *dev)
857 {
858 	comedi_pci_auto_unconfig(dev);
859 }
860 
861 static struct pci_driver driver_cb_pcidda_pci_driver = {
862 	.id_table = cb_pcidda_pci_table,
863 	.probe = &driver_cb_pcidda_pci_probe,
864 	.remove = __devexit_p(&driver_cb_pcidda_pci_remove)
865 };
866 
driver_cb_pcidda_init_module(void)867 static int __init driver_cb_pcidda_init_module(void)
868 {
869 	int retval;
870 
871 	retval = comedi_driver_register(&driver_cb_pcidda);
872 	if (retval < 0)
873 		return retval;
874 
875 	driver_cb_pcidda_pci_driver.name = (char *)driver_cb_pcidda.driver_name;
876 	return pci_register_driver(&driver_cb_pcidda_pci_driver);
877 }
878 
driver_cb_pcidda_cleanup_module(void)879 static void __exit driver_cb_pcidda_cleanup_module(void)
880 {
881 	pci_unregister_driver(&driver_cb_pcidda_pci_driver);
882 	comedi_driver_unregister(&driver_cb_pcidda);
883 }
884 
885 module_init(driver_cb_pcidda_init_module);
886 module_exit(driver_cb_pcidda_cleanup_module);
887 
888 MODULE_AUTHOR("Comedi http://www.comedi.org");
889 MODULE_DESCRIPTION("Comedi low-level driver");
890 MODULE_LICENSE("GPL");
891