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