linux/drivers/staging/comedi/drivers/me4000.c
<<
>>
Prefs
   1/*
   2   comedi/drivers/me4000.c
   3   Source code for the Meilhaus ME-4000 board family.
   4
   5   COMEDI - Linux Control and Measurement Device Interface
   6   Copyright (C) 2000 David A. Schleef <ds@schleef.org>
   7
   8   This program is free software; you can redistribute it and/or modify
   9   it under the terms of the GNU General Public License as published by
  10   the Free Software Foundation; either version 2 of the License, or
  11   (at your option) any later version.
  12
  13   This program is distributed in the hope that it will be useful,
  14   but WITHOUT ANY WARRANTY; without even the implied warranty of
  15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16   GNU General Public License for more details.
  17
  18   You should have received a copy of the GNU General Public License
  19   along with this program; if not, write to the Free Software
  20   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21
  22 */
  23/*
  24Driver: me4000
  25Description: Meilhaus ME-4000 series boards
  26Devices: [Meilhaus] ME-4650 (me4000), ME-4670i, ME-4680, ME-4680i, ME-4680is
  27Author: gg (Guenter Gebhardt <g.gebhardt@meilhaus.com>)
  28Updated: Mon, 18 Mar 2002 15:34:01 -0800
  29Status: broken (no support for loading firmware)
  30
  31Supports:
  32
  33    - Analog Input
  34    - Analog Output
  35    - Digital I/O
  36    - Counter
  37
  38Configuration Options: not applicable, uses PCI auto config
  39
  40The firmware required by these boards is available in the
  41comedi_nonfree_firmware tarball available from
  42http://www.comedi.org.  However, the driver's support for
  43loading the firmware through comedi_config is currently
  44broken.
  45
  46 */
  47
  48#include <linux/pci.h>
  49#include <linux/delay.h>
  50#include <linux/interrupt.h>
  51#include <linux/list.h>
  52#include <linux/spinlock.h>
  53
  54#include "../comedidev.h"
  55
  56#include "comedi_fc.h"
  57#include "8253.h"
  58#include "plx9052.h"
  59
  60#if 0
  61/* file removed due to GPL incompatibility */
  62#include "me4000_fw.h"
  63#endif
  64
  65/*
  66 * ME4000 Register map and bit defines
  67 */
  68#define ME4000_AO_CHAN(x)                       ((x) * 0x18)
  69
  70#define ME4000_AO_CTRL_REG(x)                   (0x00 + ME4000_AO_CHAN(x))
  71#define ME4000_AO_CTRL_BIT_MODE_0               (1 << 0)
  72#define ME4000_AO_CTRL_BIT_MODE_1               (1 << 1)
  73#define ME4000_AO_CTRL_MASK_MODE                (3 << 0)
  74#define ME4000_AO_CTRL_BIT_STOP                 (1 << 2)
  75#define ME4000_AO_CTRL_BIT_ENABLE_FIFO          (1 << 3)
  76#define ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG       (1 << 4)
  77#define ME4000_AO_CTRL_BIT_EX_TRIG_EDGE         (1 << 5)
  78#define ME4000_AO_CTRL_BIT_IMMEDIATE_STOP       (1 << 7)
  79#define ME4000_AO_CTRL_BIT_ENABLE_DO            (1 << 8)
  80#define ME4000_AO_CTRL_BIT_ENABLE_IRQ           (1 << 9)
  81#define ME4000_AO_CTRL_BIT_RESET_IRQ            (1 << 10)
  82#define ME4000_AO_STATUS_REG(x)                 (0x04 + ME4000_AO_CHAN(x))
  83#define ME4000_AO_STATUS_BIT_FSM                (1 << 0)
  84#define ME4000_AO_STATUS_BIT_FF                 (1 << 1)
  85#define ME4000_AO_STATUS_BIT_HF                 (1 << 2)
  86#define ME4000_AO_STATUS_BIT_EF                 (1 << 3)
  87#define ME4000_AO_FIFO_REG(x)                   (0x08 + ME4000_AO_CHAN(x))
  88#define ME4000_AO_SINGLE_REG(x)                 (0x0c + ME4000_AO_CHAN(x))
  89#define ME4000_AO_TIMER_REG(x)                  (0x10 + ME4000_AO_CHAN(x))
  90#define ME4000_AI_CTRL_REG                      0x74
  91#define ME4000_AI_STATUS_REG                    0x74
  92#define ME4000_AI_CTRL_BIT_MODE_0               (1 << 0)
  93#define ME4000_AI_CTRL_BIT_MODE_1               (1 << 1)
  94#define ME4000_AI_CTRL_BIT_MODE_2               (1 << 2)
  95#define ME4000_AI_CTRL_BIT_SAMPLE_HOLD          (1 << 3)
  96#define ME4000_AI_CTRL_BIT_IMMEDIATE_STOP       (1 << 4)
  97#define ME4000_AI_CTRL_BIT_STOP                 (1 << 5)
  98#define ME4000_AI_CTRL_BIT_CHANNEL_FIFO         (1 << 6)
  99#define ME4000_AI_CTRL_BIT_DATA_FIFO            (1 << 7)
 100#define ME4000_AI_CTRL_BIT_FULLSCALE            (1 << 8)
 101#define ME4000_AI_CTRL_BIT_OFFSET               (1 << 9)
 102#define ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG       (1 << 10)
 103#define ME4000_AI_CTRL_BIT_EX_TRIG              (1 << 11)
 104#define ME4000_AI_CTRL_BIT_EX_TRIG_FALLING      (1 << 12)
 105#define ME4000_AI_CTRL_BIT_EX_IRQ               (1 << 13)
 106#define ME4000_AI_CTRL_BIT_EX_IRQ_RESET         (1 << 14)
 107#define ME4000_AI_CTRL_BIT_LE_IRQ               (1 << 15)
 108#define ME4000_AI_CTRL_BIT_LE_IRQ_RESET         (1 << 16)
 109#define ME4000_AI_CTRL_BIT_HF_IRQ               (1 << 17)
 110#define ME4000_AI_CTRL_BIT_HF_IRQ_RESET         (1 << 18)
 111#define ME4000_AI_CTRL_BIT_SC_IRQ               (1 << 19)
 112#define ME4000_AI_CTRL_BIT_SC_IRQ_RESET         (1 << 20)
 113#define ME4000_AI_CTRL_BIT_SC_RELOAD            (1 << 21)
 114#define ME4000_AI_STATUS_BIT_EF_CHANNEL         (1 << 22)
 115#define ME4000_AI_STATUS_BIT_HF_CHANNEL         (1 << 23)
 116#define ME4000_AI_STATUS_BIT_FF_CHANNEL         (1 << 24)
 117#define ME4000_AI_STATUS_BIT_EF_DATA            (1 << 25)
 118#define ME4000_AI_STATUS_BIT_HF_DATA            (1 << 26)
 119#define ME4000_AI_STATUS_BIT_FF_DATA            (1 << 27)
 120#define ME4000_AI_STATUS_BIT_LE                 (1 << 28)
 121#define ME4000_AI_STATUS_BIT_FSM                (1 << 29)
 122#define ME4000_AI_CTRL_BIT_EX_TRIG_BOTH         (1 << 31)
 123#define ME4000_AI_CHANNEL_LIST_REG              0x78
 124#define ME4000_AI_LIST_INPUT_SINGLE_ENDED       (0 << 5)
 125#define ME4000_AI_LIST_INPUT_DIFFERENTIAL       (1 << 5)
 126#define ME4000_AI_LIST_RANGE_BIPOLAR_10         (0 << 6)
 127#define ME4000_AI_LIST_RANGE_BIPOLAR_2_5        (1 << 6)
 128#define ME4000_AI_LIST_RANGE_UNIPOLAR_10        (2 << 6)
 129#define ME4000_AI_LIST_RANGE_UNIPOLAR_2_5       (3 << 6)
 130#define ME4000_AI_LIST_LAST_ENTRY               (1 << 8)
 131#define ME4000_AI_DATA_REG                      0x7c
 132#define ME4000_AI_CHAN_TIMER_REG                0x80
 133#define ME4000_AI_CHAN_PRE_TIMER_REG            0x84
 134#define ME4000_AI_SCAN_TIMER_LOW_REG            0x88
 135#define ME4000_AI_SCAN_TIMER_HIGH_REG           0x8c
 136#define ME4000_AI_SCAN_PRE_TIMER_LOW_REG        0x90
 137#define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG       0x94
 138#define ME4000_AI_START_REG                     0x98
 139#define ME4000_IRQ_STATUS_REG                   0x9c
 140#define ME4000_IRQ_STATUS_BIT_EX                (1 << 0)
 141#define ME4000_IRQ_STATUS_BIT_LE                (1 << 1)
 142#define ME4000_IRQ_STATUS_BIT_AI_HF             (1 << 2)
 143#define ME4000_IRQ_STATUS_BIT_AO_0_HF           (1 << 3)
 144#define ME4000_IRQ_STATUS_BIT_AO_1_HF           (1 << 4)
 145#define ME4000_IRQ_STATUS_BIT_AO_2_HF           (1 << 5)
 146#define ME4000_IRQ_STATUS_BIT_AO_3_HF           (1 << 6)
 147#define ME4000_IRQ_STATUS_BIT_SC                (1 << 7)
 148#define ME4000_DIO_PORT_0_REG                   0xa0
 149#define ME4000_DIO_PORT_1_REG                   0xa4
 150#define ME4000_DIO_PORT_2_REG                   0xa8
 151#define ME4000_DIO_PORT_3_REG                   0xac
 152#define ME4000_DIO_DIR_REG                      0xb0
 153#define ME4000_AO_LOADSETREG_XX                 0xb4
 154#define ME4000_DIO_CTRL_REG                     0xb8
 155#define ME4000_DIO_CTRL_BIT_MODE_0              (1 << 0)
 156#define ME4000_DIO_CTRL_BIT_MODE_1              (1 << 1)
 157#define ME4000_DIO_CTRL_BIT_MODE_2              (1 << 2)
 158#define ME4000_DIO_CTRL_BIT_MODE_3              (1 << 3)
 159#define ME4000_DIO_CTRL_BIT_MODE_4              (1 << 4)
 160#define ME4000_DIO_CTRL_BIT_MODE_5              (1 << 5)
 161#define ME4000_DIO_CTRL_BIT_MODE_6              (1 << 6)
 162#define ME4000_DIO_CTRL_BIT_MODE_7              (1 << 7)
 163#define ME4000_DIO_CTRL_BIT_FUNCTION_0          (1 << 8)
 164#define ME4000_DIO_CTRL_BIT_FUNCTION_1          (1 << 9)
 165#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_0         (1 << 10)
 166#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_1         (1 << 11)
 167#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2         (1 << 12)
 168#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3         (1 << 13)
 169#define ME4000_AO_DEMUX_ADJUST_REG              0xbc
 170#define ME4000_AO_DEMUX_ADJUST_VALUE            0x4c
 171#define ME4000_AI_SAMPLE_COUNTER_REG            0xc0
 172
 173#define ME4000_AI_FIFO_COUNT                    2048
 174
 175#define ME4000_AI_MIN_TICKS                     66
 176#define ME4000_AI_MIN_SAMPLE_TIME               2000
 177#define ME4000_AI_BASE_FREQUENCY                (unsigned int) 33E6
 178
 179#define ME4000_AI_CHANNEL_LIST_COUNT            1024
 180
 181struct me4000_info {
 182        unsigned long plx_regbase;
 183        unsigned long timer_regbase;
 184
 185        unsigned int ao_readback[4];
 186};
 187
 188enum me4000_boardid {
 189        BOARD_ME4650,
 190        BOARD_ME4660,
 191        BOARD_ME4660I,
 192        BOARD_ME4660S,
 193        BOARD_ME4660IS,
 194        BOARD_ME4670,
 195        BOARD_ME4670I,
 196        BOARD_ME4670S,
 197        BOARD_ME4670IS,
 198        BOARD_ME4680,
 199        BOARD_ME4680I,
 200        BOARD_ME4680S,
 201        BOARD_ME4680IS,
 202};
 203
 204struct me4000_board {
 205        const char *name;
 206        int ao_nchan;
 207        int ao_fifo;
 208        int ai_nchan;
 209        int ai_diff_nchan;
 210        int ai_sh_nchan;
 211        int ex_trig_analog;
 212        int dio_nchan;
 213        int has_counter;
 214};
 215
 216static const struct me4000_board me4000_boards[] = {
 217        [BOARD_ME4650] = {
 218                .name           = "ME-4650",
 219                .ai_nchan       = 16,
 220                .dio_nchan      = 32,
 221        },
 222        [BOARD_ME4660] = {
 223                .name           = "ME-4660",
 224                .ai_nchan       = 32,
 225                .ai_diff_nchan  = 16,
 226                .dio_nchan      = 32,
 227                .has_counter    = 1,
 228        },
 229        [BOARD_ME4660I] = {
 230                .name           = "ME-4660i",
 231                .ai_nchan       = 32,
 232                .ai_diff_nchan  = 16,
 233                .dio_nchan      = 32,
 234                .has_counter    = 1,
 235        },
 236        [BOARD_ME4660S] = {
 237                .name           = "ME-4660s",
 238                .ai_nchan       = 32,
 239                .ai_diff_nchan  = 16,
 240                .ai_sh_nchan    = 8,
 241                .dio_nchan      = 32,
 242                .has_counter    = 1,
 243        },
 244        [BOARD_ME4660IS] = {
 245                .name           = "ME-4660is",
 246                .ai_nchan       = 32,
 247                .ai_diff_nchan  = 16,
 248                .ai_sh_nchan    = 8,
 249                .dio_nchan      = 32,
 250                .has_counter    = 1,
 251        },
 252        [BOARD_ME4670] = {
 253                .name           = "ME-4670",
 254                .ao_nchan       = 4,
 255                .ai_nchan       = 32,
 256                .ai_diff_nchan  = 16,
 257                .ex_trig_analog = 1,
 258                .dio_nchan      = 32,
 259                .has_counter    = 1,
 260        },
 261        [BOARD_ME4670I] = {
 262                .name           = "ME-4670i",
 263                .ao_nchan       = 4,
 264                .ai_nchan       = 32,
 265                .ai_diff_nchan  = 16,
 266                .ex_trig_analog = 1,
 267                .dio_nchan      = 32,
 268                .has_counter    = 1,
 269        },
 270        [BOARD_ME4670S] = {
 271                .name           = "ME-4670s",
 272                .ao_nchan       = 4,
 273                .ai_nchan       = 32,
 274                .ai_diff_nchan  = 16,
 275                .ai_sh_nchan    = 8,
 276                .ex_trig_analog = 1,
 277                .dio_nchan      = 32,
 278                .has_counter    = 1,
 279        },
 280        [BOARD_ME4670IS] = {
 281                .name           = "ME-4670is",
 282                .ao_nchan       = 4,
 283                .ai_nchan       = 32,
 284                .ai_diff_nchan  = 16,
 285                .ai_sh_nchan    = 8,
 286                .ex_trig_analog = 1,
 287                .dio_nchan      = 32,
 288                .has_counter    = 1,
 289        },
 290        [BOARD_ME4680] = {
 291                .name           = "ME-4680",
 292                .ao_nchan       = 4,
 293                .ao_fifo        = 4,
 294                .ai_nchan       = 32,
 295                .ai_diff_nchan  = 16,
 296                .ex_trig_analog = 1,
 297                .dio_nchan      = 32,
 298                .has_counter    = 1,
 299        },
 300        [BOARD_ME4680I] = {
 301                .name           = "ME-4680i",
 302                .ao_nchan       = 4,
 303                .ao_fifo        = 4,
 304                .ai_nchan       = 32,
 305                .ai_diff_nchan  = 16,
 306                .ex_trig_analog = 1,
 307                .dio_nchan      = 32,
 308                .has_counter    = 1,
 309        },
 310        [BOARD_ME4680S] = {
 311                .name           = "ME-4680s",
 312                .ao_nchan       = 4,
 313                .ao_fifo        = 4,
 314                .ai_nchan       = 32,
 315                .ai_diff_nchan  = 16,
 316                .ai_sh_nchan    = 8,
 317                .ex_trig_analog = 1,
 318                .dio_nchan      = 32,
 319                .has_counter    = 1,
 320        },
 321        [BOARD_ME4680IS] = {
 322                .name           = "ME-4680is",
 323                .ao_nchan       = 4,
 324                .ao_fifo        = 4,
 325                .ai_nchan       = 32,
 326                .ai_diff_nchan  = 16,
 327                .ai_sh_nchan    = 8,
 328                .ex_trig_analog = 1,
 329                .dio_nchan      = 32,
 330                .has_counter    = 1,
 331        },
 332};
 333
 334static const struct comedi_lrange me4000_ai_range = {
 335        4,
 336        {
 337         UNI_RANGE(2.5),
 338         UNI_RANGE(10),
 339         BIP_RANGE(2.5),
 340         BIP_RANGE(10),
 341         }
 342};
 343
 344#define FIRMWARE_NOT_AVAILABLE 1
 345#if FIRMWARE_NOT_AVAILABLE
 346extern unsigned char *xilinx_firm;
 347#endif
 348
 349static int xilinx_download(struct comedi_device *dev)
 350{
 351        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 352        struct me4000_info *info = dev->private;
 353        unsigned long xilinx_iobase = pci_resource_start(pcidev, 5);
 354        u32 value = 0;
 355        wait_queue_head_t queue;
 356        int idx = 0;
 357        int size = 0;
 358        unsigned int intcsr;
 359
 360        if (!xilinx_iobase)
 361                return -ENODEV;
 362
 363        init_waitqueue_head(&queue);
 364
 365        /*
 366         * Set PLX local interrupt 2 polarity to high.
 367         * Interrupt is thrown by init pin of xilinx.
 368         */
 369        outl(PLX9052_INTCSR_LI2POL, info->plx_regbase + PLX9052_INTCSR);
 370
 371        /* Set /CS and /WRITE of the Xilinx */
 372        value = inl(info->plx_regbase + PLX9052_CNTRL);
 373        value |= PLX9052_CNTRL_UIO2_DATA;
 374        outl(value, info->plx_regbase + PLX9052_CNTRL);
 375
 376        /* Init Xilinx with CS1 */
 377        inb(xilinx_iobase + 0xC8);
 378
 379        /* Wait until /INIT pin is set */
 380        udelay(20);
 381        intcsr = inl(info->plx_regbase + PLX9052_INTCSR);
 382        if (!(intcsr & PLX9052_INTCSR_LI2STAT)) {
 383                dev_err(dev->class_dev, "Can't init Xilinx\n");
 384                return -EIO;
 385        }
 386
 387        /* Reset /CS and /WRITE of the Xilinx */
 388        value = inl(info->plx_regbase + PLX9052_CNTRL);
 389        value &= ~PLX9052_CNTRL_UIO2_DATA;
 390        outl(value, info->plx_regbase + PLX9052_CNTRL);
 391        if (FIRMWARE_NOT_AVAILABLE) {
 392                dev_err(dev->class_dev,
 393                        "xilinx firmware unavailable due to licensing, aborting");
 394                return -EIO;
 395        } else {
 396                /* Download Xilinx firmware */
 397                size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) +
 398                    (xilinx_firm[2] << 8) + xilinx_firm[3];
 399                udelay(10);
 400
 401                for (idx = 0; idx < size; idx++) {
 402                        outb(xilinx_firm[16 + idx], xilinx_iobase);
 403                        udelay(10);
 404
 405                        /* Check if BUSY flag is low */
 406                        if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO1_DATA) {
 407                                dev_err(dev->class_dev,
 408                                        "Xilinx is still busy (idx = %d)\n",
 409                                        idx);
 410                                return -EIO;
 411                        }
 412                }
 413        }
 414
 415        /* If done flag is high download was successful */
 416        if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO0_DATA) {
 417        } else {
 418                dev_err(dev->class_dev, "DONE flag is not set\n");
 419                dev_err(dev->class_dev, "Download not successful\n");
 420                return -EIO;
 421        }
 422
 423        /* Set /CS and /WRITE */
 424        value = inl(info->plx_regbase + PLX9052_CNTRL);
 425        value |= PLX9052_CNTRL_UIO2_DATA;
 426        outl(value, info->plx_regbase + PLX9052_CNTRL);
 427
 428        return 0;
 429}
 430
 431static void me4000_reset(struct comedi_device *dev)
 432{
 433        struct me4000_info *info = dev->private;
 434        unsigned long val;
 435        int chan;
 436
 437        /* Make a hardware reset */
 438        val = inl(info->plx_regbase + PLX9052_CNTRL);
 439        val |= PLX9052_CNTRL_PCI_RESET;
 440        outl(val, info->plx_regbase + PLX9052_CNTRL);
 441        val &= ~PLX9052_CNTRL_PCI_RESET;
 442        outl(val , info->plx_regbase + PLX9052_CNTRL);
 443
 444        /* 0x8000 to the DACs means an output voltage of 0V */
 445        for (chan = 0; chan < 4; chan++)
 446                outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan));
 447
 448        /* Set both stop bits in the analog input control register */
 449        outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
 450                dev->iobase + ME4000_AI_CTRL_REG);
 451
 452        /* Set both stop bits in the analog output control register */
 453        val = ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP;
 454        for (chan = 0; chan < 4; chan++)
 455                outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan));
 456
 457        /* Enable interrupts on the PLX */
 458        outl(PLX9052_INTCSR_LI1ENAB |
 459             PLX9052_INTCSR_LI1POL |
 460             PLX9052_INTCSR_PCIENAB, info->plx_regbase + PLX9052_INTCSR);
 461
 462        /* Set the adustment register for AO demux */
 463        outl(ME4000_AO_DEMUX_ADJUST_VALUE,
 464                    dev->iobase + ME4000_AO_DEMUX_ADJUST_REG);
 465
 466        /*
 467         * Set digital I/O direction for port 0
 468         * to output on isolated versions
 469         */
 470        if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1))
 471                outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG);
 472}
 473
 474/*=============================================================================
 475  Analog input section
 476  ===========================================================================*/
 477
 478static int me4000_ai_insn_read(struct comedi_device *dev,
 479                               struct comedi_subdevice *subdevice,
 480                               struct comedi_insn *insn, unsigned int *data)
 481{
 482        const struct me4000_board *thisboard = comedi_board(dev);
 483        int chan = CR_CHAN(insn->chanspec);
 484        int rang = CR_RANGE(insn->chanspec);
 485        int aref = CR_AREF(insn->chanspec);
 486
 487        unsigned long entry = 0;
 488        unsigned long tmp;
 489        long lval;
 490
 491        if (insn->n == 0) {
 492                return 0;
 493        } else if (insn->n > 1) {
 494                dev_err(dev->class_dev, "Invalid instruction length %d\n",
 495                        insn->n);
 496                return -EINVAL;
 497        }
 498
 499        switch (rang) {
 500        case 0:
 501                entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
 502                break;
 503        case 1:
 504                entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
 505                break;
 506        case 2:
 507                entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
 508                break;
 509        case 3:
 510                entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
 511                break;
 512        default:
 513                dev_err(dev->class_dev, "Invalid range specified\n");
 514                return -EINVAL;
 515        }
 516
 517        switch (aref) {
 518        case AREF_GROUND:
 519        case AREF_COMMON:
 520                if (chan >= thisboard->ai_nchan) {
 521                        dev_err(dev->class_dev,
 522                                "Analog input is not available\n");
 523                        return -EINVAL;
 524                }
 525                entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
 526                break;
 527
 528        case AREF_DIFF:
 529                if (rang == 0 || rang == 1) {
 530                        dev_err(dev->class_dev,
 531                                "Range must be bipolar when aref = diff\n");
 532                        return -EINVAL;
 533                }
 534
 535                if (chan >= thisboard->ai_diff_nchan) {
 536                        dev_err(dev->class_dev,
 537                                "Analog input is not available\n");
 538                        return -EINVAL;
 539                }
 540                entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
 541                break;
 542        default:
 543                dev_err(dev->class_dev, "Invalid aref specified\n");
 544                return -EINVAL;
 545        }
 546
 547        entry |= ME4000_AI_LIST_LAST_ENTRY;
 548
 549        /* Clear channel list, data fifo and both stop bits */
 550        tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
 551        tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
 552                 ME4000_AI_CTRL_BIT_DATA_FIFO |
 553                 ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
 554        outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
 555
 556        /* Set the acquisition mode to single */
 557        tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 |
 558                 ME4000_AI_CTRL_BIT_MODE_2);
 559        outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
 560
 561        /* Enable channel list and data fifo */
 562        tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
 563        outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
 564
 565        /* Generate channel list entry */
 566        outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
 567
 568        /* Set the timer to maximum sample rate */
 569        outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
 570        outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
 571
 572        /* Start conversion by dummy read */
 573        inl(dev->iobase + ME4000_AI_START_REG);
 574
 575        /* Wait until ready */
 576        udelay(10);
 577        if (!(inl(dev->iobase + ME4000_AI_STATUS_REG) &
 578             ME4000_AI_STATUS_BIT_EF_DATA)) {
 579                dev_err(dev->class_dev, "Value not available after wait\n");
 580                return -EIO;
 581        }
 582
 583        /* Read value from data fifo */
 584        lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
 585        data[0] = lval ^ 0x8000;
 586
 587        return 1;
 588}
 589
 590static int me4000_ai_cancel(struct comedi_device *dev,
 591                            struct comedi_subdevice *s)
 592{
 593        unsigned long tmp;
 594
 595        /* Stop any running conversion */
 596        tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
 597        tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
 598        outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
 599
 600        /* Clear the control register */
 601        outl(0x0, dev->iobase + ME4000_AI_CTRL_REG);
 602
 603        return 0;
 604}
 605
 606static int ai_check_chanlist(struct comedi_device *dev,
 607                             struct comedi_subdevice *s, struct comedi_cmd *cmd)
 608{
 609        const struct me4000_board *thisboard = comedi_board(dev);
 610        int aref;
 611        int i;
 612
 613        /* Check whether a channel list is available */
 614        if (!cmd->chanlist_len) {
 615                dev_err(dev->class_dev, "No channel list available\n");
 616                return -EINVAL;
 617        }
 618
 619        /* Check the channel list size */
 620        if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) {
 621                dev_err(dev->class_dev, "Channel list is to large\n");
 622                return -EINVAL;
 623        }
 624
 625        /* Check the pointer */
 626        if (!cmd->chanlist) {
 627                dev_err(dev->class_dev, "NULL pointer to channel list\n");
 628                return -EFAULT;
 629        }
 630
 631        /* Check whether aref is equal for all entries */
 632        aref = CR_AREF(cmd->chanlist[0]);
 633        for (i = 0; i < cmd->chanlist_len; i++) {
 634                if (CR_AREF(cmd->chanlist[i]) != aref) {
 635                        dev_err(dev->class_dev,
 636                                "Mode is not equal for all entries\n");
 637                        return -EINVAL;
 638                }
 639        }
 640
 641        /* Check whether channels are available for this ending */
 642        if (aref == SDF_DIFF) {
 643                for (i = 0; i < cmd->chanlist_len; i++) {
 644                        if (CR_CHAN(cmd->chanlist[i]) >=
 645                            thisboard->ai_diff_nchan) {
 646                                dev_err(dev->class_dev,
 647                                        "Channel number to high\n");
 648                                return -EINVAL;
 649                        }
 650                }
 651        } else {
 652                for (i = 0; i < cmd->chanlist_len; i++) {
 653                        if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai_nchan) {
 654                                dev_err(dev->class_dev,
 655                                        "Channel number to high\n");
 656                                return -EINVAL;
 657                        }
 658                }
 659        }
 660
 661        /* Check if bipolar is set for all entries when in differential mode */
 662        if (aref == SDF_DIFF) {
 663                for (i = 0; i < cmd->chanlist_len; i++) {
 664                        if (CR_RANGE(cmd->chanlist[i]) != 1 &&
 665                            CR_RANGE(cmd->chanlist[i]) != 2) {
 666                                dev_err(dev->class_dev,
 667                                       "Bipolar is not selected in differential mode\n");
 668                                return -EINVAL;
 669                        }
 670                }
 671        }
 672
 673        return 0;
 674}
 675
 676static int ai_round_cmd_args(struct comedi_device *dev,
 677                             struct comedi_subdevice *s,
 678                             struct comedi_cmd *cmd,
 679                             unsigned int *init_ticks,
 680                             unsigned int *scan_ticks, unsigned int *chan_ticks)
 681{
 682
 683        int rest;
 684
 685        *init_ticks = 0;
 686        *scan_ticks = 0;
 687        *chan_ticks = 0;
 688
 689        if (cmd->start_arg) {
 690                *init_ticks = (cmd->start_arg * 33) / 1000;
 691                rest = (cmd->start_arg * 33) % 1000;
 692
 693                if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
 694                        if (rest > 33)
 695                                (*init_ticks)++;
 696                } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
 697                        if (rest)
 698                                (*init_ticks)++;
 699                }
 700        }
 701
 702        if (cmd->scan_begin_arg) {
 703                *scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
 704                rest = (cmd->scan_begin_arg * 33) % 1000;
 705
 706                if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
 707                        if (rest > 33)
 708                                (*scan_ticks)++;
 709                } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
 710                        if (rest)
 711                                (*scan_ticks)++;
 712                }
 713        }
 714
 715        if (cmd->convert_arg) {
 716                *chan_ticks = (cmd->convert_arg * 33) / 1000;
 717                rest = (cmd->convert_arg * 33) % 1000;
 718
 719                if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) {
 720                        if (rest > 33)
 721                                (*chan_ticks)++;
 722                } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) {
 723                        if (rest)
 724                                (*chan_ticks)++;
 725                }
 726        }
 727
 728        return 0;
 729}
 730
 731static void ai_write_timer(struct comedi_device *dev,
 732                           unsigned int init_ticks,
 733                           unsigned int scan_ticks, unsigned int chan_ticks)
 734{
 735        outl(init_ticks - 1, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG);
 736        outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG);
 737
 738        if (scan_ticks) {
 739                outl(scan_ticks - 1, dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG);
 740                outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG);
 741        }
 742
 743        outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
 744        outl(chan_ticks - 1, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
 745}
 746
 747static int ai_write_chanlist(struct comedi_device *dev,
 748                             struct comedi_subdevice *s, struct comedi_cmd *cmd)
 749{
 750        unsigned int entry;
 751        unsigned int chan;
 752        unsigned int rang;
 753        unsigned int aref;
 754        int i;
 755
 756        for (i = 0; i < cmd->chanlist_len; i++) {
 757                chan = CR_CHAN(cmd->chanlist[i]);
 758                rang = CR_RANGE(cmd->chanlist[i]);
 759                aref = CR_AREF(cmd->chanlist[i]);
 760
 761                entry = chan;
 762
 763                if (rang == 0)
 764                        entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
 765                else if (rang == 1)
 766                        entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
 767                else if (rang == 2)
 768                        entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
 769                else
 770                        entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
 771
 772                if (aref == SDF_DIFF)
 773                        entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
 774                else
 775                        entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
 776
 777                outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
 778        }
 779
 780        return 0;
 781}
 782
 783static int ai_prepare(struct comedi_device *dev,
 784                      struct comedi_subdevice *s,
 785                      struct comedi_cmd *cmd,
 786                      unsigned int init_ticks,
 787                      unsigned int scan_ticks, unsigned int chan_ticks)
 788{
 789
 790        unsigned long tmp = 0;
 791
 792        /* Write timer arguments */
 793        ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
 794
 795        /* Reset control register */
 796        outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
 797
 798        /* Start sources */
 799        if ((cmd->start_src == TRIG_EXT &&
 800             cmd->scan_begin_src == TRIG_TIMER &&
 801             cmd->convert_src == TRIG_TIMER) ||
 802            (cmd->start_src == TRIG_EXT &&
 803             cmd->scan_begin_src == TRIG_FOLLOW &&
 804             cmd->convert_src == TRIG_TIMER)) {
 805                tmp = ME4000_AI_CTRL_BIT_MODE_1 |
 806                    ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
 807                    ME4000_AI_CTRL_BIT_DATA_FIFO;
 808        } else if (cmd->start_src == TRIG_EXT &&
 809                   cmd->scan_begin_src == TRIG_EXT &&
 810                   cmd->convert_src == TRIG_TIMER) {
 811                tmp = ME4000_AI_CTRL_BIT_MODE_2 |
 812                    ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
 813                    ME4000_AI_CTRL_BIT_DATA_FIFO;
 814        } else if (cmd->start_src == TRIG_EXT &&
 815                   cmd->scan_begin_src == TRIG_EXT &&
 816                   cmd->convert_src == TRIG_EXT) {
 817                tmp = ME4000_AI_CTRL_BIT_MODE_0 |
 818                    ME4000_AI_CTRL_BIT_MODE_1 |
 819                    ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
 820                    ME4000_AI_CTRL_BIT_DATA_FIFO;
 821        } else {
 822                tmp = ME4000_AI_CTRL_BIT_MODE_0 |
 823                    ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
 824                    ME4000_AI_CTRL_BIT_DATA_FIFO;
 825        }
 826
 827        /* Stop triggers */
 828        if (cmd->stop_src == TRIG_COUNT) {
 829                outl(cmd->chanlist_len * cmd->stop_arg,
 830                            dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
 831                tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
 832        } else if (cmd->stop_src == TRIG_NONE &&
 833                   cmd->scan_end_src == TRIG_COUNT) {
 834                outl(cmd->scan_end_arg,
 835                            dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
 836                tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
 837        } else {
 838                tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
 839        }
 840
 841        /* Write the setup to the control register */
 842        outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
 843
 844        /* Write the channel list */
 845        ai_write_chanlist(dev, s, cmd);
 846
 847        return 0;
 848}
 849
 850static int me4000_ai_do_cmd(struct comedi_device *dev,
 851                            struct comedi_subdevice *s)
 852{
 853        int err;
 854        unsigned int init_ticks = 0;
 855        unsigned int scan_ticks = 0;
 856        unsigned int chan_ticks = 0;
 857        struct comedi_cmd *cmd = &s->async->cmd;
 858
 859        /* Reset the analog input */
 860        err = me4000_ai_cancel(dev, s);
 861        if (err)
 862                return err;
 863
 864        /* Round the timer arguments */
 865        err = ai_round_cmd_args(dev,
 866                                s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
 867        if (err)
 868                return err;
 869
 870        /* Prepare the AI for acquisition */
 871        err = ai_prepare(dev, s, cmd, init_ticks, scan_ticks, chan_ticks);
 872        if (err)
 873                return err;
 874
 875        /* Start acquistion by dummy read */
 876        inl(dev->iobase + ME4000_AI_START_REG);
 877
 878        return 0;
 879}
 880
 881static int me4000_ai_do_cmd_test(struct comedi_device *dev,
 882                                 struct comedi_subdevice *s,
 883                                 struct comedi_cmd *cmd)
 884{
 885
 886        unsigned int init_ticks;
 887        unsigned int chan_ticks;
 888        unsigned int scan_ticks;
 889        int err = 0;
 890
 891        /* Only rounding flags are implemented */
 892        cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN;
 893
 894        /* Round the timer arguments */
 895        ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
 896
 897        /* Step 1 : check if triggers are trivially valid */
 898
 899        err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
 900        err |= cfc_check_trigger_src(&cmd->scan_begin_src,
 901                                        TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
 902        err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
 903        err |= cfc_check_trigger_src(&cmd->scan_end_src,
 904                                        TRIG_NONE | TRIG_COUNT);
 905        err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE | TRIG_COUNT);
 906
 907        if (err)
 908                return 1;
 909
 910        /* Step 2a : make sure trigger sources are unique */
 911
 912        err |= cfc_check_trigger_is_unique(cmd->start_src);
 913        err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
 914        err |= cfc_check_trigger_is_unique(cmd->convert_src);
 915        err |= cfc_check_trigger_is_unique(cmd->scan_end_src);
 916        err |= cfc_check_trigger_is_unique(cmd->stop_src);
 917
 918        /* Step 2b : and mutually compatible */
 919
 920        if (cmd->start_src == TRIG_NOW &&
 921            cmd->scan_begin_src == TRIG_TIMER &&
 922            cmd->convert_src == TRIG_TIMER) {
 923        } else if (cmd->start_src == TRIG_NOW &&
 924                   cmd->scan_begin_src == TRIG_FOLLOW &&
 925                   cmd->convert_src == TRIG_TIMER) {
 926        } else if (cmd->start_src == TRIG_EXT &&
 927                   cmd->scan_begin_src == TRIG_TIMER &&
 928                   cmd->convert_src == TRIG_TIMER) {
 929        } else if (cmd->start_src == TRIG_EXT &&
 930                   cmd->scan_begin_src == TRIG_FOLLOW &&
 931                   cmd->convert_src == TRIG_TIMER) {
 932        } else if (cmd->start_src == TRIG_EXT &&
 933                   cmd->scan_begin_src == TRIG_EXT &&
 934                   cmd->convert_src == TRIG_TIMER) {
 935        } else if (cmd->start_src == TRIG_EXT &&
 936                   cmd->scan_begin_src == TRIG_EXT &&
 937                   cmd->convert_src == TRIG_EXT) {
 938        } else {
 939                err |= -EINVAL;
 940        }
 941
 942        if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) {
 943        } else if (cmd->stop_src == TRIG_COUNT &&
 944                   cmd->scan_end_src == TRIG_NONE) {
 945        } else if (cmd->stop_src == TRIG_NONE &&
 946                   cmd->scan_end_src == TRIG_COUNT) {
 947        } else if (cmd->stop_src == TRIG_COUNT &&
 948                   cmd->scan_end_src == TRIG_COUNT) {
 949        } else {
 950                err |= -EINVAL;
 951        }
 952
 953        if (err)
 954                return 2;
 955
 956        /* Step 3: check if arguments are trivially valid */
 957
 958        if (cmd->chanlist_len < 1) {
 959                cmd->chanlist_len = 1;
 960                err |= -EINVAL;
 961        }
 962        if (init_ticks < 66) {
 963                cmd->start_arg = 2000;
 964                err |= -EINVAL;
 965        }
 966        if (scan_ticks && scan_ticks < 67) {
 967                cmd->scan_begin_arg = 2031;
 968                err |= -EINVAL;
 969        }
 970        if (chan_ticks < 66) {
 971                cmd->convert_arg = 2000;
 972                err |= -EINVAL;
 973        }
 974
 975        if (err)
 976                return 3;
 977
 978        /*
 979         * Stage 4. Check for argument conflicts.
 980         */
 981        if (cmd->start_src == TRIG_NOW &&
 982            cmd->scan_begin_src == TRIG_TIMER &&
 983            cmd->convert_src == TRIG_TIMER) {
 984
 985                /* Check timer arguments */
 986                if (init_ticks < ME4000_AI_MIN_TICKS) {
 987                        dev_err(dev->class_dev, "Invalid start arg\n");
 988                        cmd->start_arg = 2000;  /*  66 ticks at least */
 989                        err++;
 990                }
 991                if (chan_ticks < ME4000_AI_MIN_TICKS) {
 992                        dev_err(dev->class_dev, "Invalid convert arg\n");
 993                        cmd->convert_arg = 2000;        /*  66 ticks at least */
 994                        err++;
 995                }
 996                if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
 997                        dev_err(dev->class_dev, "Invalid scan end arg\n");
 998
 999                        /*  At least one tick more */
1000                        cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
1001                        err++;
1002                }
1003        } else if (cmd->start_src == TRIG_NOW &&
1004                   cmd->scan_begin_src == TRIG_FOLLOW &&
1005                   cmd->convert_src == TRIG_TIMER) {
1006
1007                /* Check timer arguments */
1008                if (init_ticks < ME4000_AI_MIN_TICKS) {
1009                        dev_err(dev->class_dev, "Invalid start arg\n");
1010                        cmd->start_arg = 2000;  /*  66 ticks at least */
1011                        err++;
1012                }
1013                if (chan_ticks < ME4000_AI_MIN_TICKS) {
1014                        dev_err(dev->class_dev, "Invalid convert arg\n");
1015                        cmd->convert_arg = 2000;        /*  66 ticks at least */
1016                        err++;
1017                }
1018        } else if (cmd->start_src == TRIG_EXT &&
1019                   cmd->scan_begin_src == TRIG_TIMER &&
1020                   cmd->convert_src == TRIG_TIMER) {
1021
1022                /* Check timer arguments */
1023                if (init_ticks < ME4000_AI_MIN_TICKS) {
1024                        dev_err(dev->class_dev, "Invalid start arg\n");
1025                        cmd->start_arg = 2000;  /*  66 ticks at least */
1026                        err++;
1027                }
1028                if (chan_ticks < ME4000_AI_MIN_TICKS) {
1029                        dev_err(dev->class_dev, "Invalid convert arg\n");
1030                        cmd->convert_arg = 2000;        /*  66 ticks at least */
1031                        err++;
1032                }
1033                if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1034                        dev_err(dev->class_dev, "Invalid scan end arg\n");
1035
1036                        /*  At least one tick more */
1037                        cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
1038                        err++;
1039                }
1040        } else if (cmd->start_src == TRIG_EXT &&
1041                   cmd->scan_begin_src == TRIG_FOLLOW &&
1042                   cmd->convert_src == TRIG_TIMER) {
1043
1044                /* Check timer arguments */
1045                if (init_ticks < ME4000_AI_MIN_TICKS) {
1046                        dev_err(dev->class_dev, "Invalid start arg\n");
1047                        cmd->start_arg = 2000;  /*  66 ticks at least */
1048                        err++;
1049                }
1050                if (chan_ticks < ME4000_AI_MIN_TICKS) {
1051                        dev_err(dev->class_dev, "Invalid convert arg\n");
1052                        cmd->convert_arg = 2000;        /*  66 ticks at least */
1053                        err++;
1054                }
1055        } else if (cmd->start_src == TRIG_EXT &&
1056                   cmd->scan_begin_src == TRIG_EXT &&
1057                   cmd->convert_src == TRIG_TIMER) {
1058
1059                /* Check timer arguments */
1060                if (init_ticks < ME4000_AI_MIN_TICKS) {
1061                        dev_err(dev->class_dev, "Invalid start arg\n");
1062                        cmd->start_arg = 2000;  /*  66 ticks at least */
1063                        err++;
1064                }
1065                if (chan_ticks < ME4000_AI_MIN_TICKS) {
1066                        dev_err(dev->class_dev, "Invalid convert arg\n");
1067                        cmd->convert_arg = 2000;        /*  66 ticks at least */
1068                        err++;
1069                }
1070        } else if (cmd->start_src == TRIG_EXT &&
1071                   cmd->scan_begin_src == TRIG_EXT &&
1072                   cmd->convert_src == TRIG_EXT) {
1073
1074                /* Check timer arguments */
1075                if (init_ticks < ME4000_AI_MIN_TICKS) {
1076                        dev_err(dev->class_dev, "Invalid start arg\n");
1077                        cmd->start_arg = 2000;  /*  66 ticks at least */
1078                        err++;
1079                }
1080        }
1081        if (cmd->stop_src == TRIG_COUNT) {
1082                if (cmd->stop_arg == 0) {
1083                        dev_err(dev->class_dev, "Invalid stop arg\n");
1084                        cmd->stop_arg = 1;
1085                        err++;
1086                }
1087        }
1088        if (cmd->scan_end_src == TRIG_COUNT) {
1089                if (cmd->scan_end_arg == 0) {
1090                        dev_err(dev->class_dev, "Invalid scan end arg\n");
1091                        cmd->scan_end_arg = 1;
1092                        err++;
1093                }
1094        }
1095
1096        if (err)
1097                return 4;
1098
1099        /*
1100         * Stage 5. Check the channel list.
1101         */
1102        if (ai_check_chanlist(dev, s, cmd))
1103                return 5;
1104
1105        return 0;
1106}
1107
1108static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
1109{
1110        unsigned int tmp;
1111        struct comedi_device *dev = dev_id;
1112        struct comedi_subdevice *s = &dev->subdevices[0];
1113        int i;
1114        int c = 0;
1115        long lval;
1116
1117        if (!dev->attached)
1118                return IRQ_NONE;
1119
1120        /* Reset all events */
1121        s->async->events = 0;
1122
1123        /* Check if irq number is right */
1124        if (irq != dev->irq) {
1125                dev_err(dev->class_dev, "Incorrect interrupt num: %d\n", irq);
1126                return IRQ_HANDLED;
1127        }
1128
1129        if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
1130            ME4000_IRQ_STATUS_BIT_AI_HF) {
1131                /* Read status register to find out what happened */
1132                tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
1133
1134                if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
1135                    !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
1136                    (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1137                        c = ME4000_AI_FIFO_COUNT;
1138
1139                        /*
1140                         * FIFO overflow, so stop conversion
1141                         * and disable all interrupts
1142                         */
1143                        tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1144                        tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1145                                 ME4000_AI_CTRL_BIT_SC_IRQ);
1146                        outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1147
1148                        s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1149
1150                        dev_err(dev->class_dev, "FIFO overflow\n");
1151                } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
1152                           && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
1153                           && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1154                        s->async->events |= COMEDI_CB_BLOCK;
1155
1156                        c = ME4000_AI_FIFO_COUNT / 2;
1157                } else {
1158                        dev_err(dev->class_dev,
1159                                "Can't determine state of fifo\n");
1160                        c = 0;
1161
1162                        /*
1163                         * Undefined state, so stop conversion
1164                         * and disable all interrupts
1165                         */
1166                        tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1167                        tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1168                                 ME4000_AI_CTRL_BIT_SC_IRQ);
1169                        outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1170
1171                        s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1172
1173                        dev_err(dev->class_dev, "Undefined FIFO state\n");
1174                }
1175
1176                for (i = 0; i < c; i++) {
1177                        /* Read value from data fifo */
1178                        lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
1179                        lval ^= 0x8000;
1180
1181                        if (!comedi_buf_put(s->async, lval)) {
1182                                /*
1183                                 * Buffer overflow, so stop conversion
1184                                 * and disable all interrupts
1185                                 */
1186                                tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1187                                tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1188                                         ME4000_AI_CTRL_BIT_SC_IRQ);
1189                                outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1190
1191                                s->async->events |= COMEDI_CB_OVERFLOW;
1192
1193                                dev_err(dev->class_dev, "Buffer overflow\n");
1194
1195                                break;
1196                        }
1197                }
1198
1199                /* Work is done, so reset the interrupt */
1200                tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1201                outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1202                tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1203                outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1204        }
1205
1206        if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
1207            ME4000_IRQ_STATUS_BIT_SC) {
1208                s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
1209
1210                /*
1211                 * Acquisition is complete, so stop
1212                 * conversion and disable all interrupts
1213                 */
1214                tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
1215                tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1216                tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1217                outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1218
1219                /* Poll data until fifo empty */
1220                while (inl(dev->iobase + ME4000_AI_CTRL_REG) &
1221                       ME4000_AI_STATUS_BIT_EF_DATA) {
1222                        /* Read value from data fifo */
1223                        lval = inl(dev->iobase + ME4000_AI_DATA_REG) & 0xFFFF;
1224                        lval ^= 0x8000;
1225
1226                        if (!comedi_buf_put(s->async, lval)) {
1227                                dev_err(dev->class_dev, "Buffer overflow\n");
1228                                s->async->events |= COMEDI_CB_OVERFLOW;
1229                                break;
1230                        }
1231                }
1232
1233                /* Work is done, so reset the interrupt */
1234                tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1235                outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1236                tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1237                outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
1238        }
1239
1240        if (s->async->events)
1241                comedi_event(dev, s);
1242
1243        return IRQ_HANDLED;
1244}
1245
1246/*=============================================================================
1247  Analog output section
1248  ===========================================================================*/
1249
1250static int me4000_ao_insn_write(struct comedi_device *dev,
1251                                struct comedi_subdevice *s,
1252                                struct comedi_insn *insn, unsigned int *data)
1253{
1254        const struct me4000_board *thisboard = comedi_board(dev);
1255        struct me4000_info *info = dev->private;
1256        int chan = CR_CHAN(insn->chanspec);
1257        int rang = CR_RANGE(insn->chanspec);
1258        int aref = CR_AREF(insn->chanspec);
1259        unsigned long tmp;
1260
1261        if (insn->n == 0) {
1262                return 0;
1263        } else if (insn->n > 1) {
1264                dev_err(dev->class_dev, "Invalid instruction length %d\n",
1265                        insn->n);
1266                return -EINVAL;
1267        }
1268
1269        if (chan >= thisboard->ao_nchan) {
1270                dev_err(dev->class_dev, "Invalid channel %d\n", insn->n);
1271                return -EINVAL;
1272        }
1273
1274        if (rang != 0) {
1275                dev_err(dev->class_dev, "Invalid range %d\n", insn->n);
1276                return -EINVAL;
1277        }
1278
1279        if (aref != AREF_GROUND && aref != AREF_COMMON) {
1280                dev_err(dev->class_dev, "Invalid aref %d\n", insn->n);
1281                return -EINVAL;
1282        }
1283
1284        /* Stop any running conversion */
1285        tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan));
1286        tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
1287        outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan));
1288
1289        /* Clear control register and set to single mode */
1290        outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan));
1291
1292        /* Write data value */
1293        outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan));
1294
1295        /* Store in the mirror */
1296        info->ao_readback[chan] = data[0];
1297
1298        return 1;
1299}
1300
1301static int me4000_ao_insn_read(struct comedi_device *dev,
1302                               struct comedi_subdevice *s,
1303                               struct comedi_insn *insn, unsigned int *data)
1304{
1305        struct me4000_info *info = dev->private;
1306        int chan = CR_CHAN(insn->chanspec);
1307
1308        if (insn->n == 0) {
1309                return 0;
1310        } else if (insn->n > 1) {
1311                dev_err(dev->class_dev, "Invalid instruction length\n");
1312                return -EINVAL;
1313        }
1314
1315        data[0] = info->ao_readback[chan];
1316
1317        return 1;
1318}
1319
1320/*=============================================================================
1321  Digital I/O section
1322  ===========================================================================*/
1323
1324static int me4000_dio_insn_bits(struct comedi_device *dev,
1325                                struct comedi_subdevice *s,
1326                                struct comedi_insn *insn, unsigned int *data)
1327{
1328        /*
1329         * The insn data consists of a mask in data[0] and the new data
1330         * in data[1]. The mask defines which bits we are concerning about.
1331         * The new data must be anded with the mask.
1332         * Each channel corresponds to a bit.
1333         */
1334        if (data[0]) {
1335                /* Check if requested ports are configured for output */
1336                if ((s->io_bits & data[0]) != data[0])
1337                        return -EIO;
1338
1339                s->state &= ~data[0];
1340                s->state |= data[0] & data[1];
1341
1342                /* Write out the new digital output lines */
1343                outl((s->state >> 0) & 0xFF,
1344                            dev->iobase + ME4000_DIO_PORT_0_REG);
1345                outl((s->state >> 8) & 0xFF,
1346                            dev->iobase + ME4000_DIO_PORT_1_REG);
1347                outl((s->state >> 16) & 0xFF,
1348                            dev->iobase + ME4000_DIO_PORT_2_REG);
1349                outl((s->state >> 24) & 0xFF,
1350                            dev->iobase + ME4000_DIO_PORT_3_REG);
1351        }
1352
1353        /* On return, data[1] contains the value of
1354           the digital input and output lines. */
1355        data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
1356                  ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
1357                  ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
1358                  ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24);
1359
1360        return insn->n;
1361}
1362
1363static int me4000_dio_insn_config(struct comedi_device *dev,
1364                                  struct comedi_subdevice *s,
1365                                  struct comedi_insn *insn, unsigned int *data)
1366{
1367        unsigned long tmp;
1368        int chan = CR_CHAN(insn->chanspec);
1369
1370        switch (data[0]) {
1371        default:
1372                return -EINVAL;
1373        case INSN_CONFIG_DIO_QUERY:
1374                data[1] =
1375                    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1376                return insn->n;
1377        case INSN_CONFIG_DIO_INPUT:
1378        case INSN_CONFIG_DIO_OUTPUT:
1379                break;
1380        }
1381
1382        /*
1383         * The input or output configuration of each digital line is
1384         * configured by a special insn_config instruction.  chanspec
1385         * contains the channel to be changed, and data[0] contains the
1386         * value INSN_CONFIG_DIO_INPUT or INSN_CONFIG_DIO_OUTPUT.
1387         * On the ME-4000 it is only possible to switch port wise (8 bit)
1388         */
1389
1390        tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
1391
1392        if (data[0] == INSN_CONFIG_DIO_OUTPUT) {
1393                if (chan < 8) {
1394                        s->io_bits |= 0xFF;
1395                        tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
1396                                 ME4000_DIO_CTRL_BIT_MODE_1);
1397                        tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
1398                } else if (chan < 16) {
1399                        /*
1400                         * Chech for optoisolated ME-4000 version.
1401                         * If one the first port is a fixed output
1402                         * port and the second is a fixed input port.
1403                         */
1404                        if (!inl(dev->iobase + ME4000_DIO_DIR_REG))
1405                                return -ENODEV;
1406
1407                        s->io_bits |= 0xFF00;
1408                        tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
1409                                 ME4000_DIO_CTRL_BIT_MODE_3);
1410                        tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
1411                } else if (chan < 24) {
1412                        s->io_bits |= 0xFF0000;
1413                        tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
1414                                 ME4000_DIO_CTRL_BIT_MODE_5);
1415                        tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
1416                } else if (chan < 32) {
1417                        s->io_bits |= 0xFF000000;
1418                        tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
1419                                 ME4000_DIO_CTRL_BIT_MODE_7);
1420                        tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
1421                } else {
1422                        return -EINVAL;
1423                }
1424        } else {
1425                if (chan < 8) {
1426                        /*
1427                         * Chech for optoisolated ME-4000 version.
1428                         * If one the first port is a fixed output
1429                         * port and the second is a fixed input port.
1430                         */
1431                        if (!inl(dev->iobase + ME4000_DIO_DIR_REG))
1432                                return -ENODEV;
1433
1434                        s->io_bits &= ~0xFF;
1435                        tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
1436                                 ME4000_DIO_CTRL_BIT_MODE_1);
1437                } else if (chan < 16) {
1438                        s->io_bits &= ~0xFF00;
1439                        tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
1440                                 ME4000_DIO_CTRL_BIT_MODE_3);
1441                } else if (chan < 24) {
1442                        s->io_bits &= ~0xFF0000;
1443                        tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
1444                                 ME4000_DIO_CTRL_BIT_MODE_5);
1445                } else if (chan < 32) {
1446                        s->io_bits &= ~0xFF000000;
1447                        tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
1448                                 ME4000_DIO_CTRL_BIT_MODE_7);
1449                } else {
1450                        return -EINVAL;
1451                }
1452        }
1453
1454        outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
1455
1456        return 1;
1457}
1458
1459/*=============================================================================
1460  Counter section
1461  ===========================================================================*/
1462
1463static int me4000_cnt_insn_config(struct comedi_device *dev,
1464                                  struct comedi_subdevice *s,
1465                                  struct comedi_insn *insn,
1466                                  unsigned int *data)
1467{
1468        struct me4000_info *info = dev->private;
1469        int err;
1470
1471        switch (data[0]) {
1472        case GPCT_RESET:
1473                if (insn->n != 1)
1474                        return -EINVAL;
1475
1476                err = i8254_load(info->timer_regbase, 0, insn->chanspec, 0,
1477                                I8254_MODE0 | I8254_BINARY);
1478                if (err)
1479                        return err;
1480                break;
1481        case GPCT_SET_OPERATION:
1482                if (insn->n != 2)
1483                        return -EINVAL;
1484
1485                err = i8254_set_mode(info->timer_regbase, 0, insn->chanspec,
1486                                (data[1] << 1) | I8254_BINARY);
1487                if (err)
1488                        return err;
1489                break;
1490        default:
1491                return -EINVAL;
1492        }
1493
1494        return insn->n;
1495}
1496
1497static int me4000_cnt_insn_read(struct comedi_device *dev,
1498                                struct comedi_subdevice *s,
1499                                struct comedi_insn *insn, unsigned int *data)
1500{
1501        struct me4000_info *info = dev->private;
1502
1503        if (insn->n == 0)
1504                return 0;
1505
1506        if (insn->n > 1) {
1507                dev_err(dev->class_dev, "Invalid instruction length %d\n",
1508                        insn->n);
1509                return -EINVAL;
1510        }
1511
1512        data[0] = i8254_read(info->timer_regbase, 0, insn->chanspec);
1513
1514        return 1;
1515}
1516
1517static int me4000_cnt_insn_write(struct comedi_device *dev,
1518                                 struct comedi_subdevice *s,
1519                                 struct comedi_insn *insn, unsigned int *data)
1520{
1521        struct me4000_info *info = dev->private;
1522
1523        if (insn->n == 0) {
1524                return 0;
1525        } else if (insn->n > 1) {
1526                dev_err(dev->class_dev, "Invalid instruction length %d\n",
1527                        insn->n);
1528                return -EINVAL;
1529        }
1530
1531        i8254_write(info->timer_regbase, 0, insn->chanspec, data[0]);
1532
1533        return 1;
1534}
1535
1536static int me4000_auto_attach(struct comedi_device *dev,
1537                              unsigned long context)
1538{
1539        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1540        const struct me4000_board *thisboard = NULL;
1541        struct me4000_info *info;
1542        struct comedi_subdevice *s;
1543        int result;
1544
1545        if (context < ARRAY_SIZE(me4000_boards))
1546                thisboard = &me4000_boards[context];
1547        if (!thisboard)
1548                return -ENODEV;
1549        dev->board_ptr = thisboard;
1550        dev->board_name = thisboard->name;
1551
1552        info = kzalloc(sizeof(*info), GFP_KERNEL);
1553        if (!info)
1554                return -ENOMEM;
1555        dev->private = info;
1556
1557        result = comedi_pci_enable(dev);
1558        if (result)
1559                return result;
1560
1561        info->plx_regbase = pci_resource_start(pcidev, 1);
1562        dev->iobase = pci_resource_start(pcidev, 2);
1563        info->timer_regbase = pci_resource_start(pcidev, 3);
1564        if (!info->plx_regbase || !dev->iobase || !info->timer_regbase)
1565                return -ENODEV;
1566
1567        result = xilinx_download(dev);
1568        if (result)
1569                return result;
1570
1571        me4000_reset(dev);
1572
1573        result = comedi_alloc_subdevices(dev, 4);
1574        if (result)
1575                return result;
1576
1577    /*=========================================================================
1578      Analog input subdevice
1579      ========================================================================*/
1580
1581        s = &dev->subdevices[0];
1582
1583        if (thisboard->ai_nchan) {
1584                s->type = COMEDI_SUBD_AI;
1585                s->subdev_flags =
1586                    SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
1587                s->n_chan = thisboard->ai_nchan;
1588                s->maxdata = 0xFFFF;    /*  16 bit ADC */
1589                s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
1590                s->range_table = &me4000_ai_range;
1591                s->insn_read = me4000_ai_insn_read;
1592
1593                if (pcidev->irq > 0) {
1594                        if (request_irq(pcidev->irq, me4000_ai_isr,
1595                                        IRQF_SHARED, dev->board_name, dev)) {
1596                                dev_warn(dev->class_dev,
1597                                        "request_irq failed\n");
1598                        } else {
1599                                dev->read_subdev = s;
1600                                s->subdev_flags |= SDF_CMD_READ;
1601                                s->cancel = me4000_ai_cancel;
1602                                s->do_cmdtest = me4000_ai_do_cmd_test;
1603                                s->do_cmd = me4000_ai_do_cmd;
1604
1605                                dev->irq = pcidev->irq;
1606                        }
1607                } else {
1608                        dev_warn(dev->class_dev, "No interrupt available\n");
1609                }
1610        } else {
1611                s->type = COMEDI_SUBD_UNUSED;
1612        }
1613
1614    /*=========================================================================
1615      Analog output subdevice
1616      ========================================================================*/
1617
1618        s = &dev->subdevices[1];
1619
1620        if (thisboard->ao_nchan) {
1621                s->type = COMEDI_SUBD_AO;
1622                s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
1623                s->n_chan = thisboard->ao_nchan;
1624                s->maxdata = 0xFFFF;    /*  16 bit DAC */
1625                s->range_table = &range_bipolar10;
1626                s->insn_write = me4000_ao_insn_write;
1627                s->insn_read = me4000_ao_insn_read;
1628        } else {
1629                s->type = COMEDI_SUBD_UNUSED;
1630        }
1631
1632    /*=========================================================================
1633      Digital I/O subdevice
1634      ========================================================================*/
1635
1636        s = &dev->subdevices[2];
1637
1638        if (thisboard->dio_nchan) {
1639                s->type = COMEDI_SUBD_DIO;
1640                s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1641                s->n_chan = thisboard->dio_nchan;
1642                s->maxdata = 1;
1643                s->range_table = &range_digital;
1644                s->insn_bits = me4000_dio_insn_bits;
1645                s->insn_config = me4000_dio_insn_config;
1646        } else {
1647                s->type = COMEDI_SUBD_UNUSED;
1648        }
1649
1650        /*
1651         * Check for optoisolated ME-4000 version. If one the first
1652         * port is a fixed output port and the second is a fixed input port.
1653         */
1654        if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) {
1655                s->io_bits |= 0xFF;
1656                outl(ME4000_DIO_CTRL_BIT_MODE_0,
1657                        dev->iobase + ME4000_DIO_DIR_REG);
1658        }
1659
1660    /*=========================================================================
1661      Counter subdevice
1662      ========================================================================*/
1663
1664        s = &dev->subdevices[3];
1665
1666        if (thisboard->has_counter) {
1667                s->type = COMEDI_SUBD_COUNTER;
1668                s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1669                s->n_chan = 3;
1670                s->maxdata = 0xFFFF;    /*  16 bit counters */
1671                s->insn_read = me4000_cnt_insn_read;
1672                s->insn_write = me4000_cnt_insn_write;
1673                s->insn_config = me4000_cnt_insn_config;
1674        } else {
1675                s->type = COMEDI_SUBD_UNUSED;
1676        }
1677
1678        return 0;
1679}
1680
1681static void me4000_detach(struct comedi_device *dev)
1682{
1683        if (dev->irq)
1684                free_irq(dev->irq, dev);
1685        if (dev->iobase)
1686                me4000_reset(dev);
1687        comedi_pci_disable(dev);
1688}
1689
1690static struct comedi_driver me4000_driver = {
1691        .driver_name    = "me4000",
1692        .module         = THIS_MODULE,
1693        .auto_attach    = me4000_auto_attach,
1694        .detach         = me4000_detach,
1695};
1696
1697static int me4000_pci_probe(struct pci_dev *dev,
1698                            const struct pci_device_id *id)
1699{
1700        return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data);
1701}
1702
1703static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
1704        { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 },
1705        { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 },
1706        { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I },
1707        { PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S },
1708        { PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS },
1709        { PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 },
1710        { PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I },
1711        { PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S },
1712        { PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS },
1713        { PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 },
1714        { PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I },
1715        { PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S },
1716        { PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS },
1717        { 0 }
1718};
1719MODULE_DEVICE_TABLE(pci, me4000_pci_table);
1720
1721static struct pci_driver me4000_pci_driver = {
1722        .name           = "me4000",
1723        .id_table       = me4000_pci_table,
1724        .probe          = me4000_pci_probe,
1725        .remove         = comedi_pci_auto_unconfig,
1726};
1727module_comedi_pci_driver(me4000_driver, me4000_pci_driver);
1728
1729MODULE_AUTHOR("Comedi http://www.comedi.org");
1730MODULE_DESCRIPTION("Comedi low-level driver");
1731MODULE_LICENSE("GPL");
1732