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