2 comedi/drivers/cb_pcidda.c
3 This intends to be a driver for the ComputerBoards / MeasurementComputing
6 Copyright (C) 2001 Ivan Martinez <ivanmr@altavista.com>
7 Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net>
9 COMEDI - Linux Control and Measurement Device Interface
10 Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
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.
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.
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.
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
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
41 Only simple analog output writing is supported.
43 So far it has only been tested with:
45 Please report success/failure with other different cards to
49 #include "../comedidev.h"
51 #include "comedi_fc.h"
54 /* PCI vendor number of ComputerBoards */
55 #define PCI_VENDOR_ID_CB 0x1307
56 #define EEPROM_SIZE 128 /* number of entries in eeprom */
57 /* maximum number of ao channels for supported boards */
58 #define MAX_AO_CHANNELS 8
60 /* Digital I/O registers */
61 #define PORT1A 0 /* PORT 1A DATA */
63 #define PORT1B 1 /* PORT 1B DATA */
65 #define PORT1C 2 /* PORT 1C DATA */
67 #define CONTROL1 3 /* CONTROL REGISTER 1 */
69 #define PORT2A 4 /* PORT 2A DATA */
71 #define PORT2B 5 /* PORT 2B DATA */
73 #define PORT2C 6 /* PORT 2C DATA */
75 #define CONTROL2 7 /* CONTROL REGISTER 2 */
78 #define DACONTROL 0 /* D/A CONTROL REGISTER */
79 #define SU 0000001 /* Simultaneous update enabled */
80 #define NOSU 0000000 /* Simultaneous update disabled */
81 #define ENABLEDAC 0000002 /* Enable specified DAC */
82 #define DISABLEDAC 0000000 /* Disable specified DAC */
83 #define RANGE2V5 0000000 /* 2.5V */
84 #define RANGE5V 0000200 /* 5V */
85 #define RANGE10V 0000300 /* 10V */
86 #define UNIP 0000400 /* Unipolar outputs */
87 #define BIP 0000000 /* Bipolar outputs */
89 #define DACALIBRATION1 4 /* D/A CALIBRATION REGISTER 1 */
91 /* serial data input for eeprom, caldacs, reference dac */
92 #define SERIAL_IN_BIT 0x1
93 #define CAL_CHANNEL_MASK (0x7 << 1)
94 #define CAL_CHANNEL_BITS(channel) (((channel) << 1) & CAL_CHANNEL_MASK)
96 #define CAL_COUNTER_MASK 0x1f
97 /* calibration counter overflow status bit */
98 #define CAL_COUNTER_OVERFLOW_BIT 0x20
99 /* analog output is less than reference dac voltage */
100 #define AO_BELOW_REF_BIT 0x40
101 #define SERIAL_OUT_BIT 0x80 /* serial data out, for reading from eeprom */
103 #define DACALIBRATION2 6 /* D/A CALIBRATION REGISTER 2 */
104 #define SELECT_EEPROM_BIT 0x1 /* send serial data in to eeprom */
105 /* don't send serial data to MAX542 reference dac */
106 #define DESELECT_REF_DAC_BIT 0x2
107 /* don't send serial data to caldac n */
108 #define DESELECT_CALDAC_BIT(n) (0x4 << (n))
109 /* manual says to set this bit with no explanation */
110 #define DUMMY_BIT 0x40
112 #define DADATA 8 /* FIRST D/A DATA REGISTER (0) */
114 static const struct comedi_lrange cb_pcidda_ranges = {
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.
131 struct cb_pcidda_board {
133 char status; /* Driver status: */
137 * 1 - manual read, not tested
138 * 2 - manual not read
141 unsigned short device_id;
144 const struct comedi_lrange *ranges;
147 static const struct cb_pcidda_board cb_pcidda_boards[] = {
149 .name = "pci-dda02/12",
154 .ranges = &cb_pcidda_ranges,
157 .name = "pci-dda04/12",
162 .ranges = &cb_pcidda_ranges,
165 .name = "pci-dda08/12",
170 .ranges = &cb_pcidda_ranges,
173 .name = "pci-dda02/16",
178 .ranges = &cb_pcidda_ranges,
181 .name = "pci-dda04/16",
186 .ranges = &cb_pcidda_ranges,
189 .name = "pci-dda08/16",
194 .ranges = &cb_pcidda_ranges,
199 * this structure is for data unique to this hardware driver. If
200 * several hardware drivers keep similar information in this structure,
201 * feel free to suggest moving the variable to the struct comedi_device
204 struct cb_pcidda_private {
207 unsigned long digitalio;
210 /* unsigned long control_status; */
211 /* unsigned long adc_fifo; */
213 /* bits last written to da calibration register 1 */
214 unsigned int dac_cal1_bits;
215 /* current range settings for output channels */
216 unsigned int ao_range[MAX_AO_CHANNELS];
217 u16 eeprom_data[EEPROM_SIZE]; /* software copy of board's eeprom */
221 * I will program this later... ;-)
224 static int cb_pcidda_ai_cmd(struct comedi_device *dev,
225 struct comedi_subdevice *s)
227 printk("cb_pcidda_ai_cmd\n");
228 printk("subdev: %d\n", cmd->subdev);
229 printk("flags: %d\n", cmd->flags);
230 printk("start_src: %d\n", cmd->start_src);
231 printk("start_arg: %d\n", cmd->start_arg);
232 printk("scan_begin_src: %d\n", cmd->scan_begin_src);
233 printk("convert_src: %d\n", cmd->convert_src);
234 printk("convert_arg: %d\n", cmd->convert_arg);
235 printk("scan_end_src: %d\n", cmd->scan_end_src);
236 printk("scan_end_arg: %d\n", cmd->scan_end_arg);
237 printk("stop_src: %d\n", cmd->stop_src);
238 printk("stop_arg: %d\n", cmd->stop_arg);
239 printk("chanlist_len: %d\n", cmd->chanlist_len);
244 static int cb_pcidda_ai_cmdtest(struct comedi_device *dev,
245 struct comedi_subdevice *s,
246 struct comedi_cmd *cmd)
251 /* Step 1 : check if triggers are trivially valid */
253 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
254 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
255 TRIG_TIMER | TRIG_EXT);
256 err |= cfc_check_trigger_src(&cmd->convert_src,
257 TRIG_TIMER | TRIG_EXT);
258 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
259 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
264 /* Step 2a : make sure trigger sources are unique */
266 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
267 err |= cfc_check_trigger_is_unique(cmd->convert_src);
268 err |= cfc_check_trigger_is_unique(cmd->stop_src);
270 /* Step 2b : and mutually compatible */
275 /* step 3: make sure arguments are trivially compatible */
277 if (cmd->start_arg != 0) {
281 #define MAX_SPEED 10000 /* in nanoseconds */
282 #define MIN_SPEED 1000000000 /* in nanoseconds */
284 if (cmd->scan_begin_src == TRIG_TIMER) {
285 if (cmd->scan_begin_arg < MAX_SPEED) {
286 cmd->scan_begin_arg = MAX_SPEED;
289 if (cmd->scan_begin_arg > MIN_SPEED) {
290 cmd->scan_begin_arg = MIN_SPEED;
294 /* external trigger */
295 /* should be level/edge, hi/lo specification here */
296 /* should specify multiple external triggers */
297 if (cmd->scan_begin_arg > 9) {
298 cmd->scan_begin_arg = 9;
302 if (cmd->convert_src == TRIG_TIMER) {
303 if (cmd->convert_arg < MAX_SPEED) {
304 cmd->convert_arg = MAX_SPEED;
307 if (cmd->convert_arg > MIN_SPEED) {
308 cmd->convert_arg = MIN_SPEED;
312 /* external trigger */
314 if (cmd->convert_arg > 9) {
315 cmd->convert_arg = 9;
320 if (cmd->scan_end_arg != cmd->chanlist_len) {
321 cmd->scan_end_arg = cmd->chanlist_len;
324 if (cmd->stop_src == TRIG_COUNT) {
325 if (cmd->stop_arg > 0x00ffffff) {
326 cmd->stop_arg = 0x00ffffff;
331 if (cmd->stop_arg != 0) {
340 /* step 4: fix up any arguments */
342 if (cmd->scan_begin_src == TRIG_TIMER) {
343 tmp = cmd->scan_begin_arg;
344 cb_pcidda_ns_to_timer(&cmd->scan_begin_arg,
345 cmd->flags & TRIG_ROUND_MASK);
346 if (tmp != cmd->scan_begin_arg)
349 if (cmd->convert_src == TRIG_TIMER) {
350 tmp = cmd->convert_arg;
351 cb_pcidda_ns_to_timer(&cmd->convert_arg,
352 cmd->flags & TRIG_ROUND_MASK);
353 if (tmp != cmd->convert_arg)
355 if (cmd->scan_begin_src == TRIG_TIMER &&
356 cmd->scan_begin_arg <
357 cmd->convert_arg * cmd->scan_end_arg) {
358 cmd->scan_begin_arg =
359 cmd->convert_arg * cmd->scan_end_arg;
371 /* This function doesn't require a particular form, this is just
372 * what happens to be used in some of the drivers. It should
373 * convert ns nanoseconds to a counter value suitable for programming
374 * the device. Also, it should adjust ns so that it cooresponds to
375 * the actual time that the device will use. */
377 static int cb_pcidda_ns_to_timer(unsigned int *ns, int round)
384 /* lowlevel read from eeprom */
385 static unsigned int cb_pcidda_serial_in(struct comedi_device *dev)
387 struct cb_pcidda_private *devpriv = dev->private;
388 unsigned int value = 0;
390 const int value_width = 16; /* number of bits wide values are */
392 for (i = 1; i <= value_width; i++) {
393 /* read bits most significant bit first */
394 if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT)
395 value |= 1 << (value_width - i);
401 /* lowlevel write to eeprom/dac */
402 static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
403 unsigned int num_bits)
405 struct cb_pcidda_private *devpriv = dev->private;
408 for (i = 1; i <= num_bits; i++) {
409 /* send bits most significant bit first */
410 if (value & (1 << (num_bits - i)))
411 devpriv->dac_cal1_bits |= SERIAL_IN_BIT;
413 devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT;
414 outw_p(devpriv->dac_cal1_bits, devpriv->dac + DACALIBRATION1);
418 /* reads a 16 bit value from board's eeprom */
419 static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
420 unsigned int address)
422 struct cb_pcidda_private *devpriv = dev->private;
424 unsigned int cal2_bits;
426 /* one caldac for every two dac channels */
427 const int max_num_caldacs = 4;
428 /* bits to send to tell eeprom we want to read */
429 const int read_instruction = 0x6;
430 const int instruction_length = 3;
431 const int address_length = 8;
433 /* send serial output stream to eeprom */
434 cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
435 /* deactivate caldacs (one caldac for every two channels) */
436 for (i = 0; i < max_num_caldacs; i++)
437 cal2_bits |= DESELECT_CALDAC_BIT(i);
438 outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
440 /* tell eeprom we want to read */
441 cb_pcidda_serial_out(dev, read_instruction, instruction_length);
442 /* send address we want to read from */
443 cb_pcidda_serial_out(dev, address, address_length);
445 value = cb_pcidda_serial_in(dev);
447 /* deactivate eeprom */
448 cal2_bits &= ~SELECT_EEPROM_BIT;
449 outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
454 /* writes to 8 bit calibration dacs */
455 static void cb_pcidda_write_caldac(struct comedi_device *dev,
456 unsigned int caldac, unsigned int channel,
459 struct cb_pcidda_private *devpriv = dev->private;
460 unsigned int cal2_bits;
462 /* caldacs use 3 bit channel specification */
463 const int num_channel_bits = 3;
464 const int num_caldac_bits = 8; /* 8 bit calibration dacs */
465 /* one caldac for every two dac channels */
466 const int max_num_caldacs = 4;
468 /* write 3 bit channel */
469 cb_pcidda_serial_out(dev, channel, num_channel_bits);
470 /* write 8 bit caldac value */
471 cb_pcidda_serial_out(dev, value, num_caldac_bits);
474 * latch stream into appropriate caldac deselect reference dac
476 cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
477 /* deactivate caldacs (one caldac for every two channels) */
478 for (i = 0; i < max_num_caldacs; i++)
479 cal2_bits |= DESELECT_CALDAC_BIT(i);
480 /* activate the caldac we want */
481 cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
482 outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
483 /* deactivate caldac */
484 cal2_bits |= DESELECT_CALDAC_BIT(caldac);
485 outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
488 /* returns caldac that calibrates given analog out channel */
489 static unsigned int caldac_number(unsigned int channel)
494 /* returns caldac channel that provides fine gain for given ao channel */
495 static unsigned int fine_gain_channel(unsigned int ao_channel)
497 return 4 * (ao_channel % 2);
500 /* returns caldac channel that provides coarse gain for given ao channel */
501 static unsigned int coarse_gain_channel(unsigned int ao_channel)
503 return 1 + 4 * (ao_channel % 2);
506 /* returns caldac channel that provides coarse offset for given ao channel */
507 static unsigned int coarse_offset_channel(unsigned int ao_channel)
509 return 2 + 4 * (ao_channel % 2);
512 /* returns caldac channel that provides fine offset for given ao channel */
513 static unsigned int fine_offset_channel(unsigned int ao_channel)
515 return 3 + 4 * (ao_channel % 2);
518 /* returns eeprom address that provides offset for given ao channel and range */
519 static unsigned int offset_eeprom_address(unsigned int ao_channel,
522 return 0x7 + 2 * range + 12 * ao_channel;
526 * returns eeprom address that provides gain calibration for given ao
529 static unsigned int gain_eeprom_address(unsigned int ao_channel,
532 return 0x8 + 2 * range + 12 * ao_channel;
536 * returns upper byte of eeprom entry, which gives the coarse adjustment
539 static unsigned int eeprom_coarse_byte(unsigned int word)
541 return (word >> 8) & 0xff;
544 /* returns lower byte of eeprom entry, which gives the fine adjustment values */
545 static unsigned int eeprom_fine_byte(unsigned int word)
550 /* set caldacs to eeprom values for given channel and range */
551 static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
554 struct cb_pcidda_private *devpriv = dev->private;
555 unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain;
557 /* remember range so we can tell when we need to readjust calibration */
558 devpriv->ao_range[channel] = range;
560 /* get values from eeprom data */
562 eeprom_coarse_byte(devpriv->eeprom_data
563 [offset_eeprom_address(channel, range)]);
565 eeprom_fine_byte(devpriv->eeprom_data
566 [offset_eeprom_address(channel, range)]);
568 eeprom_coarse_byte(devpriv->eeprom_data
569 [gain_eeprom_address(channel, range)]);
571 eeprom_fine_byte(devpriv->eeprom_data
572 [gain_eeprom_address(channel, range)]);
575 cb_pcidda_write_caldac(dev, caldac_number(channel),
576 coarse_offset_channel(channel), coarse_offset);
577 cb_pcidda_write_caldac(dev, caldac_number(channel),
578 fine_offset_channel(channel), fine_offset);
579 cb_pcidda_write_caldac(dev, caldac_number(channel),
580 coarse_gain_channel(channel), coarse_gain);
581 cb_pcidda_write_caldac(dev, caldac_number(channel),
582 fine_gain_channel(channel), fine_gain);
585 static int cb_pcidda_ao_winsn(struct comedi_device *dev,
586 struct comedi_subdevice *s,
587 struct comedi_insn *insn, unsigned int *data)
589 struct cb_pcidda_private *devpriv = dev->private;
590 unsigned int command;
591 unsigned int channel, range;
593 channel = CR_CHAN(insn->chanspec);
594 range = CR_RANGE(insn->chanspec);
596 /* adjust calibration dacs if range has changed */
597 if (range != devpriv->ao_range[channel])
598 cb_pcidda_calibrate(dev, channel, range);
600 /* output channel configuration */
601 command = NOSU | ENABLEDAC;
603 /* output channel range */
606 command |= BIP | RANGE10V;
609 command |= BIP | RANGE5V;
612 command |= BIP | RANGE2V5;
615 command |= UNIP | RANGE10V;
618 command |= UNIP | RANGE5V;
621 command |= UNIP | RANGE2V5;
625 /* output channel specification */
626 command |= channel << 2;
627 outw(command, devpriv->dac + DACONTROL);
630 outw(data[0], devpriv->dac + DADATA + channel * 2);
632 /* return the number of samples read/written */
636 static const void *cb_pcidda_find_boardinfo(struct comedi_device *dev,
637 struct pci_dev *pcidev)
639 const struct cb_pcidda_board *thisboard;
642 for (i = 0; i < ARRAY_SIZE(cb_pcidda_boards); i++) {
643 thisboard = &cb_pcidda_boards[i];
644 if (thisboard->device_id != pcidev->device)
650 static int cb_pcidda_attach_pci(struct comedi_device *dev,
651 struct pci_dev *pcidev)
653 const struct cb_pcidda_board *thisboard;
654 struct cb_pcidda_private *devpriv;
655 struct comedi_subdevice *s;
659 thisboard = cb_pcidda_find_boardinfo(dev, pcidev);
662 dev->board_ptr = thisboard;
663 dev->board_name = thisboard->name;
665 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
668 dev->private = devpriv;
670 ret = comedi_pci_enable(pcidev, dev->board_name);
674 devpriv->digitalio = pci_resource_start(pcidev, 2);
675 devpriv->dac = pci_resource_start(pcidev, 3);
676 dev->iobase = devpriv->dac;
678 if (thisboard->status == 2)
680 ("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. "
681 "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. "
682 "PLEASE REPORT USAGE TO <ivanmr@altavista.com>.\n");
684 ret = comedi_alloc_subdevices(dev, 3);
688 s = &dev->subdevices[0];
689 /* analog output subdevice */
690 s->type = COMEDI_SUBD_AO;
691 s->subdev_flags = SDF_WRITABLE;
692 s->n_chan = thisboard->ao_chans;
693 s->maxdata = (1 << thisboard->ao_bits) - 1;
694 s->range_table = thisboard->ranges;
695 s->insn_write = cb_pcidda_ao_winsn;
697 /* s->subdev_flags |= SDF_CMD_READ; */
698 /* s->do_cmd = cb_pcidda_ai_cmd; */
699 /* s->do_cmdtest = cb_pcidda_ai_cmdtest; */
701 /* two 8255 digital io subdevices */
702 s = &dev->subdevices[1];
703 subdev_8255_init(dev, s, NULL, devpriv->digitalio);
704 s = &dev->subdevices[2];
705 subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A);
707 dev_dbg(dev->class_dev, "eeprom:\n");
708 for (index = 0; index < EEPROM_SIZE; index++) {
709 devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index);
710 dev_dbg(dev->class_dev, "%i:0x%x\n", index,
711 devpriv->eeprom_data[index]);
714 /* set calibrations dacs */
715 for (index = 0; index < thisboard->ao_chans; index++)
716 cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]);
718 dev_info(dev->class_dev, "%s attached\n", dev->board_name);
723 static void cb_pcidda_detach(struct comedi_device *dev)
725 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
727 if (dev->subdevices) {
728 subdev_8255_cleanup(dev, &dev->subdevices[1]);
729 subdev_8255_cleanup(dev, &dev->subdevices[2]);
733 comedi_pci_disable(pcidev);
737 static struct comedi_driver cb_pcidda_driver = {
738 .driver_name = "cb_pcidda",
739 .module = THIS_MODULE,
740 .attach_pci = cb_pcidda_attach_pci,
741 .detach = cb_pcidda_detach,
744 static int __devinit cb_pcidda_pci_probe(struct pci_dev *dev,
745 const struct pci_device_id *ent)
747 return comedi_pci_auto_config(dev, &cb_pcidda_driver);
750 static void __devexit cb_pcidda_pci_remove(struct pci_dev *dev)
752 comedi_pci_auto_unconfig(dev);
755 static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = {
756 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0020) },
757 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0021) },
758 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0022) },
759 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0023) },
760 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0024) },
761 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0025) },
764 MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
766 static struct pci_driver cb_pcidda_pci_driver = {
768 .id_table = cb_pcidda_pci_table,
769 .probe = cb_pcidda_pci_probe,
770 .remove = __devexit_p(cb_pcidda_pci_remove),
772 module_comedi_pci_driver(cb_pcidda_driver, cb_pcidda_pci_driver);
774 MODULE_AUTHOR("Comedi http://www.comedi.org");
775 MODULE_DESCRIPTION("Comedi low-level driver");
776 MODULE_LICENSE("GPL");