1e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef/* 2e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef comedi/drivers/ni_pcidio.c 3e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef driver for National Instruments PCI-DIO-96/PCI-6508 42d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi National Instruments PCI-DIO-32HS 52d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi National Instruments PCI-6503 6e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 7e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef COMEDI - Linux Control and Measurement Device Interface 8e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org> 9e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 10e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef This program is free software; you can redistribute it and/or modify 11e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef it under the terms of the GNU General Public License as published by 12e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef the Free Software Foundation; either version 2 of the License, or 13e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef (at your option) any later version. 14e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 15e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef This program is distributed in the hope that it will be useful, 16e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef but WITHOUT ANY WARRANTY; without even the implied warranty of 17e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef GNU General Public License for more details. 19e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 20e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef You should have received a copy of the GNU General Public License 21e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef along with this program; if not, write to the Free Software 22e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 24e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef*/ 25e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef/* 26e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefDriver: ni_pcidio 27e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefDescription: National Instruments PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503 28e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefAuthor: ds 29e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefStatus: works 30e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefDevices: [National Instruments] PCI-DIO-32HS (ni_pcidio), PXI-6533, 31e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X, 32e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef PXI-6503, PCI-6533, PCI-6534 3322494ed9b8e9404d6646f85c835bcd7b37d3f562Ian AbbottUpdated: Mon, 09 Jan 2012 14:27:23 +0000 34e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 35e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefThe DIO-96 appears as four 8255 subdevices. See the 8255 36e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefdriver notes for details. 37e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 38e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefThe DIO32HS board appears as one subdevice, with 32 channels. 39e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefEach channel is individually I/O configurable. The channel order 40e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefis 0=A0, 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0. The driver only 41e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefsupports simple digital I/O; no handshaking is supported. 42e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 43e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefDMA mostly works for the PCI-DIO32HS, but only in timed input mode. 44e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 4522494ed9b8e9404d6646f85c835bcd7b37d3f562Ian AbbottThe PCI-DIO-32HS/PCI-6533 has a configurable external trigger. Setting 4622494ed9b8e9404d6646f85c835bcd7b37d3f562Ian Abbottscan_begin_arg to 0 or CR_EDGE triggers on the leading edge. Setting 4722494ed9b8e9404d6646f85c835bcd7b37d3f562Ian Abbottscan_begin_arg to CR_INVERT or (CR_EDGE | CR_INVERT) triggers on the 4822494ed9b8e9404d6646f85c835bcd7b37d3f562Ian Abbotttrailing edge. 4922494ed9b8e9404d6646f85c835bcd7b37d3f562Ian Abbott 50e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefThis driver could be easily modified to support AT-MIO32HS and 51e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefAT-MIO96. 52e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 53e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefThe PCI-6534 requires a firmware upload after power-up to work, the 54e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleeffirmware data and instructions for loading it with comedi_config 55e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefit are contained in the 56e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefcomedi_nonfree_firmware tarball available from http://www.comedi.org 57e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef*/ 58e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 59e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef/* 60e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef This driver is for both the NI PCI-DIO-32HS and the PCI-DIO-96, 61e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef which have very different architectures. But, since the '96 is 62e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef so simple, it is included here. 63e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 64e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef Manuals (available from ftp://ftp.natinst.com/support/manuals) 65e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 66e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 320938c.pdf PCI-DIO-96/PXI-6508/PCI-6503 User Manual 67e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 321464b.pdf AT/PCI-DIO-32HS User Manual 68e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 341329A.pdf PCI-6533 Register-Level Programmer Manual 69e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 341330A.pdf DAQ-DIO Technical Reference Manual 70e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 71e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef */ 72e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 73e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define USE_DMA 7456e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton/* #define DEBUG 1 */ 7556e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton/* #define DEBUG_FLAGS */ 76e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 7725436dc9d84f1be60ff549c9ab712bba2835f284Greg Kroah-Hartman#include <linux/interrupt.h> 784377a026500a3f59e9c41c23d03e55ff2e712379Greg Kroah-Hartman#include <linux/sched.h> 79e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#include "../comedidev.h" 80e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 81e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#include "mite.h" 82e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#include "8255.h" 83e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 84e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#undef DPRINTK 85e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef DEBUG 86e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DPRINTK(format, args...) printk(format, ## args) 87e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#else 88e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DPRINTK(format, args...) 89e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif 90e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 91e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define PCI_DIO_SIZE 4096 92e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define PCI_MITE_SIZE 4096 93e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 94e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef/* defines for the PCI-DIO-96 */ 95e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 96e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define NIDIO_8255_BASE(x) ((x)*4) 97e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define NIDIO_A 0 98e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define NIDIO_B 4 99e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define NIDIO_C 8 100e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define NIDIO_D 12 101e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 102e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef/* defines for the PCI-DIO-32HS */ 103e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 104e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Window_Address 4 /* W */ 105e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Interrupt_And_Window_Status 4 /* R */ 106e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define IntStatus1 (1<<0) 107e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define IntStatus2 (1<<1) 108e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define WindowAddressStatus_mask 0x7c 109e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 110e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Master_DMA_And_Interrupt_Control 5 /* W */ 111e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InterruptLine(x) ((x)&3) 112e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define OpenInt (1<<2) 113e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_Status 5 /* R */ 114e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DataLeft (1<<0) 115e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Req (1<<2) 116e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define StopTrig (1<<3) 117e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 118e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_1_Flags 6 /* R */ 119e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_2_Flags 7 /* R */ 120e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define TransferReady (1<<0) 121e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define CountExpired (1<<1) 122e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Waited (1<<5) 123e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define PrimaryTC (1<<6) 124e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define SecondaryTC (1<<7) 12556e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* #define SerialRose */ 12656e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* #define ReqRose */ 12756e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* #define Paused */ 128e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 129e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_1_First_Clear 6 /* W */ 130e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_2_First_Clear 7 /* W */ 131e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClearWaited (1<<3) 132e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClearPrimaryTC (1<<4) 133e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClearSecondaryTC (1<<5) 134e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DMAReset (1<<6) 135e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define FIFOReset (1<<7) 136e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClearAll 0xf8 137e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 138e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_1_FIFO 8 /* W */ 139e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_2_FIFO 12 /* W */ 140e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 141e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Transfer_Count 20 142e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Chip_ID_D 24 143e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Chip_ID_I 25 144e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Chip_ID_O 26 145e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Chip_Version 27 146e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Port_IO(x) (28+(x)) 147e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Port_Pin_Directions(x) (32+(x)) 148e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Port_Pin_Mask(x) (36+(x)) 149e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Port_Pin_Polarities(x) (40+(x)) 150e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 151e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Master_Clock_Routing 45 152e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define RTSIClocking(x) (((x)&3)<<4) 153e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 154e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_1_Second_Clear 46 /* W */ 155e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_2_Second_Clear 47 /* W */ 156e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClearExpired (1<<0) 157e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 158e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Port_Pattern(x) (48+(x)) 159e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 160e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Data_Path 64 161e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define FIFOEnableA (1<<0) 162e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define FIFOEnableB (1<<1) 163e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define FIFOEnableC (1<<2) 164e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define FIFOEnableD (1<<3) 165e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Funneling(x) (((x)&3)<<4) 166e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define GroupDirection (1<<7) 167e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 168e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_1 65 169e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define OpMode Protocol_Register_1 170e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define RunMode(x) ((x)&7) 171e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Numbered (1<<3) 172e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 173e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_2 66 174e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClockReg Protocol_Register_2 175e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClockLine(x) (((x)&3)<<5) 176e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertStopTrig (1<<7) 177e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DataLatching(x) (((x)&3)<<5) 178e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 179e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_3 67 180e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Sequence Protocol_Register_3 181e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 182e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_14 68 /* 16 bit */ 183e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClockSpeed Protocol_Register_14 184e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 185e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_4 70 186e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ReqReg Protocol_Register_4 187e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ReqConditioning(x) (((x)&7)<<3) 188e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 189e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_5 71 190e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define BlockMode Protocol_Register_5 191e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 192e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define FIFO_Control 72 193e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ReadyLevel(x) ((x)&7) 194e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 195e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_6 73 196e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define LinePolarities Protocol_Register_6 197e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertAck (1<<0) 198e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertReq (1<<1) 199e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertClock (1<<2) 200e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertSerial (1<<3) 201e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define OpenAck (1<<4) 202e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define OpenClock (1<<5) 203e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 204e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_7 74 205e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define AckSer Protocol_Register_7 206e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define AckLine(x) (((x)&3)<<2) 207e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ExchangePins (1<<7) 208e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 209e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Interrupt_Control 75 210e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* bits same as flags */ 211e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 212e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DMA_Line_Control_Group1 76 213e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DMA_Line_Control_Group2 108 21456e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton/* channel zero is none */ 215e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic inline unsigned primary_DMAChannel_bits(unsigned channel) 216e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 217e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return channel & 0x3; 218e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 2190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral 220e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic inline unsigned secondary_DMAChannel_bits(unsigned channel) 221e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 222e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return (channel << 2) & 0xc; 223e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 224e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 225e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Transfer_Size_Control 77 226e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define TransferWidth(x) ((x)&3) 227e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define TransferLength(x) (((x)&3)<<3) 228e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define RequireRLevel (1<<5) 229e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 230e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_15 79 231e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DAQOptions Protocol_Register_15 232e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define StartSource(x) ((x)&0x3) 233e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertStart (1<<2) 234e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define StopSource(x) (((x)&0x3)<<3) 235e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ReqStart (1<<6) 236e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define PreStart (1<<7) 237e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 238e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Pattern_Detection 81 239e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DetectionMethod (1<<0) 240e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertMatch (1<<1) 241e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define IE_Pattern_Detection (1<<2) 242e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 243e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_9 82 244e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ReqDelay Protocol_Register_9 245e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 246e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_10 83 247e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ReqNotDelay Protocol_Register_10 248e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 249e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_11 84 250e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define AckDelay Protocol_Register_11 251e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 252e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_12 85 253e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define AckNotDelay Protocol_Register_12 254e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 255e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_13 86 256e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Data1Delay Protocol_Register_13 257e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 258e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_8 88 /* 32 bit */ 259e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define StartDelay Protocol_Register_8 260e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 261e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefenum pci_6534_firmware_registers { /* 16 bit */ 262e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef Firmware_Control_Register = 0x100, 263e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef Firmware_Status_Register = 0x104, 264e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef Firmware_Data_Register = 0x108, 265e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef Firmware_Mask_Register = 0x10c, 266e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef Firmware_Debug_Register = 0x110, 267e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}; 268e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef/* main fpga registers (32 bit)*/ 269e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefenum pci_6534_fpga_registers { 270e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_Control1_Register = 0x200, 271e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_Control2_Register = 0x204, 272e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_Irq_Mask_Register = 0x208, 273e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_Status_Register = 0x20c, 274e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_Signature_Register = 0x210, 275e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_SCALS_Counter_Register = 0x280, /*write-clear */ 276e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_SCAMS_Counter_Register = 0x284, /*write-clear */ 277e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_SCBLS_Counter_Register = 0x288, /*write-clear */ 278e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_SCBMS_Counter_Register = 0x28c, /*write-clear */ 279e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_Temp_Control_Register = 0x2a0, 280e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_DAR_Register = 0x2a8, 281e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_ELC_Read_Register = 0x2b8, 282e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_ELC_Write_Register = 0x2bc, 283e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}; 284e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefenum FPGA_Control_Bits { 285e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef FPGA_Enable_Bit = 0x8000, 286e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}; 287e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 288e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define TIMER_BASE 50 /* nanoseconds */ 289e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 290e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef USE_DMA 291e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define IntEn (CountExpired|Waited|PrimaryTC|SecondaryTC) 292e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#else 293e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define IntEn (TransferReady|CountExpired|Waited|PrimaryTC|SecondaryTC) 294e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif 295e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 296da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it); 297da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int nidio_detach(struct comedi_device *dev); 2980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni_pcidio_cancel(struct comedi_device *dev, 2990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 300e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 301139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_pcidio = { 30268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "ni_pcidio", 30368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 30468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = nidio_attach, 30568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = nidio_detach, 306e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}; 307e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 308a7195f3d92f5fc560e597598a56d9c394b65ee81Bill Pembertonstruct nidio_board { 309a7195f3d92f5fc560e597598a56d9c394b65ee81Bill Pemberton 310e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int dev_id; 311e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef const char *name; 312e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int n_8255; 313e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef unsigned int is_diodaq:1; 314e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef unsigned int uses_firmware:1; 315a7195f3d92f5fc560e597598a56d9c394b65ee81Bill Pemberton}; 316a7195f3d92f5fc560e597598a56d9c394b65ee81Bill Pemberton 317a7195f3d92f5fc560e597598a56d9c394b65ee81Bill Pembertonstatic const struct nidio_board nidio_boards[] = { 318e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef { 3190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .dev_id = 0x1150, 3200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-dio-32hs", 3210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_8255 = 0, 3220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .is_diodaq = 1, 3230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 324e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef { 3250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .dev_id = 0x1320, 3260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pxi-6533", 3270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_8255 = 0, 3280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .is_diodaq = 1, 3290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 330e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef { 3310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .dev_id = 0x12b0, 3320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-6534", 3330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_8255 = 0, 3340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .is_diodaq = 1, 3350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .uses_firmware = 1, 3360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 337e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef { 3380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .dev_id = 0x0160, 3390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-dio-96", 3400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_8255 = 4, 3410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .is_diodaq = 0, 3420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 343e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef { 3440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .dev_id = 0x1630, 3450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-dio-96b", 3460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_8255 = 4, 3470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .is_diodaq = 0, 3480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 349e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef { 3500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .dev_id = 0x13c0, 3510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pxi-6508", 3520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_8255 = 4, 3530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .is_diodaq = 0, 3540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 355e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef { 3560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .dev_id = 0x0400, 3570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-6503", 3580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_8255 = 1, 3590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .is_diodaq = 0, 3600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 361e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef { 3620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .dev_id = 0x1250, 3630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-6503b", 3640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_8255 = 1, 3650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .is_diodaq = 0, 3660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 367e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef { 3680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .dev_id = 0x17d0, 3690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-6503x", 3700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_8255 = 1, 3710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .is_diodaq = 0, 3720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 373e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef { 3740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .dev_id = 0x1800, 3750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pxi-6503", 3760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_8255 = 1, 3770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .is_diodaq = 0, 3780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 379e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}; 380e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 381b6ac161364eccce1bea4a23a9de395883e90d7abStoyan Gaydarov#define n_nidio_boards ARRAY_SIZE(nidio_boards) 382a7195f3d92f5fc560e597598a56d9c394b65ee81Bill Pemberton#define this_board ((const struct nidio_board *)dev->board_ptr) 383e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 384e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = { 3854e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1150)}, 3864e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1320)}, 3874e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x12b0)}, 3884e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0160)}, 3894e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1630)}, 3904e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x13c0)}, 3914e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0400)}, 3924e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1250)}, 3934e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x17d0)}, 3944e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1800)}, 3954e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman {0} 396e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}; 397e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 398e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefMODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table); 399e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 4002e93aa5b5b8050090a22e162f9af6b18ca3ec47aBill Pembertonstruct nidio96_private { 401e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef struct mite_struct *mite; 402e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int boardtype; 403e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int dio; 404e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef unsigned short OpModeBits; 405e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef struct mite_channel *di_mite_chan; 406e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef struct mite_dma_descriptor_ring *di_mite_ring; 407e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef spinlock_t mite_channel_lock; 4082e93aa5b5b8050090a22e162f9af6b18ca3ec47aBill Pemberton}; 4092e93aa5b5b8050090a22e162f9af6b18ca3ec47aBill Pemberton#define devpriv ((struct nidio96_private *)dev->private) 410e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 4110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni_pcidio_cmdtest(struct comedi_device *dev, 4120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd); 414da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s); 4150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni_pcidio_inttrig(struct comedi_device *dev, 4160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, unsigned int trignum); 417da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int nidio_find_device(struct comedi_device *dev, int bus, int slot); 418e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic int ni_pcidio_ns_to_timer(int *nanosec, int round_mode); 4190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int setup_mite_dma(struct comedi_device *dev, 4200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 421e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 422e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef DEBUG_FLAGS 423e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic void ni_pcidio_print_flags(unsigned int flags); 424e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic void ni_pcidio_print_status(unsigned int status); 425e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#else 426e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ni_pcidio_print_flags(x) 427e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ni_pcidio_print_status(x) 428e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif 429e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 430da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni_pcidio_request_di_mite_channel(struct comedi_device *dev) 431e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 432e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef unsigned long flags; 433e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 4345f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&devpriv->mite_channel_lock, flags); 435e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef BUG_ON(devpriv->di_mite_chan); 436e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef devpriv->di_mite_chan = 4370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral mite_request_channel_in_range(devpriv->mite, 4380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->di_mite_ring, 1, 2); 439e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (devpriv->di_mite_chan == NULL) { 4405f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); 441e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef comedi_error(dev, "failed to reserve mite dma channel."); 442e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return -EBUSY; 443e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 444e3794b52f56ac20947a2dbdd505e9ad29013c555Ian Abbott devpriv->di_mite_chan->dir = COMEDI_INPUT; 445e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) | 4460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral secondary_DMAChannel_bits(devpriv->di_mite_chan->channel), 4470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + DMA_Line_Control_Group1); 448e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef mmiowb(); 4495f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); 450e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 0; 451e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 452e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 453da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void ni_pcidio_release_di_mite_channel(struct comedi_device *dev) 454e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 455e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef unsigned long flags; 456e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 4575f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&devpriv->mite_channel_lock, flags); 458e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (devpriv->di_mite_chan) { 459e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef mite_dma_disarm(devpriv->di_mite_chan); 460e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef mite_dma_reset(devpriv->di_mite_chan); 461e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef mite_release_channel(devpriv->di_mite_chan); 462e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef devpriv->di_mite_chan = NULL; 463e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(primary_DMAChannel_bits(0) | 4640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral secondary_DMAChannel_bits(0), 4650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + DMA_Line_Control_Group1); 466e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef mmiowb(); 467e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 4685f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); 469e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 470e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 471e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic int nidio96_8255_cb(int dir, int port, int data, unsigned long iobase) 472e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 473e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (dir) { 474e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(data, (void *)(iobase + port)); 475e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 0; 476e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } else { 477e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return readb((void *)(iobase + port)); 478e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 479e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 480e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 481da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonvoid ni_pcidio_event(struct comedi_device *dev, struct comedi_subdevice *s) 482e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 4830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral if (s-> 4840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | 4850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral COMEDI_CB_OVERFLOW)) { 486e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ni_pcidio_cancel(dev, s); 487e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 488e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef comedi_event(dev, s); 489e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 490e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 49102f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbottstatic int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s) 49202f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott{ 49302f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott unsigned long irq_flags; 49402f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott int count; 49502f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott 49602f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott spin_lock_irqsave(&dev->spinlock, irq_flags); 49702f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott spin_lock(&devpriv->mite_channel_lock); 49802f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott if (devpriv->di_mite_chan) 49902f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott mite_sync_input_dma(devpriv->di_mite_chan, s->async); 50002f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott spin_unlock(&devpriv->mite_channel_lock); 50102f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott count = s->async->buf_write_count - s->async->buf_read_count; 50202f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott spin_unlock_irqrestore(&dev->spinlock, irq_flags); 50302f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott return count; 50402f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott} 50502f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott 50670265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t nidio_interrupt(int irq, void *d) 507e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 50871b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton struct comedi_device *dev = d; 50934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s = dev->subdevices; 510d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 511e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef struct mite_struct *mite = devpriv->mite; 512e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 51356e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* int i, j; */ 514e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef long int AuxData = 0; 515790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short data1 = 0; 516790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short data2 = 0; 517e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int flags; 518e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int status; 519e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int work = 0; 520e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef unsigned int m_status = 0; 521e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 52256e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* interrupcions parasites */ 523e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (dev->attached == 0) { 52456e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* assume it's from another card */ 525e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return IRQ_NONE; 526e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 527e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 52802f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott /* Lock to avoid race with comedi_poll */ 52902f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott spin_lock(&dev->spinlock); 53002f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott 531e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef status = readb(devpriv->mite->daq_io_addr + 5320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Interrupt_And_Window_Status); 533e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags); 534e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 535e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n", 536e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef status, flags); 537e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ni_pcidio_print_flags(flags); 538e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ni_pcidio_print_status(status); 539e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 54056e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf); */ 5412d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi /* printk("buf[4096]=%08x\n", 5422d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi *(unsigned int *)(async->prealloc_buf+4096)); */ 543e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 54402f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott spin_lock(&devpriv->mite_channel_lock); 545e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (devpriv->di_mite_chan) 546e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef m_status = mite_get_status(devpriv->di_mite_chan); 547e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef MITE_DEBUG 548e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef mite_print_chsr(m_status); 549e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif 5502d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi /* printk("mite_bytes_transferred: %d\n", 5512d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi mite_bytes_transferred(mite,DI_DMA_CHAN)); */ 5522d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi 55356e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* mite_dump_regs(mite); */ 554e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (m_status & CHSR_INT) { 555e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (m_status & CHSR_LINKC) { 556e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(CHOR_CLRLC, 5570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral mite->mite_io_addr + 5580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral MITE_CHOR(devpriv->di_mite_chan->channel)); 559e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef mite_sync_input_dma(devpriv->di_mite_chan, s->async); 560e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* XXX need to byteswap */ 561e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 562e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY | 5630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CHSR_DRQ1 | CHSR_MRDY)) { 564e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef DPRINTK("unknown mite interrupt, disabling IRQ\n"); 565e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 566e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef disable_irq(dev->irq); 567e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 568e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 56902f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott spin_unlock(&devpriv->mite_channel_lock); 570e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 571e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef while (status & DataLeft) { 572e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef work++; 573e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (work > 20) { 574e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef DPRINTK("too much work in interrupt\n"); 575e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x00, 5760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + 5770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Master_DMA_And_Interrupt_Control); 578e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef break; 579e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 580e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 581e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef flags &= IntEn; 582e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 583e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (flags & TransferReady) { 58456e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* DPRINTK("TransferReady\n"); */ 585e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef while (flags & TransferReady) { 586e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef work++; 587e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (work > 100) { 588e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef DPRINTK("too much work in interrupt\n"); 589e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x00, 5900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + 5912d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi Master_DMA_And_Interrupt_Control 5922d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi ); 593e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef goto out; 594e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 595e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef AuxData = 5960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral readl(devpriv->mite->daq_io_addr + 5970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Group_1_FIFO); 598e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef data1 = AuxData & 0xffff; 599e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef data2 = (AuxData & 0xffff0000) >> 16; 600e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef comedi_buf_put(async, data1); 601e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef comedi_buf_put(async, data2); 60256e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* DPRINTK("read:%d, %d\n",data1,data2); */ 603e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef flags = readb(devpriv->mite->daq_io_addr + 6040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Group_1_Flags); 605e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 6062d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi /* DPRINTK("buf_int_count: %d\n", 6072d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi async->buf_int_count); */ 6082d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi /* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n", 6092d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi IntEn,flags,status); */ 61056e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* ni_pcidio_print_flags(flags); */ 61156e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* ni_pcidio_print_status(status); */ 612e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef async->events |= COMEDI_CB_BLOCK; 613e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 614e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 615e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (flags & CountExpired) { 616e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef DPRINTK("CountExpired\n"); 617e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(ClearExpired, 6180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + 6190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Group_1_Second_Clear); 620e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef async->events |= COMEDI_CB_EOA; 621e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 622e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x00, devpriv->mite->daq_io_addr + OpMode); 623e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef break; 624e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } else if (flags & Waited) { 625e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef DPRINTK("Waited\n"); 626e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(ClearWaited, 6270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + 6280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Group_1_First_Clear); 629e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 630e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef break; 631e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } else if (flags & PrimaryTC) { 632e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef DPRINTK("PrimaryTC\n"); 633e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(ClearPrimaryTC, 6340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + 6350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Group_1_First_Clear); 636e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef async->events |= COMEDI_CB_EOA; 637e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } else if (flags & SecondaryTC) { 638e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef DPRINTK("SecondaryTC\n"); 639e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(ClearSecondaryTC, 6400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + 6410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Group_1_First_Clear); 642e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef async->events |= COMEDI_CB_EOA; 643e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 644e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#if 0 645e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef else { 646e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef printk("ni_pcidio: unknown interrupt\n"); 647e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 648e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x00, 6490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + 6500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Master_DMA_And_Interrupt_Control); 651e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 652e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif 653e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags); 654e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef status = readb(devpriv->mite->daq_io_addr + 6550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Interrupt_And_Window_Status); 6562d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi /* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x," 6572d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi "status=0x%02x\n", IntEn, flags, status); */ 65856e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* ni_pcidio_print_flags(flags); */ 65956e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton /* ni_pcidio_print_status(status); */ 660e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 661e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 6620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralout: 663e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ni_pcidio_event(dev, s); 664e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#if 0 665e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (!tag) { 666e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x03, 6670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + 6680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Master_DMA_And_Interrupt_Control); 669e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 670e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif 67102f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott 67202f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott spin_unlock(&dev->spinlock); 673e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return IRQ_HANDLED; 674e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 675e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 676e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef DEBUG_FLAGS 677e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic const char *const flags_strings[] = { 678e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef "TransferReady", "CountExpired", "2", "3", 679e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef "4", "Waited", "PrimaryTC", "SecondaryTC", 680e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}; 6810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral 682e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic void ni_pcidio_print_flags(unsigned int flags) 683e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 684e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int i; 685e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 6862d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi printk(KERN_INFO "group_1_flags:"); 687e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef for (i = 7; i >= 0; i--) { 6882d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi if (flags & (1 << i)) 689e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef printk(" %s", flags_strings[i]); 690e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 691e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef printk("\n"); 692e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 6930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral 694e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic char *status_strings[] = { 695e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef "DataLeft1", "Reserved1", "Req1", "StopTrig1", 696e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef "DataLeft2", "Reserved2", "Req2", "StopTrig2", 697e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}; 6980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral 699e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic void ni_pcidio_print_status(unsigned int flags) 700e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 701e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int i; 702e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 7032d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi printk(KERN_INFO "group_status:"); 704e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef for (i = 7; i >= 0; i--) { 7052d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi if (flags & (1 << i)) 706e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef printk(" %s", status_strings[i]); 707e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 708e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef printk("\n"); 709e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 710e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif 711e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 712e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef unused 7130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void debug_int(struct comedi_device *dev) 714e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 715e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int a, b; 71613a9e03c0c209b59f07b72c5388845a5f55eda2aBojan Prtvar static int n_int; 717e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef struct timeval tv; 718e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 719e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef do_gettimeofday(&tv); 720e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef a = readb(devpriv->mite->daq_io_addr + Group_Status); 721e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef b = readb(devpriv->mite->daq_io_addr + Group_1_Flags); 722e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 723e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (n_int < 10) { 724e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef DPRINTK("status 0x%02x flags 0x%02x time %06d\n", a, b, 725e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef (int)tv.tv_usec); 726e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 727e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 728e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef while (b & 1) { 729e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writew(0xff, devpriv->mite->daq_io_addr + Group_1_FIFO); 730e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef b = readb(devpriv->mite->daq_io_addr + Group_1_Flags); 731e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 732e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 733e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef b = readb(devpriv->mite->daq_io_addr + Group_1_Flags); 734e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 735e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (n_int < 10) { 736e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef DPRINTK("new status 0x%02x\n", b); 737e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef n_int++; 738e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 739e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 740e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif 741e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 7420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni_pcidio_insn_config(struct comedi_device *dev, 7430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 7440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 745e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 746e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (insn->n != 1) 747e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return -EINVAL; 748e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef switch (data[0]) { 749e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef case INSN_CONFIG_DIO_OUTPUT: 750e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->io_bits |= 1 << CR_CHAN(insn->chanspec); 751e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef break; 752e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef case INSN_CONFIG_DIO_INPUT: 753e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->io_bits &= ~(1 << CR_CHAN(insn->chanspec)); 754e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef break; 755e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef case INSN_CONFIG_DIO_QUERY: 756e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef data[1] = 7570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (s-> 7580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT : 7590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral COMEDI_INPUT; 760e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return insn->n; 761e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef break; 762e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef default: 763e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return -EINVAL; 764e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 765e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0)); 766e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 767e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 1; 768e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 769e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 7700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni_pcidio_insn_bits(struct comedi_device *dev, 7710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 7720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 773e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 774e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (insn->n != 2) 775e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return -EINVAL; 776e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (data[0]) { 777e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->state &= ~data[0]; 778e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->state |= (data[0] & data[1]); 779e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0)); 780e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 781e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0)); 782e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 783e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 2; 784e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 785e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 7860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni_pcidio_cmdtest(struct comedi_device *dev, 7870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_cmd *cmd) 788e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 789e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int err = 0; 790e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int tmp; 791e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 792e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* step 1: make sure trigger sources are trivially valid */ 793e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 794e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef tmp = cmd->start_src; 795e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef cmd->start_src &= TRIG_NOW | TRIG_INT; 796e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (!cmd->start_src || tmp != cmd->start_src) 797e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 798e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 799e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef tmp = cmd->scan_begin_src; 800e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; 801e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 802e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 803e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 804e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef tmp = cmd->convert_src; 805e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef cmd->convert_src &= TRIG_NOW; 806e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (!cmd->convert_src || tmp != cmd->convert_src) 807e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 808e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 809e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef tmp = cmd->scan_end_src; 810e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef cmd->scan_end_src &= TRIG_COUNT; 811e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 812e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 813e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 814e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef tmp = cmd->stop_src; 815e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 816e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (!cmd->stop_src || tmp != cmd->stop_src) 817e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 818e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 819e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (err) 820e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 1; 821e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 8222d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi /* step 2: make sure trigger sources are unique and mutually 8232d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi compatible */ 824e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 825828684f9a6e096f9150bad523c43b75d74b9baddDirk Hohndel /* note that mutual compatibility is not an issue here */ 826e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT) 827e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 828e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->scan_begin_src != TRIG_TIMER && 8290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_src != TRIG_EXT) 830e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 831e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 832e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (err) 833e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 2; 834e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 835e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* step 3: make sure arguments are trivially compatible */ 836e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 837e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->start_arg != 0) { 838e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* same for both TRIG_INT and TRIG_NOW */ 839e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef cmd->start_arg = 0; 840e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 841e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 842e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define MAX_SPEED (TIMER_BASE) /* in nanoseconds */ 843e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 844e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER) { 845e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->scan_begin_arg < MAX_SPEED) { 846e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef cmd->scan_begin_arg = MAX_SPEED; 847e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 848e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 84925985edcedea6396277003854657b5f3cb31a628Lucas De Marchi /* no minimum speed */ 850e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } else { 851e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* TRIG_EXT */ 852e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* should be level/edge, hi/lo specification here */ 85322494ed9b8e9404d6646f85c835bcd7b37d3f562Ian Abbott if ((cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) != 0) { 85422494ed9b8e9404d6646f85c835bcd7b37d3f562Ian Abbott cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT); 855e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 856e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 857e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 858e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->convert_arg != 0) { 859e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef cmd->convert_arg = 0; 860e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 861e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 862e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 863e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->scan_end_arg != cmd->chanlist_len) { 864e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef cmd->scan_end_arg = cmd->chanlist_len; 865e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 866e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 867e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->stop_src == TRIG_COUNT) { 868e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* no limit */ 869e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } else { 870e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* TRIG_NONE */ 871e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->stop_arg != 0) { 872e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef cmd->stop_arg = 0; 873e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 874e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 875e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 876e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 877e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (err) 878e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 3; 879e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 880e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* step 4: fix up any arguments */ 881e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 882e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER) { 883e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef tmp = cmd->scan_begin_arg; 884e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ni_pcidio_ns_to_timer(&cmd->scan_begin_arg, 8850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 886e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (tmp != cmd->scan_begin_arg) 887e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef err++; 888e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 889e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 890e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (err) 891e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 4; 892e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 893e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 0; 894e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 895e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 896e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic int ni_pcidio_ns_to_timer(int *nanosec, int round_mode) 897e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 898e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int divider, base; 899e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 900e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef base = TIMER_BASE; 901e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 902e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef switch (round_mode) { 903e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef case TRIG_ROUND_NEAREST: 904e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef default: 905e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef divider = (*nanosec + base / 2) / base; 906e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef break; 907e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef case TRIG_ROUND_DOWN: 908e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef divider = (*nanosec) / base; 909e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef break; 910e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef case TRIG_ROUND_UP: 911e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef divider = (*nanosec + base - 1) / base; 912e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef break; 913e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 914e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 915e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef *nanosec = base * divider; 916e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return divider; 917e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 918e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 9190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 920e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 921ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 922e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 923e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* XXX configure ports for input */ 924e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0)); 925e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 926e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (1) { 927e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* enable fifos A B C D */ 928e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path); 929e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 930e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* set transfer width a 32 bits */ 931e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(TransferWidth(0) | TransferLength(0), 9320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + Transfer_Size_Control); 933e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } else { 934e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x03, devpriv->mite->daq_io_addr + Data_Path); 935e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(TransferWidth(3) | TransferLength(0), 9360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + Transfer_Size_Control); 937e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 938e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 939e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* protocol configuration */ 940e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER) { 941e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* page 4-5, "input with internal REQs" */ 942e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0, devpriv->mite->daq_io_addr + OpMode); 943e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x00, devpriv->mite->daq_io_addr + ClockReg); 944e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(1, devpriv->mite->daq_io_addr + Sequence); 945e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x04, devpriv->mite->daq_io_addr + ReqReg); 946e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(4, devpriv->mite->daq_io_addr + BlockMode); 947e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(3, devpriv->mite->daq_io_addr + LinePolarities); 948e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0xc0, devpriv->mite->daq_io_addr + AckSer); 949e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg, 9500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral TRIG_ROUND_NEAREST), 9510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + StartDelay); 952e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(1, devpriv->mite->daq_io_addr + ReqDelay); 953e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay); 954e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(1, devpriv->mite->daq_io_addr + AckDelay); 955e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay); 956e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay); 957e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* manual, page 4-5: ClockSpeed comment is incorrectly listed 958e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef * on DAQOptions */ 959e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writew(0, devpriv->mite->daq_io_addr + ClockSpeed); 960e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0, devpriv->mite->daq_io_addr + DAQOptions); 961e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } else { 962e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* TRIG_EXT */ 963e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* page 4-5, "input with external REQs" */ 964e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0, devpriv->mite->daq_io_addr + OpMode); 965e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x00, devpriv->mite->daq_io_addr + ClockReg); 966e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0, devpriv->mite->daq_io_addr + Sequence); 967e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x00, devpriv->mite->daq_io_addr + ReqReg); 968e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(4, devpriv->mite->daq_io_addr + BlockMode); 96922494ed9b8e9404d6646f85c835bcd7b37d3f562Ian Abbott if (!(cmd->scan_begin_arg & CR_INVERT)) { 97022494ed9b8e9404d6646f85c835bcd7b37d3f562Ian Abbott /* Leading Edge pulse mode */ 97122494ed9b8e9404d6646f85c835bcd7b37d3f562Ian Abbott writeb(0, devpriv->mite->daq_io_addr + LinePolarities); 97222494ed9b8e9404d6646f85c835bcd7b37d3f562Ian Abbott } else { 97322494ed9b8e9404d6646f85c835bcd7b37d3f562Ian Abbott /* Trailing Edge pulse mode */ 97422494ed9b8e9404d6646f85c835bcd7b37d3f562Ian Abbott writeb(2, devpriv->mite->daq_io_addr + LinePolarities); 97522494ed9b8e9404d6646f85c835bcd7b37d3f562Ian Abbott } 976e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x00, devpriv->mite->daq_io_addr + AckSer); 977e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(1, devpriv->mite->daq_io_addr + StartDelay); 978e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(1, devpriv->mite->daq_io_addr + ReqDelay); 979e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay); 980e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(1, devpriv->mite->daq_io_addr + AckDelay); 981e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay); 982e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay); 983e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writew(0, devpriv->mite->daq_io_addr + ClockSpeed); 984e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions); 985e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 986e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 987e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->stop_src == TRIG_COUNT) { 988e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(cmd->stop_arg, 9890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + Transfer_Count); 990e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } else { 991e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* XXX */ 992e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 993e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 994e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef USE_DMA 995e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(ClearPrimaryTC | ClearSecondaryTC, 9960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + Group_1_First_Clear); 997e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 998e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef { 999e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int retval = setup_mite_dma(dev, s); 1000e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (retval) 1001e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return retval; 1002e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1003e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#else 1004e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1); 1005e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif 1006e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2); 1007e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1008e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* clear and enable interrupts */ 1009e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear); 10102d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi /* writeb(ClearExpired, 10112d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi devpriv->mite->daq_io_addr+Group_1_Second_Clear); */ 1012e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1013e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control); 1014e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x03, 10150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control); 1016e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1017e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->stop_src == TRIG_NONE) { 1018e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef devpriv->OpModeBits = DataLatching(0) | RunMode(7); 101956e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton } else { /* TRIG_TIMER */ 1020e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef devpriv->OpModeBits = Numbered | RunMode(7); 1021e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1022e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (cmd->start_src == TRIG_NOW) { 1023e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* start */ 1024e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(devpriv->OpModeBits, 10250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + OpMode); 1026e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->async->inttrig = NULL; 1027e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } else { 1028e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* TRIG_INT */ 1029e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->async->inttrig = ni_pcidio_inttrig; 1030e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1031e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1032e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef DPRINTK("ni_pcidio: command started\n"); 1033e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 0; 1034e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 1035e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 10360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s) 1037e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 1038e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int retval; 1039e3794b52f56ac20947a2dbdd505e9ad29013c555Ian Abbott unsigned long flags; 1040e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1041e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef retval = ni_pcidio_request_di_mite_channel(dev); 1042e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (retval) 1043e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return retval; 1044e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 104541add2e84bff0c887949698e01dab28105f11a6bIan Abbott /* write alloc the entire buffer */ 104641add2e84bff0c887949698e01dab28105f11a6bIan Abbott comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz); 104741add2e84bff0c887949698e01dab28105f11a6bIan Abbott 1048e3794b52f56ac20947a2dbdd505e9ad29013c555Ian Abbott spin_lock_irqsave(&devpriv->mite_channel_lock, flags); 1049e3794b52f56ac20947a2dbdd505e9ad29013c555Ian Abbott if (devpriv->di_mite_chan) { 1050e3794b52f56ac20947a2dbdd505e9ad29013c555Ian Abbott mite_prep_dma(devpriv->di_mite_chan, 32, 32); 1051e3794b52f56ac20947a2dbdd505e9ad29013c555Ian Abbott mite_dma_arm(devpriv->di_mite_chan); 1052e3794b52f56ac20947a2dbdd505e9ad29013c555Ian Abbott } else 1053e3794b52f56ac20947a2dbdd505e9ad29013c555Ian Abbott retval = -EIO; 1054e3794b52f56ac20947a2dbdd505e9ad29013c555Ian Abbott spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); 1055e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1056e3794b52f56ac20947a2dbdd505e9ad29013c555Ian Abbott return retval; 1057e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 1058e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 10590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni_pcidio_inttrig(struct comedi_device *dev, 10600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, unsigned int trignum) 1061e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 1062e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (trignum != 0) 1063e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return -EINVAL; 1064e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1065e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(devpriv->OpModeBits, devpriv->mite->daq_io_addr + OpMode); 1066e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->async->inttrig = NULL; 1067e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1068e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 1; 1069e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 1070e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 10710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni_pcidio_cancel(struct comedi_device *dev, 10720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 1073e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 1074e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x00, 10750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control); 1076e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ni_pcidio_release_di_mite_channel(dev); 1077e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1078e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 0; 1079e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 1080e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 10810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni_pcidio_change(struct comedi_device *dev, 10820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, unsigned long new_size) 1083e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 1084e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int ret; 1085e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1086e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ret = mite_buf_change(devpriv->di_mite_ring, s->async); 1087e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (ret < 0) 1088e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return ret; 1089e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1090e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz); 1091e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1092e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 0; 1093e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 1094e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 10950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index, 10962d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi u8 *data, int data_len) 1097e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 1098e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef static const int timeout = 1000; 1099e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int i, j; 1100e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writew(0x80 | fpga_index, 11010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + Firmware_Control_Register); 1102e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writew(0xc0 | fpga_index, 11030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + Firmware_Control_Register); 1104e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef for (i = 0; 11050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (readw(devpriv->mite->daq_io_addr + 11060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Firmware_Status_Register) & 0x2) == 0 && i < timeout; ++i) { 1107e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef udelay(1); 1108e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1109e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (i == timeout) { 11102d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, " 11112d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi "waiting for status 0x2\n", fpga_index); 1112e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return -EIO; 1113e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1114e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writew(0x80 | fpga_index, 11150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + Firmware_Control_Register); 1116e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef for (i = 0; 11170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral readw(devpriv->mite->daq_io_addr + Firmware_Status_Register) != 11180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral 0x3 && i < timeout; ++i) { 1119e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef udelay(1); 1120e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1121e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (i == timeout) { 11222d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, " 11232d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi "waiting for status 0x3\n", fpga_index); 1124e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return -EIO; 1125e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1126e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef for (j = 0; j + 1 < data_len;) { 1127e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef unsigned int value = data[j++]; 1128e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef value |= data[j++] << 8; 1129e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writew(value, 11300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + Firmware_Data_Register); 1131e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef for (i = 0; 11320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (readw(devpriv->mite->daq_io_addr + 11330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Firmware_Status_Register) & 0x2) == 0 11340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral && i < timeout; ++i) { 1135e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef udelay(1); 1136e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1137e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (i == timeout) { 1138e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef printk("ni_pcidio: failed to load word into fpga %i\n", 11390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral fpga_index); 1140e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return -EIO; 1141e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1142e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (need_resched()) 1143e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef schedule(); 1144e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1145e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register); 1146e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 0; 1147e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 1148e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 11490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci_6534_reset_fpga(struct comedi_device *dev, int fpga_index) 1150e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 1151e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return pci_6534_load_fpga(dev, fpga_index, NULL, 0); 1152e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 1153e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 11540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci_6534_reset_fpgas(struct comedi_device *dev) 1155e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 1156e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int ret; 1157e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int i; 1158e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register); 1159e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef for (i = 0; i < 3; ++i) { 1160e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ret = pci_6534_reset_fpga(dev, i); 1161e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (ret < 0) 1162e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef break; 1163e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1164e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writew(0x0, devpriv->mite->daq_io_addr + Firmware_Mask_Register); 1165e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return ret; 1166e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 1167e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 11680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void pci_6534_init_main_fpga(struct comedi_device *dev) 1169e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 1170e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register); 1171e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register); 1172e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register); 1173e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(0, devpriv->mite->daq_io_addr + FPGA_SCAMS_Counter_Register); 1174e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(0, devpriv->mite->daq_io_addr + FPGA_SCBLS_Counter_Register); 1175e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register); 1176e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 1177e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 11780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci_6534_upload_firmware(struct comedi_device *dev, int options[]) 1179e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 1180e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int ret; 1181e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef void *main_fpga_data, *scarab_a_data, *scarab_b_data; 1182e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int main_fpga_data_len, scarab_a_data_len, scarab_b_data_len; 1183e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1184e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (options[COMEDI_DEVCONF_AUX_DATA_LENGTH] == 0) 1185e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 0; 1186e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ret = pci_6534_reset_fpgas(dev); 1187e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (ret < 0) 1188e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return ret; 1189e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef main_fpga_data = comedi_aux_data(options, 0); 1190e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef main_fpga_data_len = options[COMEDI_DEVCONF_AUX_DATA0_LENGTH]; 1191e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ret = pci_6534_load_fpga(dev, 2, main_fpga_data, main_fpga_data_len); 1192e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (ret < 0) 1193e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return ret; 1194e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef pci_6534_init_main_fpga(dev); 1195e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef scarab_a_data = comedi_aux_data(options, 1); 1196e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef scarab_a_data_len = options[COMEDI_DEVCONF_AUX_DATA1_LENGTH]; 1197e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ret = pci_6534_load_fpga(dev, 0, scarab_a_data, scarab_a_data_len); 1198e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (ret < 0) 1199e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return ret; 1200e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef scarab_b_data = comedi_aux_data(options, 2); 1201e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef scarab_b_data_len = options[COMEDI_DEVCONF_AUX_DATA2_LENGTH]; 1202e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ret = pci_6534_load_fpga(dev, 1, scarab_b_data, scarab_b_data_len); 1203e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (ret < 0) 1204e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return ret; 1205e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 0; 1206e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 1207e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 12080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) 1209e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 121034c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 1211e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int i; 1212e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int ret; 1213e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int n_subdevices; 1214e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef unsigned int irq; 1215e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 12162d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi printk(KERN_INFO "comedi%d: nidio:", dev->minor); 1217e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 12182d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi ret = alloc_private(dev, sizeof(struct nidio96_private)); 12192d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi if (ret < 0) 1220e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return ret; 1221e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef spin_lock_init(&devpriv->mite_channel_lock); 1222e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1223e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ret = nidio_find_device(dev, it->options[0], it->options[1]); 1224e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (ret < 0) 1225e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return ret; 1226e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1227e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ret = mite_setup(devpriv->mite); 1228e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (ret < 0) { 12292d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi printk(KERN_WARNING "error setting up mite\n"); 1230e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return ret; 1231e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1232e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev); 1233e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite); 1234e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (devpriv->di_mite_ring == NULL) 1235e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return -ENOMEM; 1236e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1237e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef dev->board_name = this_board->name; 1238e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef irq = mite_irq(devpriv->mite); 12392d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi printk(KERN_INFO " %s", dev->board_name); 1240e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (this_board->uses_firmware) { 1241e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef ret = pci_6534_upload_firmware(dev, it->options); 1242e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (ret < 0) 1243e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return ret; 1244e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 12452d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi if (!this_board->is_diodaq) 1246e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef n_subdevices = this_board->n_8255; 12472d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi else 1248e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef n_subdevices = 1; 12492d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi 12502d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi ret = alloc_subdevices(dev, n_subdevices); 12512d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi if (ret < 0) 1252e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return ret; 1253e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1254e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (!this_board->is_diodaq) { 1255e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef for (i = 0; i < this_board->n_8255; i++) { 1256e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef subdev_8255_init(dev, dev->subdevices + i, 12570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral nidio96_8255_cb, 12580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (unsigned long)(devpriv->mite-> 12590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral daq_io_addr + 12600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral NIDIO_8255_BASE(i))); 1261e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1262e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } else { 1263e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 12642d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi printk(KERN_INFO " rev=%d", 12650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral readb(devpriv->mite->daq_io_addr + Chip_Version)); 1266e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1267e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s = dev->subdevices + 0; 1268e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1269e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef dev->read_subdev = s; 1270e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->type = COMEDI_SUBD_DIO; 1271e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->subdev_flags = 12720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED | 12730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral SDF_CMD_READ; 1274e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->n_chan = 32; 1275e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->range_table = &range_digital; 1276e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->maxdata = 1; 1277e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->insn_config = &ni_pcidio_insn_config; 1278e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->insn_bits = &ni_pcidio_insn_bits; 1279e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->do_cmd = &ni_pcidio_cmd; 1280e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->do_cmdtest = &ni_pcidio_cmdtest; 1281e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->cancel = &ni_pcidio_cancel; 1282e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->len_chanlist = 32; /* XXX */ 1283e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->buf_change = &ni_pcidio_change; 1284e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef s->async_dma_dir = DMA_BIDIRECTIONAL; 128502f69d67684b77f7f04e281a026a790f0e08b3a3Ian Abbott s->poll = &ni_pcidio_poll; 1286e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1287e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(0, devpriv->mite->daq_io_addr + Port_IO(0)); 1288e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0)); 1289e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0)); 1290e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1291e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef /* disable interrupts on board */ 1292e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef writeb(0x00, 12930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->mite->daq_io_addr + 12940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral Master_DMA_And_Interrupt_Control); 1295e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 12965f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman ret = request_irq(irq, nidio_interrupt, IRQF_SHARED, 12975f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman "ni_pcidio", dev); 12982d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi if (ret < 0) 12992d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi printk(KERN_WARNING " irq not available"); 13002d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi 1301e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef dev->irq = irq; 1302e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1303e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1304e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef printk("\n"); 1305e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1306e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 0; 1307e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 1308e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 13090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int nidio_detach(struct comedi_device *dev) 1310e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 1311e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int i; 1312e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1313e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (this_board && !this_board->is_diodaq) { 13142d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi for (i = 0; i < this_board->n_8255; i++) 1315e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef subdev_8255_cleanup(dev, dev->subdevices + i); 1316e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1317e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1318e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (dev->irq) 13195f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 1320e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1321e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (devpriv) { 1322e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (devpriv->di_mite_ring) { 1323e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef mite_free_ring(devpriv->di_mite_ring); 1324e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef devpriv->di_mite_ring = NULL; 1325e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1326e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (devpriv->mite) 1327e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef mite_unsetup(devpriv->mite); 1328e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1329e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 0; 1330e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 1331e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 13320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int nidio_find_device(struct comedi_device *dev, int bus, int slot) 1333e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{ 1334e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef struct mite_struct *mite; 1335e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef int i; 1336e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1337e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef for (mite = mite_devices; mite; mite = mite->next) { 1338e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (mite->used) 1339e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef continue; 1340e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (bus || slot) { 1341e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (bus != mite->pcidev->bus->number || 13420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral slot != PCI_SLOT(mite->pcidev->devfn)) 1343e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef continue; 1344e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1345e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef for (i = 0; i < n_nidio_boards; i++) { 1346e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef if (mite_device_id(mite) == nidio_boards[i].dev_id) { 1347e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef dev->board_ptr = nidio_boards + i; 1348e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef devpriv->mite = mite; 1349e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1350e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return 0; 1351e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1352e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 1353e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef } 13542d2facda0b71609be294aa1fd5f56d2cdbcbb794Benjamin Adolphi printk(KERN_WARNING "no device found\n"); 1355e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef mite_list_devices(); 1356e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef return -EIO; 1357e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef} 1358e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef 1359727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __devinit driver_pcidio_pci_probe(struct pci_dev *dev, 1360727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas const struct pci_device_id *ent) 1361727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 1362727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return comedi_pci_auto_config(dev, driver_pcidio.driver_name); 1363727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 1364727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1365727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __devexit driver_pcidio_pci_remove(struct pci_dev *dev) 1366727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 1367727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_pci_auto_unconfig(dev); 1368727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 1369727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1370727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic struct pci_driver driver_pcidio_pci_driver = { 1371727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .id_table = ni_pcidio_pci_table, 1372727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .probe = &driver_pcidio_pci_probe, 1373727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .remove = __devexit_p(&driver_pcidio_pci_remove) 1374727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}; 1375727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1376727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __init driver_pcidio_init_module(void) 1377727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 1378727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas int retval; 1379727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1380727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas retval = comedi_driver_register(&driver_pcidio); 1381727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas if (retval < 0) 1382727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return retval; 1383727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1384727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas driver_pcidio_pci_driver.name = (char *)driver_pcidio.driver_name; 1385727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return pci_register_driver(&driver_pcidio_pci_driver); 1386727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 1387727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1388727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __exit driver_pcidio_cleanup_module(void) 1389727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 1390727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas pci_unregister_driver(&driver_pcidio_pci_driver); 1391727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_driver_unregister(&driver_pcidio); 1392727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 1393727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1394727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_init(driver_pcidio_init_module); 1395727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_exit(driver_pcidio_cleanup_module); 13963c323c01b6bd5fd01be21a8f0cdc11e55997aa06Ian Abbott 13973c323c01b6bd5fd01be21a8f0cdc11e55997aa06Ian AbbottMODULE_AUTHOR("Comedi http://www.comedi.org"); 13983c323c01b6bd5fd01be21a8f0cdc11e55997aa06Ian AbbottMODULE_DESCRIPTION("Comedi low-level driver"); 13993c323c01b6bd5fd01be21a8f0cdc11e55997aa06Ian AbbottMODULE_LICENSE("GPL"); 1400