linux/drivers/staging/comedi/drivers/ni_mio_cs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Comedi driver for NI PCMCIA MIO E series cards
   4 *
   5 * COMEDI - Linux Control and Measurement Device Interface
   6 * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
   7 */
   8
   9/*
  10 * Driver: ni_mio_cs
  11 * Description: National Instruments DAQCard E series
  12 * Author: ds
  13 * Status: works
  14 * Devices: [National Instruments] DAQCard-AI-16XE-50 (ni_mio_cs),
  15 *   DAQCard-AI-16E-4, DAQCard-6062E, DAQCard-6024E, DAQCard-6036E
  16 * Updated: Thu Oct 23 19:43:17 CDT 2003
  17 *
  18 * See the notes in the ni_atmio.o driver.
  19 */
  20
  21/*
  22 * The real guts of the driver is in ni_mio_common.c, which is
  23 * included by all the E series drivers.
  24 *
  25 * References for specifications:
  26 *      341080a.pdf  DAQCard E Series Register Level Programmer Manual
  27 */
  28
  29#include <linux/module.h>
  30#include <linux/delay.h>
  31
  32#include "../comedi_pcmcia.h"
  33#include "ni_stc.h"
  34#include "8255.h"
  35
  36/*
  37 *  AT specific setup
  38 */
  39
  40static const struct ni_board_struct ni_boards[] = {
  41        {
  42                .name           = "DAQCard-ai-16xe-50",
  43                .device_id      = 0x010d,
  44                .n_adchan       = 16,
  45                .ai_maxdata     = 0xffff,
  46                .ai_fifo_depth  = 1024,
  47                .gainlkup       = ai_gain_8,
  48                .ai_speed       = 5000,
  49                .caldac         = { dac8800, dac8043 },
  50        }, {
  51                .name           = "DAQCard-ai-16e-4",
  52                .device_id      = 0x010c,
  53                .n_adchan       = 16,
  54                .ai_maxdata     = 0x0fff,
  55                .ai_fifo_depth  = 1024,
  56                .gainlkup       = ai_gain_16,
  57                .ai_speed       = 4000,
  58                .caldac         = { mb88341 },          /* verified */
  59        }, {
  60                .name           = "DAQCard-6062E",
  61                .device_id      = 0x02c4,
  62                .n_adchan       = 16,
  63                .ai_maxdata     = 0x0fff,
  64                .ai_fifo_depth  = 8192,
  65                .gainlkup       = ai_gain_16,
  66                .ai_speed       = 2000,
  67                .n_aochan       = 2,
  68                .ao_maxdata     = 0x0fff,
  69                .ao_fifo_depth  = 2048,
  70                .ao_range_table = &range_bipolar10,
  71                .ao_speed       = 1176,
  72                .caldac         = { ad8804_debug },     /* verified */
  73         }, {
  74                /* specs incorrect! */
  75                .name           = "DAQCard-6024E",
  76                .device_id      = 0x075e,
  77                .n_adchan       = 16,
  78                .ai_maxdata     = 0x0fff,
  79                .ai_fifo_depth  = 1024,
  80                .gainlkup       = ai_gain_4,
  81                .ai_speed       = 5000,
  82                .n_aochan       = 2,
  83                .ao_maxdata     = 0x0fff,
  84                .ao_range_table = &range_bipolar10,
  85                .ao_speed       = 1000000,
  86                .caldac         = { ad8804_debug },
  87        }, {
  88                /* specs incorrect! */
  89                .name           = "DAQCard-6036E",
  90                .device_id      = 0x0245,
  91                .n_adchan       = 16,
  92                .ai_maxdata     = 0xffff,
  93                .ai_fifo_depth  = 1024,
  94                .alwaysdither   = 1,
  95                .gainlkup       = ai_gain_4,
  96                .ai_speed       = 5000,
  97                .n_aochan       = 2,
  98                .ao_maxdata     = 0xffff,
  99                .ao_range_table = &range_bipolar10,
 100                .ao_speed       = 1000000,
 101                .caldac         = { ad8804_debug },
 102         },
 103#if 0
 104        {
 105                .name           = "DAQCard-6715",
 106                .device_id      = 0x0000,       /* unknown */
 107                .n_aochan       = 8,
 108                .ao_maxdata     = 0x0fff,
 109                .ao_671x        = 8192,
 110                .caldac         = { mb88341, mb88341 },
 111        },
 112#endif
 113};
 114
 115#include "ni_mio_common.c"
 116
 117static const void *ni_getboardtype(struct comedi_device *dev,
 118                                   struct pcmcia_device *link)
 119{
 120        static const struct ni_board_struct *board;
 121        int i;
 122
 123        for (i = 0; i < ARRAY_SIZE(ni_boards); i++) {
 124                board = &ni_boards[i];
 125                if (board->device_id == link->card_id)
 126                        return board;
 127        }
 128        return NULL;
 129}
 130
 131static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data)
 132{
 133        int base, ret;
 134
 135        p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
 136        p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
 137
 138        for (base = 0x000; base < 0x400; base += 0x20) {
 139                p_dev->resource[0]->start = base;
 140                ret = pcmcia_request_io(p_dev);
 141                if (!ret)
 142                        return 0;
 143        }
 144        return -ENODEV;
 145}
 146
 147static int mio_cs_auto_attach(struct comedi_device *dev,
 148                              unsigned long context)
 149{
 150        struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
 151        static const struct ni_board_struct *board;
 152        int ret;
 153
 154        board = ni_getboardtype(dev, link);
 155        if (!board)
 156                return -ENODEV;
 157        dev->board_ptr = board;
 158        dev->board_name = board->name;
 159
 160        link->config_flags |= CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
 161        ret = comedi_pcmcia_enable(dev, mio_pcmcia_config_loop);
 162        if (ret)
 163                return ret;
 164        dev->iobase = link->resource[0]->start;
 165
 166        link->priv = dev;
 167        ret = pcmcia_request_irq(link, ni_E_interrupt);
 168        if (ret)
 169                return ret;
 170        dev->irq = link->irq;
 171
 172        ret = ni_alloc_private(dev);
 173        if (ret)
 174                return ret;
 175
 176        return ni_E_init(dev, 0, 1);
 177}
 178
 179static void mio_cs_detach(struct comedi_device *dev)
 180{
 181        mio_common_detach(dev);
 182        comedi_pcmcia_disable(dev);
 183}
 184
 185static struct comedi_driver driver_ni_mio_cs = {
 186        .driver_name    = "ni_mio_cs",
 187        .module         = THIS_MODULE,
 188        .auto_attach    = mio_cs_auto_attach,
 189        .detach         = mio_cs_detach,
 190};
 191
 192static int cs_attach(struct pcmcia_device *link)
 193{
 194        return comedi_pcmcia_auto_config(link, &driver_ni_mio_cs);
 195}
 196
 197static const struct pcmcia_device_id ni_mio_cs_ids[] = {
 198        PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010d),        /* DAQCard-ai-16xe-50 */
 199        PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010c),        /* DAQCard-ai-16e-4 */
 200        PCMCIA_DEVICE_MANF_CARD(0x010b, 0x02c4),        /* DAQCard-6062E */
 201        PCMCIA_DEVICE_MANF_CARD(0x010b, 0x075e),        /* DAQCard-6024E */
 202        PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0245),        /* DAQCard-6036E */
 203        PCMCIA_DEVICE_NULL
 204};
 205MODULE_DEVICE_TABLE(pcmcia, ni_mio_cs_ids);
 206
 207static struct pcmcia_driver ni_mio_cs_driver = {
 208        .name           = "ni_mio_cs",
 209        .owner          = THIS_MODULE,
 210        .id_table       = ni_mio_cs_ids,
 211        .probe          = cs_attach,
 212        .remove         = comedi_pcmcia_auto_unconfig,
 213};
 214module_comedi_pcmcia_driver(driver_ni_mio_cs, ni_mio_cs_driver);
 215
 216MODULE_DESCRIPTION("Comedi driver for National Instruments DAQCard E series");
 217MODULE_AUTHOR("David A. Schleef <ds@schleef.org>");
 218MODULE_LICENSE("GPL");
 219