linux/drivers/staging/comedi/drivers/cb_pcidda.c
<<
>>
Prefs
   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 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
 114static 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 */
 131struct 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
 147static 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
 198static 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
 208MODULE_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.  */
 218struct 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
 241static int cb_pcidda_attach(struct comedi_device *dev,
 242                            struct comedi_devconfig *it);
 243static 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); */
 245static 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
 253static unsigned int cb_pcidda_serial_in(struct comedi_device *dev);
 254static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
 255                                 unsigned int num_bits);
 256static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
 257                                          unsigned int address);
 258static 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 */
 267static 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 */
 278static 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        printk("comedi%d: cb_pcidda: ", dev->minor);
 286
 287/*
 288 * Allocate the private structure area.
 289 */
 290        if (alloc_private(dev, sizeof(struct cb_pcidda_private)) < 0)
 291                return -ENOMEM;
 292
 293/*
 294 * Probe the device to determine what device in the series it is.
 295 */
 296        printk("\n");
 297
 298        for_each_pci_dev(pcidev) {
 299                if (pcidev->vendor == PCI_VENDOR_ID_CB) {
 300                        if (it->options[0] || it->options[1]) {
 301                                if (pcidev->bus->number != it->options[0] ||
 302                                    PCI_SLOT(pcidev->devfn) != it->options[1]) {
 303                                        continue;
 304                                }
 305                        }
 306                        for (index = 0; index < ARRAY_SIZE(cb_pcidda_boards); index++) {
 307                                if (cb_pcidda_boards[index].device_id ==
 308                                    pcidev->device) {
 309                                        goto found;
 310                                }
 311                        }
 312                }
 313        }
 314        if (!pcidev) {
 315                printk
 316                    ("Not a ComputerBoards/MeasurementComputing card on requested position\n");
 317                return -EIO;
 318        }
 319found:
 320        devpriv->pci_dev = pcidev;
 321        dev->board_ptr = cb_pcidda_boards + index;
 322        /*  "thisboard" macro can be used from here. */
 323        printk("Found %s at requested position\n", thisboard->name);
 324
 325        /*
 326         * Enable PCI device and request regions.
 327         */
 328        if (comedi_pci_enable(pcidev, thisboard->name)) {
 329                printk
 330                    ("cb_pcidda: failed to enable PCI device and request regions\n");
 331                return -EIO;
 332        }
 333
 334/*
 335 * Allocate the I/O ports.
 336 */
 337        devpriv->digitalio =
 338            pci_resource_start(devpriv->pci_dev, DIGITALIO_BADRINDEX);
 339        devpriv->dac = pci_resource_start(devpriv->pci_dev, DAC_BADRINDEX);
 340
 341/*
 342 * Warn about the status of the driver.
 343 */
 344        if (thisboard->status == 2)
 345                printk
 346                    ("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. "
 347                     "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. "
 348                     "PLEASE REPORT USAGE TO <ivanmr@altavista.com>.\n");
 349
 350/*
 351 * Initialize dev->board_name.
 352 */
 353        dev->board_name = thisboard->name;
 354
 355/*
 356 * Allocate the subdevice structures.
 357 */
 358        if (alloc_subdevices(dev, 3) < 0)
 359                return -ENOMEM;
 360
 361        s = dev->subdevices + 0;
 362        /* analog output subdevice */
 363        s->type = COMEDI_SUBD_AO;
 364        s->subdev_flags = SDF_WRITABLE;
 365        s->n_chan = thisboard->ao_chans;
 366        s->maxdata = (1 << thisboard->ao_bits) - 1;
 367        s->range_table = thisboard->ranges;
 368        s->insn_write = cb_pcidda_ao_winsn;
 369
 370        /* s->subdev_flags |= SDF_CMD_READ; */
 371        /* s->do_cmd = cb_pcidda_ai_cmd; */
 372        /* s->do_cmdtest = cb_pcidda_ai_cmdtest; */
 373
 374        /*  two 8255 digital io subdevices */
 375        s = dev->subdevices + 1;
 376        subdev_8255_init(dev, s, NULL, devpriv->digitalio);
 377        s = dev->subdevices + 2;
 378        subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A);
 379
 380        printk(" eeprom:");
 381        for (index = 0; index < EEPROM_SIZE; index++) {
 382                devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index);
 383                printk(" %i:0x%x ", index, devpriv->eeprom_data[index]);
 384        }
 385        printk("\n");
 386
 387        /*  set calibrations dacs */
 388        for (index = 0; index < thisboard->ao_chans; index++)
 389                cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]);
 390
 391        return 1;
 392}
 393
 394/*
 395 * _detach is called to deconfigure a device.  It should deallocate
 396 * resources.
 397 * This function is also called when _attach() fails, so it should be
 398 * careful not to release resources that were not necessarily
 399 * allocated by _attach().  dev->private and dev->subdevices are
 400 * deallocated automatically by the core.
 401 */
 402static int cb_pcidda_detach(struct comedi_device *dev)
 403{
 404/*
 405 * Deallocate the I/O ports.
 406 */
 407        if (devpriv) {
 408                if (devpriv->pci_dev) {
 409                        if (devpriv->dac)
 410                                comedi_pci_disable(devpriv->pci_dev);
 411                        pci_dev_put(devpriv->pci_dev);
 412                }
 413        }
 414        /*  cleanup 8255 */
 415        if (dev->subdevices) {
 416                subdev_8255_cleanup(dev, dev->subdevices + 1);
 417                subdev_8255_cleanup(dev, dev->subdevices + 2);
 418        }
 419
 420        printk("comedi%d: cb_pcidda: remove\n", dev->minor);
 421
 422        return 0;
 423}
 424
 425/*
 426 * I will program this later... ;-)
 427 */
 428#if 0
 429static int cb_pcidda_ai_cmd(struct comedi_device *dev,
 430                            struct comedi_subdevice *s)
 431{
 432        printk("cb_pcidda_ai_cmd\n");
 433        printk("subdev: %d\n", cmd->subdev);
 434        printk("flags: %d\n", cmd->flags);
 435        printk("start_src: %d\n", cmd->start_src);
 436        printk("start_arg: %d\n", cmd->start_arg);
 437        printk("scan_begin_src: %d\n", cmd->scan_begin_src);
 438        printk("convert_src: %d\n", cmd->convert_src);
 439        printk("convert_arg: %d\n", cmd->convert_arg);
 440        printk("scan_end_src: %d\n", cmd->scan_end_src);
 441        printk("scan_end_arg: %d\n", cmd->scan_end_arg);
 442        printk("stop_src: %d\n", cmd->stop_src);
 443        printk("stop_arg: %d\n", cmd->stop_arg);
 444        printk("chanlist_len: %d\n", cmd->chanlist_len);
 445}
 446#endif
 447
 448#if 0
 449static int cb_pcidda_ai_cmdtest(struct comedi_device *dev,
 450                                struct comedi_subdevice *s,
 451                                struct comedi_cmd *cmd)
 452{
 453        int err = 0;
 454        int tmp;
 455
 456        /* cmdtest tests a particular command to see if it is valid.
 457         * Using the cmdtest ioctl, a user can create a valid cmd
 458         * and then have it executes by the cmd ioctl.
 459         *
 460         * cmdtest returns 1,2,3,4 or 0, depending on which tests
 461         * the command passes. */
 462
 463        /* step 1: make sure trigger sources are trivially valid */
 464
 465        tmp = cmd->start_src;
 466        cmd->start_src &= TRIG_NOW;
 467        if (!cmd->start_src || tmp != cmd->start_src)
 468                err++;
 469
 470        tmp = cmd->scan_begin_src;
 471        cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
 472        if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
 473                err++;
 474
 475        tmp = cmd->convert_src;
 476        cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
 477        if (!cmd->convert_src || tmp != cmd->convert_src)
 478                err++;
 479
 480        tmp = cmd->scan_end_src;
 481        cmd->scan_end_src &= TRIG_COUNT;
 482        if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
 483                err++;
 484
 485        tmp = cmd->stop_src;
 486        cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
 487        if (!cmd->stop_src || tmp != cmd->stop_src)
 488                err++;
 489
 490        if (err)
 491                return 1;
 492
 493        /* step 2: make sure trigger sources are unique and mutually compatible */
 494
 495        /* note that mutual compatibility is not an issue here */
 496        if (cmd->scan_begin_src != TRIG_TIMER
 497            && cmd->scan_begin_src != TRIG_EXT)
 498                err++;
 499        if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
 500                err++;
 501        if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT)
 502                err++;
 503
 504        if (err)
 505                return 2;
 506
 507        /* step 3: make sure arguments are trivially compatible */
 508
 509        if (cmd->start_arg != 0) {
 510                cmd->start_arg = 0;
 511                err++;
 512        }
 513#define MAX_SPEED       10000   /* in nanoseconds */
 514#define MIN_SPEED       1000000000      /* in nanoseconds */
 515
 516        if (cmd->scan_begin_src == TRIG_TIMER) {
 517                if (cmd->scan_begin_arg < MAX_SPEED) {
 518                        cmd->scan_begin_arg = MAX_SPEED;
 519                        err++;
 520                }
 521                if (cmd->scan_begin_arg > MIN_SPEED) {
 522                        cmd->scan_begin_arg = MIN_SPEED;
 523                        err++;
 524                }
 525        } else {
 526                /* external trigger */
 527                /* should be level/edge, hi/lo specification here */
 528                /* should specify multiple external triggers */
 529                if (cmd->scan_begin_arg > 9) {
 530                        cmd->scan_begin_arg = 9;
 531                        err++;
 532                }
 533        }
 534        if (cmd->convert_src == TRIG_TIMER) {
 535                if (cmd->convert_arg < MAX_SPEED) {
 536                        cmd->convert_arg = MAX_SPEED;
 537                        err++;
 538                }
 539                if (cmd->convert_arg > MIN_SPEED) {
 540                        cmd->convert_arg = MIN_SPEED;
 541                        err++;
 542                }
 543        } else {
 544                /* external trigger */
 545                /* see above */
 546                if (cmd->convert_arg > 9) {
 547                        cmd->convert_arg = 9;
 548                        err++;
 549                }
 550        }
 551
 552        if (cmd->scan_end_arg != cmd->chanlist_len) {
 553                cmd->scan_end_arg = cmd->chanlist_len;
 554                err++;
 555        }
 556        if (cmd->stop_src == TRIG_COUNT) {
 557                if (cmd->stop_arg > 0x00ffffff) {
 558                        cmd->stop_arg = 0x00ffffff;
 559                        err++;
 560                }
 561        } else {
 562                /* TRIG_NONE */
 563                if (cmd->stop_arg != 0) {
 564                        cmd->stop_arg = 0;
 565                        err++;
 566                }
 567        }
 568
 569        if (err)
 570                return 3;
 571
 572        /* step 4: fix up any arguments */
 573
 574        if (cmd->scan_begin_src == TRIG_TIMER) {
 575                tmp = cmd->scan_begin_arg;
 576                cb_pcidda_ns_to_timer(&cmd->scan_begin_arg,
 577                                      cmd->flags & TRIG_ROUND_MASK);
 578                if (tmp != cmd->scan_begin_arg)
 579                        err++;
 580        }
 581        if (cmd->convert_src == TRIG_TIMER) {
 582                tmp = cmd->convert_arg;
 583                cb_pcidda_ns_to_timer(&cmd->convert_arg,
 584                                      cmd->flags & TRIG_ROUND_MASK);
 585                if (tmp != cmd->convert_arg)
 586                        err++;
 587                if (cmd->scan_begin_src == TRIG_TIMER &&
 588                    cmd->scan_begin_arg <
 589                    cmd->convert_arg * cmd->scan_end_arg) {
 590                        cmd->scan_begin_arg =
 591                            cmd->convert_arg * cmd->scan_end_arg;
 592                        err++;
 593                }
 594        }
 595
 596        if (err)
 597                return 4;
 598
 599        return 0;
 600}
 601#endif
 602
 603/* This function doesn't require a particular form, this is just
 604 * what happens to be used in some of the drivers.  It should
 605 * convert ns nanoseconds to a counter value suitable for programming
 606 * the device.  Also, it should adjust ns so that it cooresponds to
 607 * the actual time that the device will use. */
 608#if 0
 609static int cb_pcidda_ns_to_timer(unsigned int *ns, int round)
 610{
 611        /* trivial timer */
 612        return *ns;
 613}
 614#endif
 615
 616static int cb_pcidda_ao_winsn(struct comedi_device *dev,
 617                              struct comedi_subdevice *s,
 618                              struct comedi_insn *insn, unsigned int *data)
 619{
 620        unsigned int command;
 621        unsigned int channel, range;
 622
 623        channel = CR_CHAN(insn->chanspec);
 624        range = CR_RANGE(insn->chanspec);
 625
 626        /*  adjust calibration dacs if range has changed */
 627        if (range != devpriv->ao_range[channel])
 628                cb_pcidda_calibrate(dev, channel, range);
 629
 630        /* output channel configuration */
 631        command = NOSU | ENABLEDAC;
 632
 633        /* output channel range */
 634        switch (range) {
 635        case 0:
 636                command |= BIP | RANGE10V;
 637                break;
 638        case 1:
 639                command |= BIP | RANGE5V;
 640                break;
 641        case 2:
 642                command |= BIP | RANGE2V5;
 643                break;
 644        case 3:
 645                command |= UNIP | RANGE10V;
 646                break;
 647        case 4:
 648                command |= UNIP | RANGE5V;
 649                break;
 650        case 5:
 651                command |= UNIP | RANGE2V5;
 652                break;
 653        }
 654
 655        /* output channel specification */
 656        command |= channel << 2;
 657        outw(command, devpriv->dac + DACONTROL);
 658
 659        /* write data */
 660        outw(data[0], devpriv->dac + DADATA + channel * 2);
 661
 662        /* return the number of samples read/written */
 663        return 1;
 664}
 665
 666/* lowlevel read from eeprom */
 667static unsigned int cb_pcidda_serial_in(struct comedi_device *dev)
 668{
 669        unsigned int value = 0;
 670        int i;
 671        const int value_width = 16;     /*  number of bits wide values are */
 672
 673        for (i = 1; i <= value_width; i++) {
 674                /*  read bits most significant bit first */
 675                if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT)
 676                        value |= 1 << (value_width - i);
 677        }
 678
 679        return value;
 680}
 681
 682/* lowlevel write to eeprom/dac */
 683static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
 684                                 unsigned int num_bits)
 685{
 686        int i;
 687
 688        for (i = 1; i <= num_bits; i++) {
 689                /*  send bits most significant bit first */
 690                if (value & (1 << (num_bits - i)))
 691                        devpriv->dac_cal1_bits |= SERIAL_IN_BIT;
 692                else
 693                        devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT;
 694                outw_p(devpriv->dac_cal1_bits, devpriv->dac + DACALIBRATION1);
 695        }
 696}
 697
 698/* reads a 16 bit value from board's eeprom */
 699static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
 700                                          unsigned int address)
 701{
 702        unsigned int i;
 703        unsigned int cal2_bits;
 704        unsigned int value;
 705        const int max_num_caldacs = 4;  /*  one caldac for every two dac channels */
 706        const int read_instruction = 0x6;       /*  bits to send to tell eeprom we want to read */
 707        const int instruction_length = 3;
 708        const int address_length = 8;
 709
 710        /*  send serial output stream to eeprom */
 711        cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
 712        /*  deactivate caldacs (one caldac for every two channels) */
 713        for (i = 0; i < max_num_caldacs; i++)
 714                cal2_bits |= DESELECT_CALDAC_BIT(i);
 715        outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
 716
 717        /*  tell eeprom we want to read */
 718        cb_pcidda_serial_out(dev, read_instruction, instruction_length);
 719        /*  send address we want to read from */
 720        cb_pcidda_serial_out(dev, address, address_length);
 721
 722        value = cb_pcidda_serial_in(dev);
 723
 724        /*  deactivate eeprom */
 725        cal2_bits &= ~SELECT_EEPROM_BIT;
 726        outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
 727
 728        return value;
 729}
 730
 731/* writes to 8 bit calibration dacs */
 732static void cb_pcidda_write_caldac(struct comedi_device *dev,
 733                                   unsigned int caldac, unsigned int channel,
 734                                   unsigned int value)
 735{
 736        unsigned int cal2_bits;
 737        unsigned int i;
 738        const int num_channel_bits = 3; /*  caldacs use 3 bit channel specification */
 739        const int num_caldac_bits = 8;  /*  8 bit calibration dacs */
 740        const int max_num_caldacs = 4;  /*  one caldac for every two dac channels */
 741
 742        /* write 3 bit channel */
 743        cb_pcidda_serial_out(dev, channel, num_channel_bits);
 744        /*  write 8 bit caldac value */
 745        cb_pcidda_serial_out(dev, value, num_caldac_bits);
 746
 747/*
 748* latch stream into appropriate caldac deselect reference dac
 749*/
 750        cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
 751        /*  deactivate caldacs (one caldac for every two channels) */
 752        for (i = 0; i < max_num_caldacs; i++)
 753                cal2_bits |= DESELECT_CALDAC_BIT(i);
 754        /*  activate the caldac we want */
 755        cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
 756        outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
 757        /*  deactivate caldac */
 758        cal2_bits |= DESELECT_CALDAC_BIT(caldac);
 759        outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
 760}
 761
 762/* returns caldac that calibrates given analog out channel */
 763static unsigned int caldac_number(unsigned int channel)
 764{
 765        return channel / 2;
 766}
 767
 768/* returns caldac channel that provides fine gain for given ao channel */
 769static unsigned int fine_gain_channel(unsigned int ao_channel)
 770{
 771        return 4 * (ao_channel % 2);
 772}
 773
 774/* returns caldac channel that provides coarse gain for given ao channel */
 775static unsigned int coarse_gain_channel(unsigned int ao_channel)
 776{
 777        return 1 + 4 * (ao_channel % 2);
 778}
 779
 780/* returns caldac channel that provides coarse offset for given ao channel */
 781static unsigned int coarse_offset_channel(unsigned int ao_channel)
 782{
 783        return 2 + 4 * (ao_channel % 2);
 784}
 785
 786/* returns caldac channel that provides fine offset for given ao channel */
 787static unsigned int fine_offset_channel(unsigned int ao_channel)
 788{
 789        return 3 + 4 * (ao_channel % 2);
 790}
 791
 792/* returns eeprom address that provides offset for given ao channel and range */
 793static unsigned int offset_eeprom_address(unsigned int ao_channel,
 794                                          unsigned int range)
 795{
 796        return 0x7 + 2 * range + 12 * ao_channel;
 797}
 798
 799/* returns eeprom address that provides gain calibration for given ao channel and range */
 800static unsigned int gain_eeprom_address(unsigned int ao_channel,
 801                                        unsigned int range)
 802{
 803        return 0x8 + 2 * range + 12 * ao_channel;
 804}
 805
 806/* returns upper byte of eeprom entry, which gives the coarse adjustment values */
 807static unsigned int eeprom_coarse_byte(unsigned int word)
 808{
 809        return (word >> 8) & 0xff;
 810}
 811
 812/* returns lower byte of eeprom entry, which gives the fine adjustment values */
 813static unsigned int eeprom_fine_byte(unsigned int word)
 814{
 815        return word & 0xff;
 816}
 817
 818/* set caldacs to eeprom values for given channel and range */
 819static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
 820                                unsigned int range)
 821{
 822        unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain;
 823
 824        /*  remember range so we can tell when we need to readjust calibration */
 825        devpriv->ao_range[channel] = range;
 826
 827        /*  get values from eeprom data */
 828        coarse_offset =
 829            eeprom_coarse_byte(devpriv->eeprom_data
 830                               [offset_eeprom_address(channel, range)]);
 831        fine_offset =
 832            eeprom_fine_byte(devpriv->eeprom_data
 833                             [offset_eeprom_address(channel, range)]);
 834        coarse_gain =
 835            eeprom_coarse_byte(devpriv->eeprom_data
 836                               [gain_eeprom_address(channel, range)]);
 837        fine_gain =
 838            eeprom_fine_byte(devpriv->eeprom_data
 839                             [gain_eeprom_address(channel, range)]);
 840
 841        /*  set caldacs */
 842        cb_pcidda_write_caldac(dev, caldac_number(channel),
 843                               coarse_offset_channel(channel), coarse_offset);
 844        cb_pcidda_write_caldac(dev, caldac_number(channel),
 845                               fine_offset_channel(channel), fine_offset);
 846        cb_pcidda_write_caldac(dev, caldac_number(channel),
 847                               coarse_gain_channel(channel), coarse_gain);
 848        cb_pcidda_write_caldac(dev, caldac_number(channel),
 849                               fine_gain_channel(channel), fine_gain);
 850}
 851
 852/*
 853 * A convenient macro that defines init_module() and cleanup_module(),
 854 * as necessary.
 855 */
 856static int __devinit driver_cb_pcidda_pci_probe(struct pci_dev *dev,
 857                                                const struct pci_device_id *ent)
 858{
 859        return comedi_pci_auto_config(dev, driver_cb_pcidda.driver_name);
 860}
 861
 862static void __devexit driver_cb_pcidda_pci_remove(struct pci_dev *dev)
 863{
 864        comedi_pci_auto_unconfig(dev);
 865}
 866
 867static struct pci_driver driver_cb_pcidda_pci_driver = {
 868        .id_table = cb_pcidda_pci_table,
 869        .probe = &driver_cb_pcidda_pci_probe,
 870        .remove = __devexit_p(&driver_cb_pcidda_pci_remove)
 871};
 872
 873static int __init driver_cb_pcidda_init_module(void)
 874{
 875        int retval;
 876
 877        retval = comedi_driver_register(&driver_cb_pcidda);
 878        if (retval < 0)
 879                return retval;
 880
 881        driver_cb_pcidda_pci_driver.name = (char *)driver_cb_pcidda.driver_name;
 882        return pci_register_driver(&driver_cb_pcidda_pci_driver);
 883}
 884
 885static void __exit driver_cb_pcidda_cleanup_module(void)
 886{
 887        pci_unregister_driver(&driver_cb_pcidda_pci_driver);
 888        comedi_driver_unregister(&driver_cb_pcidda);
 889}
 890
 891module_init(driver_cb_pcidda_init_module);
 892module_exit(driver_cb_pcidda_cleanup_module);
 893
 894MODULE_AUTHOR("Comedi http://www.comedi.org");
 895MODULE_DESCRIPTION("Comedi low-level driver");
 896MODULE_LICENSE("GPL");
 897