Staging: comedi: add cb_pcidda driver
[linux-2.6-block.git] / drivers / staging / comedi / drivers / cb_pcidda.c
CommitLineData
086df5b5
IM
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 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 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 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(comedi_device * dev, comedi_devconfig * it);
236static int cb_pcidda_detach(comedi_device * dev);
237//static int cb_pcidda_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
238static int cb_pcidda_ao_winsn(comedi_device * dev, comedi_subdevice * s,
239 comedi_insn * insn, lsampl_t * data);
240//static int cb_pcidda_ai_cmd(comedi_device *dev,comedi_subdevice *s);
241//static int cb_pcidda_ai_cmdtest(comedi_device *dev,comedi_subdevice *s, comedi_cmd *cmd);
242//static int cb_pcidda_ns_to_timer(unsigned int *ns,int round);
243static unsigned int cb_pcidda_serial_in(comedi_device * dev);
244static void cb_pcidda_serial_out(comedi_device * dev, unsigned int value,
245 unsigned int num_bits);
246static unsigned int cb_pcidda_read_eeprom(comedi_device * dev,
247 unsigned int address);
248static void cb_pcidda_calibrate(comedi_device * dev, unsigned int channel,
249 unsigned int range);
250
251/*
252 * The 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 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(comedi_device * dev, comedi_devconfig * it)
269{
270 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(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(comedi_device * dev, 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(comedi_device * dev, comedi_subdevice * s,
436 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(comedi_device * dev, comedi_subdevice * s,
602 comedi_insn * insn, lsampl_t * 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(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(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(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(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(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);