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