159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi/drivers/cb_pcidas.c 359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez Developed by Ivan Martinez and Frank Mori Hess, with valuable help from 559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez David Schleef and the rest of the Comedi developers comunity. 659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk> 859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net> 959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez COMEDI - Linux Control and Measurement Device Interface 1159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> 1259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez This program is free software; you can redistribute it and/or modify 1459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez it under the terms of the GNU General Public License as published by 1559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez the Free Software Foundation; either version 2 of the License, or 1659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez (at your option) any later version. 1759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez This program is distributed in the hope that it will be useful, 1959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez but WITHOUT ANY WARRANTY; without even the implied warranty of 2059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez GNU General Public License for more details. 2259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 2359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez You should have received a copy of the GNU General Public License 2459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez along with this program; if not, write to the Free Software 2559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 2659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 2759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez************************************************************************ 2859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez*/ 2959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 3059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezDriver: cb_pcidas 3159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezDescription: MeasurementComputing PCI-DAS series with the AMCC S5933 PCI controller 3259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezAuthor: Ivan Martinez <imr@oersted.dtu.dk>, 3359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez Frank Mori Hess <fmhess@users.sourceforge.net> 3459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezUpdated: 2003-3-11 3559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezDevices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas), 3659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr, 3759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez PCI-DAS1000, PCI-DAS1001, PCI_DAS1002 3859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 3959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezStatus: 4059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez There are many reports of the driver being used with most of the 4159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez supported cards. Despite no detailed log is maintained, it can 4259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez be said that the driver is quite tested and stable. 4359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 4459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez The boards may be autocalibrated using the comedi_calibrate 4559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez utility. 4659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 4759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezConfiguration options: 4859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez [0] - PCI bus of device (optional) 4959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez [1] - PCI slot of device (optional) 5059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez If bus/slot is not specified, the first supported 5159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez PCI device found will be used. 5259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 5359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezFor commands, the scanned channels must be consecutive 5459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez(i.e. 4-5-6-7, 2-3-4,...), and must all have the same 5559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezrange and aref. 56f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost 57f1bc434398e8cf400374911357e89a13de366ce7Brice DubostAI Triggering: 58f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used. 59f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost For 1602 series, the start_arg is interpreted as follows: 60f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost start_arg == 0 => gated triger (level high) 61f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost start_arg == CR_INVERT => gated triger (level low) 62f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost start_arg == CR_EDGE => Rising edge 63f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost start_arg == CR_EDGE | CR_INVERT => Falling edge 64f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost For the other boards the trigger will be done on rising edge 6559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez*/ 6659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 6759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 6859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezTODO: 6959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 7059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezanalog triggering on 1602 series 7159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez*/ 7259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 7359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include "../comedidev.h" 7459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include <linux/delay.h> 7570265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slaby#include <linux/interrupt.h> 7659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 7759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include "8253.h" 7859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include "8255.h" 7959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include "amcc_s5933.h" 8059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include "comedi_pci.h" 8159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include "comedi_fc.h" 8259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 83cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#undef CB_PCIDAS_DEBUG /* disable debugging code */ 84cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* #define CB_PCIDAS_DEBUG enable debugging code */ 8559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 86cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* PCI vendor number of ComputerBoards/MeasurementComputing */ 8759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define PCI_VENDOR_ID_CB 0x1307 88cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define TIMER_BASE 100 /* 10MHz master clock */ 89cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define AI_BUFFER_SIZE 1024 /* maximum fifo size of any supported board */ 90cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define AO_BUFFER_SIZE 1024 /* maximum fifo size of any supported board */ 9159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define NUM_CHANNELS_8800 8 9259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define NUM_CHANNELS_7376 1 9359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define NUM_CHANNELS_8402 2 9459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define NUM_CHANNELS_DAC08 1 9559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 9659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* PCI-DAS base addresses */ 9759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 98cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* indices of base address regions */ 9959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define S5933_BADRINDEX 0 10059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define CONT_STAT_BADRINDEX 1 10159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define ADC_FIFO_BADRINDEX 2 10259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define PACER_BADRINDEX 3 10359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define AO_BADRINDEX 4 104cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* sizes of io regions */ 10559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define CONT_STAT_SIZE 10 10659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define ADC_FIFO_SIZE 4 10759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define PACER_SIZE 12 10859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define AO_SIZE 4 10959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 11059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* Control/Status registers */ 111cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INT_ADCFIFO 0 /* INTERRUPT / ADC FIFO register */ 112cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INT_EOS 0x1 /* interrupt end of scan */ 113cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INT_FHF 0x2 /* interrupt fifo half full */ 114cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INT_FNE 0x3 /* interrupt fifo not empty */ 115cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INT_MASK 0x3 /* mask of interrupt select bits */ 116cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INTE 0x4 /* interrupt enable */ 117cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DAHFIE 0x8 /* dac half full interrupt enable */ 11825985edcedea6396277003854657b5f3cb31a628Lucas De Marchi#define EOAIE 0x10 /* end of acquisition interrupt enable */ 119cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DAHFI 0x20 /* dac half full read status / write interrupt clear */ 120cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define EOAI 0x40 /* read end of acq. interrupt status / write clear */ 121cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INT 0x80 /* read interrupt status / write clear */ 122cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define EOBI 0x200 /* read end of burst interrupt status */ 123cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADHFI 0x400 /* read half-full interrupt status */ 124cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADNEI 0x800 /* read fifo not empty interrupt latch status */ 125cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADNE 0x1000 /* read, fifo not empty (realtime, not latched) status */ 126cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DAEMIE 0x1000 /* write, dac empty interrupt enable */ 127cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define LADFUL 0x2000 /* read fifo overflow / write clear */ 128cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DAEMI 0x4000 /* dac fifo empty interrupt status / write clear */ 129cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton 130cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADCMUX_CONT 2 /* ADC CHANNEL MUX AND CONTROL register */ 13159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define BEGIN_SCAN(x) ((x) & 0xf) 13259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define END_SCAN(x) (((x) & 0xf) << 4) 13359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define GAIN_BITS(x) (((x) & 0x3) << 8) 134cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define UNIP 0x800 /* Analog front-end unipolar for range */ 135cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define SE 0x400 /* Inputs in single-ended mode */ 136cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define PACER_MASK 0x3000 /* pacer source bits */ 137cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define PACER_INT 0x1000 /* internal pacer */ 138cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define PACER_EXT_FALL 0x2000 /* external falling edge */ 139cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define PACER_EXT_RISE 0x3000 /* external rising edge */ 140cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define EOC 0x4000 /* adc not busy */ 141cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton 142cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define TRIG_CONTSTAT 4 /* TRIGGER CONTROL/STATUS register */ 143cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define SW_TRIGGER 0x1 /* software start trigger */ 144cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define EXT_TRIGGER 0x2 /* external start trigger */ 145cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ANALOG_TRIGGER 0x3 /* external analog trigger */ 146cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define TRIGGER_MASK 0x3 /* mask of bits that determine start trigger */ 147f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost#define TGPOL 0x04 /* invert the edge/level of the external trigger (1602 only) */ 148f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost#define TGSEL 0x08 /* if set edge triggered, otherwise level trigerred (1602 only) */ 149cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define TGEN 0x10 /* enable external start trigger */ 150cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define BURSTE 0x20 /* burst mode enable */ 151cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define XTRCL 0x80 /* clear external trigger */ 152cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton 153cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define CALIBRATION_REG 6 /* CALIBRATION register */ 154cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define SELECT_8800_BIT 0x100 /* select 8800 caldac */ 155cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define SELECT_TRIMPOT_BIT 0x200 /* select ad7376 trim pot */ 156cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define SELECT_DAC08_BIT 0x400 /* select dac08 caldac */ 15759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define CAL_SRC_BITS(x) (((x) & 0x7) << 11) 158cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define CAL_EN_BIT 0x4000 /* read calibration source instead of analog input channel 0 */ 159cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define SERIAL_DATA_IN_BIT 0x8000 /* serial data stream going to 8800 and 7376 */ 16059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 161cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DAC_CSR 0x8 /* dac control and status register */ 16259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezenum dac_csr_bits { 163cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DACEN = 0x2, /* dac enable */ 164cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_MODE_UPDATE_BOTH = 0x80, /* update both dacs when dac0 is written */ 16559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 16659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range) 16759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 16859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return (range & 0x3) << (8 + 2 * (channel & 0x1)); 16959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 1700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral 17159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic inline unsigned int DAC_RANGE_MASK(unsigned int channel) 17259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 17359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0x3 << (8 + 2 * (channel & 0x1)); 17459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 17559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 176cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* bits for 1602 series only */ 17759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezenum dac_csr_bits_1602 { 178cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_EMPTY = 0x1, /* dac fifo empty, read, write clear */ 179cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_START = 0x4, /* start/arm dac fifo operations */ 180cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_PACER_MASK = 0x18, /* bits that set dac pacer source */ 181cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_PACER_INT = 0x8, /* dac internal pacing */ 182cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_PACER_EXT_FALL = 0x10, /* dac external pacing, falling edge */ 183cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_PACER_EXT_RISE = 0x18, /* dac external pacing, rising edge */ 18459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 18559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic inline unsigned int DAC_CHAN_EN(unsigned int channel) 18659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 187cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton return 1 << (5 + (channel & 0x1)); /* enable channel 0 or 1 */ 18859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 18959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 19059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* analog input fifo */ 191cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADCDATA 0 /* ADC DATA register */ 192cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADCFIFOCLR 2 /* ADC FIFO CLEAR */ 19359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 194cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* pacer, counter, dio registers */ 19559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define ADC8254 0 19659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define DIO_8255 4 19759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define DAC8254 8 19859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 199cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output registers for 100x, 1200 series */ 20059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic inline unsigned int DAC_DATA_REG(unsigned int channel) 20159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 20259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 2 * (channel & 0x1); 20359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 20459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 20559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* analog output registers for 1602 series*/ 206cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DACDATA 0 /* DAC DATA register */ 207cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DACFIFOCLR 2 /* DAC FIFO CLEAR */ 20859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 209cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* bit in hexadecimal representation of range index that indicates unipolar input range */ 21059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define IS_UNIPOLAR 0x4 211cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog input ranges for most boards */ 2129ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange cb_pcidas_ranges = { 21359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 8, 21459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 2150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(10), 2160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(5), 2170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(2.5), 2180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(1.25), 2190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(10), 2200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(5), 2210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(2.5), 2220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(1.25) 2230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 22459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 22559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 226cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* pci-das1001 input ranges */ 2279ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange cb_pcidas_alt_ranges = { 22859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 8, 22959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 2300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(10), 2310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(1), 2320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(0.1), 2330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(0.01), 2340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(10), 2350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(1), 2360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(0.1), 2370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(0.01) 2380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 23959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 24059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 241cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output ranges */ 2429ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange cb_pcidas_ao_ranges = { 24359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 4, 24459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 2450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(5), 2460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(10), 2470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(5), 2480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(10), 2490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 25059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 25159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 25259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezenum trimpot_model { 25359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez AD7376, 25459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez AD8402, 25559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 25659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 2575c2670cba2a5fd1a27f938ae11b3a24518d999dbBill Pembertonstruct cb_pcidas_board { 25859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez const char *name; 25959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned short device_id; 260cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ai_se_chans; /* Inputs in single-ended mode */ 261cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ai_diff_chans; /* Inputs in differential mode */ 262cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ai_bits; /* analog input resolution */ 263cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ai_speed; /* fastest conversion period in ns */ 264cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ao_nchan; /* number of analog out channels */ 265cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int has_ao_fifo; /* analog output has fifo */ 266cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ao_scan_speed; /* analog output speed for 1602 series (for a scan, not conversion) */ 267cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int fifo_size; /* number of samples fifo can hold */ 2689ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pemberton const struct comedi_lrange *ranges; 26959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez enum trimpot_model trimpot; 27059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned has_dac08:1; 271f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost unsigned has_ai_trig_gated:1; /* Tells if the AI trigger can be gated */ 272f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost unsigned has_ai_trig_invert:1; /* Tells if the AI trigger can be inverted */ 2735c2670cba2a5fd1a27f938ae11b3a24518d999dbBill Pemberton}; 27459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 2755c2670cba2a5fd1a27f938ae11b3a24518d999dbBill Pembertonstatic const struct cb_pcidas_board cb_pcidas_boards[] = { 27659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 2770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1602/16", 2780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x1, 2790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 2800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 2810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 16, 2820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 5000, 2830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 2, 2840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 1, 2850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_scan_speed = 10000, 2860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 512, 2870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 2880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD8402, 2890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 1, 290f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_gated = 1, 291f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_invert = 1, 2920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 29359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 2940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1200", 2950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0xF, 2960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 2970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 2980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 12, 2990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3200, 3000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 2, 3010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 0, 3020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 1024, 3030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 3040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD7376, 3050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 0, 306f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_gated = 0, 307f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_invert = 0, 3080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 30959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 3100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1602/12", 3110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x10, 3120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 3130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 3140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 12, 3150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3200, 3160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 2, 3170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 1, 3180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_scan_speed = 4000, 3190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 1024, 3200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 3210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD7376, 3220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 0, 323f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_gated = 1, 324f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_invert = 1, 3250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 32659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 3270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1200/jr", 3280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x19, 3290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 3300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 3310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 12, 3320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3200, 3330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 0, 3340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 0, 3350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 1024, 3360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 3370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD7376, 3380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 0, 339f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_gated = 0, 340f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_invert = 0, 3410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 34259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 3430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1602/16/jr", 3440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x1C, 3450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 3460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 3470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 16, 3480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 5000, 3490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 0, 3500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 0, 3510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 512, 3520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 3530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD8402, 3540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 1, 355f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_gated = 1, 356f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_invert = 1, 3570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 35859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 3590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1000", 3600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x4C, 3610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 3620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 3630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 12, 3640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 4000, 3650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 0, 3660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 0, 3670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 1024, 3680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 3690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD7376, 3700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 0, 371f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_gated = 0, 372f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_invert = 0, 3730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 37459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 3750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1001", 3760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x1a, 3770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 3780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 3790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 12, 3800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 6800, 3810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 2, 3820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 0, 3830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 1024, 3840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_alt_ranges, 3850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD7376, 3860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 0, 387f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_gated = 0, 388f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_invert = 0, 3890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 39059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 3910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1002", 3920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x1b, 3930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 3940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 3950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 12, 3960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 6800, 3970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 2, 3980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 0, 3990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 1024, 4000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 4010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD7376, 4020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 0, 403f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_gated = 0, 404f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost .has_ai_trig_invert = 0, 4050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 40659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 40759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 40859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = { 40916f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) }, 41016f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) }, 41116f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) }, 41216f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) }, 41316f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) }, 41416f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) }, 41516f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) }, 41616f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) }, 41716f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { 0 } 41859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 41959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 42059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezMODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table); 42159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 42259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 42359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Useful for shorthand access to the particular board structure 42459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 4255c2670cba2a5fd1a27f938ae11b3a24518d999dbBill Pemberton#define thisboard ((const struct cb_pcidas_board *)dev->board_ptr) 42659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 42759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* this structure is for data unique to this hardware driver. If 42859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez several hardware drivers keep similar information in this structure, 42971b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton feel free to suggest moving the variable to the struct comedi_device struct. */ 430c77e25898523395b56e1d120195e1ad2e3efa14dBill Pembertonstruct cb_pcidas_private { 43159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* would be useful for a PCI device */ 43259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez struct pci_dev *pci_dev; 433cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* base addresses */ 43459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long s5933_config; 43559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long control_status; 43659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long adc_fifo; 43759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long pacer_counter_dio; 43859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long ao_registers; 439cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* divisors of master clock for analog input pacing */ 44059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int divisor1; 44159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int divisor2; 442cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int count; /* number of analog input samples remaining */ 44325985edcedea6396277003854657b5f3cb31a628Lucas De Marchi volatile unsigned int adc_fifo_bits; /* bits to write to interrupt/adcfifo register */ 444cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int s5933_intcsr_bits; /* bits to write to amcc s5933 interrupt control/status register */ 445cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int ao_control_bits; /* bits to write to ao control and status register */ 446790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short ai_buffer[AI_BUFFER_SIZE]; 447790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short ao_buffer[AO_BUFFER_SIZE]; 448cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* divisors of master clock for analog output pacing */ 44959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int ao_divisor1; 45059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int ao_divisor2; 451cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int ao_count; /* number of analog output samples remaining */ 452cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ao_value[2]; /* remember what the analog outputs are set to, to allow readback */ 453cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton unsigned int caldac_value[NUM_CHANNELS_8800]; /* for readback of caldac */ 454cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton unsigned int trimpot_value[NUM_CHANNELS_8402]; /* for readback of trimpot */ 45559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int dac08_value; 45659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int calibration_source; 457c77e25898523395b56e1d120195e1ad2e3efa14dBill Pemberton}; 45859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 45959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 46059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * most drivers define the following macro to make it easy to 46159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * access the private structure. 46259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 463c77e25898523395b56e1d120195e1ad2e3efa14dBill Pemberton#define devpriv ((struct cb_pcidas_private *)dev->private) 46459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 46559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 466139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pemberton * The struct comedi_driver structure tells the Comedi core module 46759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * which functions to call to configure/deconfigure (attach/detach) 46859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * the board, and also about the kernel module that contains 46959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * the device code. 47059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 4710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_attach(struct comedi_device *dev, 4720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 473da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_detach(struct comedi_device *dev); 474139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_cb_pcidas = { 47568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "cb_pcidas", 47668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 47768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = cb_pcidas_attach, 47868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = cb_pcidas_detach, 47959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 48059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 4810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ai_rinsn(struct comedi_device *dev, 4820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 484814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, 4850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 4860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev, 4870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 4890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 4900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev, 4910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 4930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 4940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_readback_insn(struct comedi_device *dev, 4950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 4970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 4980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ai_cmd(struct comedi_device *dev, 4990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 5000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ai_cmdtest(struct comedi_device *dev, 5010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd); 5030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_cmd(struct comedi_device *dev, 5040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 505d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pembertonstatic int cb_pcidas_ao_inttrig(struct comedi_device *dev, 506d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_subdevice *subdev, 507d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton unsigned int trig_num); 5080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_cmdtest(struct comedi_device *dev, 5090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd); 51170265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t cb_pcidas_interrupt(int irq, void *d); 512814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void handle_ao_interrupt(struct comedi_device *dev, unsigned int status); 5130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_cancel(struct comedi_device *dev, 5140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 5150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_cancel(struct comedi_device *dev, 5160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 517814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns, 5180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral int round_flags); 5190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int eeprom_read_insn(struct comedi_device *dev, 5200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 5220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int caldac_read_insn(struct comedi_device *dev, 5230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 5250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int caldac_write_insn(struct comedi_device *dev, 5260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 5280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int trimpot_read_insn(struct comedi_device *dev, 5290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 5310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_trimpot_write(struct comedi_device *dev, 5320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int channel, unsigned int value); 5330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int trimpot_write_insn(struct comedi_device *dev, 5340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 5360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dac08_read_insn(struct comedi_device *dev, 5370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_insn *insn, 5380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 539814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int dac08_write(struct comedi_device *dev, unsigned int value); 5400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dac08_write_insn(struct comedi_device *dev, 5410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 543814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int caldac_8800_write(struct comedi_device *dev, unsigned int address, 5440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral uint8_t value); 545814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int trimpot_7376_write(struct comedi_device *dev, uint8_t value); 546814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int trimpot_8402_write(struct comedi_device *dev, unsigned int channel, 5470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral uint8_t value); 548814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int nvram_read(struct comedi_device *dev, unsigned int address, 5492d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini uint8_t *data); 55059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 551814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic inline unsigned int cal_enable_bits(struct comedi_device *dev) 55259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 55359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source); 55459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 55559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 55659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 55759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Attach is called by the Comedi core to configure the driver 55859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * for a particular board. 55959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 5600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_attach(struct comedi_device *dev, 5610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it) 56259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 56334c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 56420fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy struct pci_dev *pcidev = NULL; 56559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int index; 56659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int i; 56759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 56859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 56959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Allocate the private structure area. 57059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 571c77e25898523395b56e1d120195e1ad2e3efa14dBill Pemberton if (alloc_private(dev, sizeof(struct cb_pcidas_private)) < 0) 57259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ENOMEM; 57359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 57459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 57559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Probe the device to determine what device in the series it is. 57659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 57759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 57820fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy for_each_pci_dev(pcidev) { 579cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* is it not a computer boards card? */ 58059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (pcidev->vendor != PCI_VENDOR_ID_CB) 58159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez continue; 582cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* loop through cards supported by this driver */ 5838629efa4cbf6f89a54a85af4b8bc31762af01800Bill Pemberton for (index = 0; index < ARRAY_SIZE(cb_pcidas_boards); index++) { 58459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cb_pcidas_boards[index].device_id != pcidev->device) 58559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez continue; 586cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* was a particular bus/slot requested? */ 58759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (it->options[0] || it->options[1]) { 588cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* are we on the wrong bus/slot? */ 58959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (pcidev->bus->number != it->options[0] || 5900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pcidev->devfn) != it->options[1]) { 59159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez continue; 59259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 59359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 59459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->pci_dev = pcidev; 59559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->board_ptr = cb_pcidas_boards + index; 59659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez goto found; 59759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 59859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 59959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 6008bde85db943971ea57780823e25778068d77eeadRavishankar karkala Mallikarjunayya dev_err(dev->hw_dev, "No supported ComputerBoards/MeasurementComputing card found on requested position\n"); 60159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EIO; 60259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 6030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralfound: 60459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 6058bde85db943971ea57780823e25778068d77eeadRavishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "Found %s on bus %i, slot %i\n", 6068bde85db943971ea57780823e25778068d77eeadRavishankar karkala Mallikarjunayya cb_pcidas_boards[index].name, pcidev->bus->number, 6078bde85db943971ea57780823e25778068d77eeadRavishankar karkala Mallikarjunayya PCI_SLOT(pcidev->devfn)); 60859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 60959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* 61059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Enable PCI device and reserve I/O ports. 61159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 61259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (comedi_pci_enable(pcidev, "cb_pcidas")) { 6138bde85db943971ea57780823e25778068d77eeadRavishankar karkala Mallikarjunayya dev_err(dev->hw_dev, "Failed to enable PCI device and request regions\n"); 61459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EIO; 61559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 61659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* 61759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Initialize devpriv->control_status and devpriv->adc_fifo to point to 61859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * their base address. 61959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 62059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->s5933_config = 6210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX); 62259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status = 6230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX); 62459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo = 6250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX); 62659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->pacer_counter_dio = 6270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX); 62859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->ao_nchan) { 62959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_registers = 6300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_resource_start(devpriv->pci_dev, AO_BADRINDEX); 63159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 632cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable and clear interrupts on amcc s5933 */ 63359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outl(INTCSR_INBOX_INTR_STATUS, 6340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->s5933_config + AMCC_OP_REG_INTCSR); 63559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 636cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* get irq */ 6375f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman if (request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt, 63859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez IRQF_SHARED, "cb_pcidas", dev)) { 6398bde85db943971ea57780823e25778068d77eeadRavishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "unable to allocate irq %d\n", 6408bde85db943971ea57780823e25778068d77eeadRavishankar karkala Mallikarjunayya devpriv->pci_dev->irq); 64159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 64259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 64359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->irq = devpriv->pci_dev->irq; 64459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 645cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* Initialize dev->board_name */ 64659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->board_name = thisboard->name; 64759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 64859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 64959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Allocate the subdevice structures. 65059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 65159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (alloc_subdevices(dev, 7) < 0) 65259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ENOMEM; 65359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 65459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 0; 65559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* analog input subdevice */ 65659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->read_subdev = s; 65759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_AI; 65859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; 65959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* WARNING: Number of inputs in differential mode is ignored */ 66059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = thisboard->ai_se_chans; 66159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->len_chanlist = thisboard->ai_se_chans; 66259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = (1 << thisboard->ai_bits) - 1; 66359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->range_table = thisboard->ranges; 66459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = cb_pcidas_ai_rinsn; 66559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_config = ai_config_insn; 66659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->do_cmd = cb_pcidas_ai_cmd; 66759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->do_cmdtest = cb_pcidas_ai_cmdtest; 66859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->cancel = cb_pcidas_cancel; 66959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 67059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* analog output subdevice */ 67159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 1; 67259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->ao_nchan) { 67359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_AO; 67459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; 67559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = thisboard->ao_nchan; 676cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* analog out resolution is the same as analog input resolution, so use ai_bits */ 67759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = (1 << thisboard->ai_bits) - 1; 67859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->range_table = &cb_pcidas_ao_ranges; 67959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = cb_pcidas_ao_readback_insn; 68059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->has_ao_fifo) { 68159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->write_subdev = s; 68259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags |= SDF_CMD_WRITE; 68359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = cb_pcidas_ao_fifo_winsn; 68459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->do_cmdtest = cb_pcidas_ao_cmdtest; 68559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->do_cmd = cb_pcidas_ao_cmd; 68659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->cancel = cb_pcidas_ao_cancel; 68759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 68859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = cb_pcidas_ao_nofifo_winsn; 68959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 69059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 69159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_UNUSED; 69259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 69359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 69459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* 8255 */ 69559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 2; 69659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez subdev_8255_init(dev, s, NULL, devpriv->pacer_counter_dio + DIO_8255); 69759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 698cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* serial EEPROM, */ 69959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 3; 70059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_MEMORY; 70159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_INTERNAL; 70259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = 256; 70359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0xff; 70459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = eeprom_read_insn; 70559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 706cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* 8800 caldac */ 70759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 4; 70859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_CALIB; 70959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 71059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = NUM_CHANNELS_8800; 71159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0xff; 71259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = caldac_read_insn; 71359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = caldac_write_insn; 71459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < s->n_chan; i++) 71559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez caldac_8800_write(dev, i, s->maxdata / 2); 71659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 717cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* trim potentiometer */ 71859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 5; 71959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_CALIB; 72059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 72159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->trimpot == AD7376) { 72259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = NUM_CHANNELS_7376; 72359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0x7f; 72459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 72559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = NUM_CHANNELS_8402; 72659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0xff; 72759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 72859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = trimpot_read_insn; 72959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = trimpot_write_insn; 73059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < s->n_chan; i++) 73159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_trimpot_write(dev, i, s->maxdata / 2); 73259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 733cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* dac08 caldac */ 73459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 6; 73559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->has_dac08) { 73659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_CALIB; 73759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 73859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = NUM_CHANNELS_DAC08; 73959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = dac08_read_insn; 74059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = dac08_write_insn; 74159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0xff; 74259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dac08_write(dev, s->maxdata / 2); 74359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else 74459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_UNUSED; 74559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 746cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* make sure mailbox 4 is empty */ 74759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez inl(devpriv->s5933_config + AMCC_OP_REG_IMB4); 74859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* Set bits to enable incoming mailbox interrupts on amcc s5933. */ 74959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->s5933_intcsr_bits = 7500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) | 7510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral INTCSR_INBOX_FULL_INT; 752cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear and enable interrupt on amcc s5933 */ 75359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS, 7540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->s5933_config + AMCC_OP_REG_INTCSR); 75559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 75659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 75759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 75859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 75959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 76059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * cb_pcidas_detach is called to deconfigure a device. It should deallocate 76159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * resources. 76259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * This function is also called when _attach() fails, so it should be 76359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * careful not to release resources that were not necessarily 76459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * allocated by _attach(). dev->private and dev->subdevices are 76559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * deallocated automatically by the core. 76659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 767da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_detach(struct comedi_device *dev) 76859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 76959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 77059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv) { 77159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv->s5933_config) { 772cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable and clear interrupts on amcc s5933 */ 77359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outl(INTCSR_INBOX_INTR_STATUS, 7740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->s5933_config + AMCC_OP_REG_INTCSR); 77559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 776aa4b8c725884b15c1d1467d382162e151b13a612Ravishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "detaching, incsr is 0x%x\n", 777aa4b8c725884b15c1d1467d382162e151b13a612Ravishankar karkala Mallikarjunayya inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR)); 77859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 77959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 78059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 78159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (dev->irq) 7825f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 78359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (dev->subdevices) 78459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez subdev_8255_cleanup(dev, dev->subdevices + 2); 78559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv && devpriv->pci_dev) { 7862d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (devpriv->s5933_config) 78759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_pci_disable(devpriv->pci_dev); 78859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez pci_dev_put(devpriv->pci_dev); 78959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 79059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 79159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 79259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 79359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 79459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 79559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * "instructions" read/write data in "one-shot" or "software-triggered" 79659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * mode. 79759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 7980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ai_rinsn(struct comedi_device *dev, 7990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 8000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 80159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 80259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int n, i; 80359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bits; 80459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int timeout = 10000; 80559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int channel; 806cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable calibration input if appropriate */ 80759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (insn->chanspec & CR_ALT_SOURCE) { 80859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev), 8090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + CALIBRATION_REG); 81059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez channel = 0; 81159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 81259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + CALIBRATION_REG); 81359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez channel = CR_CHAN(insn->chanspec); 81459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 815cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set mux limits and gain */ 81659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits = BEGIN_SCAN(channel) | 8170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral END_SCAN(channel) | GAIN_BITS(CR_RANGE(insn->chanspec)); 818cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set unipolar/bipolar */ 81959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_RANGE(insn->chanspec) & IS_UNIPOLAR) 82059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= UNIP; 821cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set singleended/differential */ 82259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_AREF(insn->chanspec) != AREF_DIFF) 82359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= SE; 82459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(bits, devpriv->control_status + ADCMUX_CONT); 82559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 82659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* clear fifo */ 82759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->adc_fifo + ADCFIFOCLR); 82859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 82959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* convert n samples */ 83059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (n = 0; n < insn->n; n++) { 83159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* trigger conversion */ 83259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->adc_fifo + ADCDATA); 83359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 83459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* wait for conversion to end */ 83559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* return -ETIMEDOUT if there is a timeout */ 83659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < timeout; i++) { 83759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (inw(devpriv->control_status + ADCMUX_CONT) & EOC) 83859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 83959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 84059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (i == timeout) 84159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ETIMEDOUT; 84259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 84359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* read data */ 84459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[n] = inw(devpriv->adc_fifo + ADCDATA); 84559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 84659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 84759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* return the number of samples read/written */ 84859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return n; 84959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 85059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 8510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ai_config_calibration_source(struct comedi_device *dev, 8520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 85359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 85459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int num_calibration_sources = 8; 855790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int source = data[1]; 85659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 85759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (source >= num_calibration_sources) { 85894cc0b4a6ea924b69bb8e784eb977d6a61ae5aceRavishankar karkala Mallikarjunayya dev_err(dev->hw_dev, "invalid calibration source: %i\n", 85994cc0b4a6ea924b69bb8e784eb977d6a61ae5aceRavishankar karkala Mallikarjunayya source); 86059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 86159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 86259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 86359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->calibration_source = source; 86459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 86559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 2; 86659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 86759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 868da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, 8690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 87059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 87159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int id = data[0]; 87259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 87359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez switch (id) { 87459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case INSN_CONFIG_ALT_SOURCE: 87559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return ai_config_calibration_source(dev, data); 87659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 87759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez default: 87859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 87959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 88059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 88159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 88259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 88359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 884cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output insn for pcidas-1000 and 1200 series */ 8850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev, 8860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 8870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 8880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 88959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 89059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int channel; 89159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 89259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 893cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set channel and range */ 89459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez channel = CR_CHAN(insn->chanspec); 8955f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 89659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits &= 8970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel); 89859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= 8990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec)); 90059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 9015f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 90259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 903cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* remember value for readback */ 90459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_value[channel] = data[0]; 905cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* send data */ 90659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(data[0], devpriv->ao_registers + DAC_DATA_REG(channel)); 90759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 90859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 90959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 91059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 911cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output insn for pcidas-1602 series */ 9120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev, 9130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 9140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 91559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 91659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int channel; 91759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 91859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 919cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear dac fifo */ 92059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->ao_registers + DACFIFOCLR); 92159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 922cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set channel and range */ 92359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez channel = CR_CHAN(insn->chanspec); 9245f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 92559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits &= 9260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) & ~DAC_RANGE_MASK(channel) & 9270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ~DAC_PACER_MASK; 92859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= 9290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral DACEN | DAC_RANGE(channel, 9300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_RANGE(insn-> 9310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral chanspec)) | DAC_CHAN_EN(channel) | 9320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral DAC_START; 93359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 9345f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 93559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 936cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* remember value for readback */ 93759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_value[channel] = data[0]; 938cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* send data */ 93959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(data[0], devpriv->ao_registers + DACDATA); 94059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 94159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 94259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 94359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 944cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output readback insn */ 945cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* XXX loses track of analog output value back after an analog ouput command is executed */ 9460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_readback_insn(struct comedi_device *dev, 9470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 9480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 9490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 95059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 95159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)]; 95259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 95359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 95459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 95559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 9560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int eeprom_read_insn(struct comedi_device *dev, 9570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 9580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 95959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 96059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez uint8_t nvram_data; 96159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int retval; 96259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 96359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data); 96459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (retval < 0) 96559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return retval; 96659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 96759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = nvram_data; 96859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 96959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 97059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 97159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 9720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int caldac_write_insn(struct comedi_device *dev, 9730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 9740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 97559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 97659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez const unsigned int channel = CR_CHAN(insn->chanspec); 97759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 97859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return caldac_8800_write(dev, channel, data[0]); 97959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 98059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 9810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int caldac_read_insn(struct comedi_device *dev, 9820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 9830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 98459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 98559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)]; 98659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 98759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 98859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 98959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 99059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 1602/16 pregain offset */ 991da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dac08_write(struct comedi_device *dev, unsigned int value) 99259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 99359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv->dac08_value == value) 99459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 99559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 99659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->dac08_value = value; 99759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 99859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev) | (value & 0xff), 9990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + CALIBRATION_REG); 10005f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 100159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev) | SELECT_DAC08_BIT | (value & 0xff), 10020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + CALIBRATION_REG); 10035f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 100459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev) | (value & 0xff), 10050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + CALIBRATION_REG); 10065f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 100759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 100859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 100959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 101059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 10110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dac08_write_insn(struct comedi_device *dev, 10120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 10130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 101459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 101559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return dac08_write(dev, data[0]); 101659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 101759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 10180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dac08_read_insn(struct comedi_device *dev, 10190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_insn *insn, 10200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 102159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 102259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = devpriv->dac08_value; 102359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 102459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 102559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 102659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1027da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_trimpot_write(struct comedi_device *dev, 10280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int channel, unsigned int value) 102959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 103059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv->trimpot_value[channel] == value) 103159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 103259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 103359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->trimpot_value[channel] = value; 103459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez switch (thisboard->trimpot) { 103559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case AD7376: 103659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez trimpot_7376_write(dev, value); 103759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 103859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case AD8402: 103959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez trimpot_8402_write(dev, channel, value); 104059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 104159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez default: 104259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "driver bug?"); 104359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 104459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 104559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 104659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 104759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 104859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 104959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 10500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int trimpot_write_insn(struct comedi_device *dev, 10510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 10520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 105359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 105459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int channel = CR_CHAN(insn->chanspec); 105559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 105659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return cb_pcidas_trimpot_write(dev, channel, data[0]); 105759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 105859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 10590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int trimpot_read_insn(struct comedi_device *dev, 10600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 10610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 106259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 106359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int channel = CR_CHAN(insn->chanspec); 106459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 106559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = devpriv->trimpot_value[channel]; 106659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 106759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 106859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 106959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 10700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ai_cmdtest(struct comedi_device *dev, 10710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 10720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd) 107359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 107459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int err = 0; 107559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int tmp; 107659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int i, gain, start_chan; 107759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 107859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* cmdtest tests a particular command to see if it is valid. 107959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Using the cmdtest ioctl, a user can create a valid cmd 108059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * and then have it executes by the cmd ioctl. 108159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * 108259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * cmdtest returns 1,2,3,4 or 0, depending on which tests 108359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * the command passes. */ 108459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 108559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 1: make sure trigger sources are trivially valid */ 108659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 108759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->start_src; 108859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->start_src &= TRIG_NOW | TRIG_EXT; 108959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->start_src || tmp != cmd->start_src) 109059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 109159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 109259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_begin_src; 109359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; 109459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 109559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 109659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 109759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->convert_src; 109859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT; 109959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->convert_src || tmp != cmd->convert_src) 110059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 110159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 110259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_end_src; 110359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_end_src &= TRIG_COUNT; 110459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 110559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 110659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 110759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->stop_src; 110859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 110959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->stop_src || tmp != cmd->stop_src) 111059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 111159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 111259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 111359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 111459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 111559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 2: make sure trigger sources are unique and mutually compatible */ 111659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 111759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) 111859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 111959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src != TRIG_FOLLOW && 11200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_src != TRIG_TIMER && 11210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_src != TRIG_EXT) 112259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 112359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src != TRIG_TIMER && 11240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) 112559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 112659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 112759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 112859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1129cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* make sure trigger sources are compatible with each other */ 113059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW) 113159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 113259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW) 113359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 113459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_src == TRIG_EXT && 11350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)) 113659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 113759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 113859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 113959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 2; 114059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 114159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 3: make sure arguments are trivially compatible */ 114259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1143f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost switch (cmd->start_src) { 1144f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost case TRIG_EXT: 1145f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost /* External trigger, only CR_EDGE and CR_INVERT flags allowed */ 1146f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost if ((cmd->start_arg 1147f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) { 1148f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost cmd->start_arg &= 1149f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost ~(CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT)); 1150f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost err++; 1151f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost } 1152f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost if (!thisboard->has_ai_trig_invert && 1153f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost (cmd->start_arg & CR_INVERT)) { 1154f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT); 1155f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost err++; 1156f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost } 1157f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost break; 1158f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost default: 1159f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost if (cmd->start_arg != 0) { 1160f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost cmd->start_arg = 0; 1161f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost err++; 1162f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost } 1163f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost break; 116459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 116559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 116659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 116759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_arg < 11680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral thisboard->ai_speed * cmd->chanlist_len) { 116959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_arg = 11700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral thisboard->ai_speed * cmd->chanlist_len; 117159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 117259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 117359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 117459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_TIMER) { 117559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_arg < thisboard->ai_speed) { 117659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->convert_arg = thisboard->ai_speed; 117759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 117859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 117959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 118059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 118159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_end_arg != cmd->chanlist_len) { 118259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_end_arg = cmd->chanlist_len; 118359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 118459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 118559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_NONE) { 118659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* TRIG_NONE */ 118759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_arg != 0) { 118859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->stop_arg = 0; 118959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 119059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 119159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 119259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 119359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 119459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 3; 119559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 119659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 4: fix up any arguments */ 119759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 119859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 119959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_begin_arg; 120059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, 12010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor1), 12020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor2), 12030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd->scan_begin_arg), 12040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 120559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (tmp != cmd->scan_begin_arg) 120659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 120759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 120859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_TIMER) { 120959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->convert_arg; 121059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, 12110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor1), 12120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor2), 12130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd->convert_arg), 12140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 121559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (tmp != cmd->convert_arg) 121659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 121759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 121859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 121959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 122059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 4; 122159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1222cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check channel/gain list against card's limitations */ 122359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->chanlist) { 122459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez gain = CR_RANGE(cmd->chanlist[0]); 122559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez start_chan = CR_CHAN(cmd->chanlist[0]); 122659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 1; i < cmd->chanlist_len; i++) { 122759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_CHAN(cmd->chanlist[i]) != 12280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (start_chan + i) % s->n_chan) { 122959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, 12300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must be consecutive channels, counting upwards\n"); 123159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 123259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 123359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_RANGE(cmd->chanlist[i]) != gain) { 123459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, 12350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must all have the same gain\n"); 123659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 123759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 123859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 123959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 124059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 124159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 124259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 5; 124359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 124459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 124559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 124659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 12470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ai_cmd(struct comedi_device *dev, 12480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 124959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 1250d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1251ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &async->cmd; 125259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bits; 125359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 125459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1255cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* make sure CAL_EN_BIT is disabled */ 125659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + CALIBRATION_REG); 1257cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* initialize before settings pacer source and count values */ 125859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + TRIG_CONTSTAT); 1259cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear fifo */ 126059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->adc_fifo + ADCFIFOCLR); 126159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1262cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set mux limits, gain and pacer source */ 126359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) | 12640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) | 12650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral GAIN_BITS(CR_RANGE(cmd->chanlist[0])); 1266cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set unipolar/bipolar */ 126759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR) 126859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= UNIP; 1269cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set singleended/differential */ 127059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF) 127159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= SE; 1272cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set pacer source */ 127359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT) 127459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= PACER_EXT_RISE; 127559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else 127659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= PACER_INT; 127759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(bits, devpriv->control_status + ADCMUX_CONT); 127859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 127959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 1280aa4b8c725884b15c1d1467d382162e151b13a612Ravishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "comedi: sent 0x%x to adcmux control\n", bits); 128159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 128259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1283cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* load counters */ 128459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_TIMER) 128559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_load_counters(dev, &cmd->convert_arg, 12860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 128759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else if (cmd->scan_begin_src == TRIG_TIMER) 128859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_load_counters(dev, &cmd->scan_begin_arg, 12890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 129059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1291cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set number of conversions */ 12922d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (cmd->stop_src == TRIG_COUNT) 129359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->count = cmd->chanlist_len * cmd->stop_arg; 1294cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable interrupts */ 12955f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 129659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits |= INTE; 129759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits &= ~INT_MASK; 129859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->flags & TRIG_WAKE_EOS) { 129959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) 1300cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton devpriv->adc_fifo_bits |= INT_EOS; /* interrupt end of burst */ 130159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else 1302cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton devpriv->adc_fifo_bits |= INT_FNE; /* interrupt fifo not empty */ 130359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 1304cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton devpriv->adc_fifo_bits |= INT_FHF; /* interrupt fifo half full */ 130559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 130659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 1307aa4b8c725884b15c1d1467d382162e151b13a612Ravishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "comedi: adc_fifo_bits are 0x%x\n", 1308aa4b8c725884b15c1d1467d382162e151b13a612Ravishankar karkala Mallikarjunayya devpriv->adc_fifo_bits); 130959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 1310cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable (and clear) interrupts */ 131159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL, 13120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 13135f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 131459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1315cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set start trigger and burst mode */ 131659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits = 0; 131759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_src == TRIG_NOW) 131859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= SW_TRIGGER; 1319f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost else if (cmd->start_src == TRIG_EXT) { 132059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= EXT_TRIGGER | TGEN | XTRCL; 1321f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost if (thisboard->has_ai_trig_invert 1322f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost && (cmd->start_arg & CR_INVERT)) 1323f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost bits |= TGPOL; 1324f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost if (thisboard->has_ai_trig_gated && (cmd->start_arg & CR_EDGE)) 1325f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost bits |= TGSEL; 1326f1bc434398e8cf400374911357e89a13de366ce7Brice Dubost } else { 132759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "bug!"); 132859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 132959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 133059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) 133159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= BURSTE; 133259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(bits, devpriv->control_status + TRIG_CONTSTAT); 133359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 1334aa4b8c725884b15c1d1467d382162e151b13a612Ravishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "comedi: sent 0x%x to trig control\n", bits); 133559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 133659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 133759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 133859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 133959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 13400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_cmdtest(struct comedi_device *dev, 13410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 13420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd) 134359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 134459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int err = 0; 134559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int tmp; 134659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 134759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* cmdtest tests a particular command to see if it is valid. 134859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Using the cmdtest ioctl, a user can create a valid cmd 134959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * and then have it executes by the cmd ioctl. 135059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * 135159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * cmdtest returns 1,2,3,4 or 0, depending on which tests 135259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * the command passes. */ 135359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 135459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 1: make sure trigger sources are trivially valid */ 135559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 135659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->start_src; 135759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->start_src &= TRIG_INT; 135859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->start_src || tmp != cmd->start_src) 135959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 136059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 136159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_begin_src; 136259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; 136359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 136459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 136559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 136659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->convert_src; 136759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->convert_src &= TRIG_NOW; 136859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->convert_src || tmp != cmd->convert_src) 136959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 137059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 137159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_end_src; 137259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_end_src &= TRIG_COUNT; 137359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 137459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 137559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 137659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->stop_src; 137759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 137859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->stop_src || tmp != cmd->stop_src) 137959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 138059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 138159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 138259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 138359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 138459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 2: make sure trigger sources are unique and mutually compatible */ 138559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 138659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src != TRIG_TIMER && 13870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_src != TRIG_EXT) 138859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 138959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 139059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 139159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 139259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 139359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 2; 139459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 139559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 3: make sure arguments are trivially compatible */ 139659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 139759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_arg != 0) { 139859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->start_arg = 0; 139959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 140059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 140159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 140259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 140359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_arg < thisboard->ao_scan_speed) { 140459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_arg = thisboard->ao_scan_speed; 140559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 140659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 140759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 140859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 140959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_end_arg != cmd->chanlist_len) { 141059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_end_arg = cmd->chanlist_len; 141159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 141259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 141359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_NONE) { 141459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* TRIG_NONE */ 141559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_arg != 0) { 141659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->stop_arg = 0; 141759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 141859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 141959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 142059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 142159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 142259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 3; 142359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 142459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 4: fix up any arguments */ 142559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 142659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 142759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_begin_arg; 142859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, 14290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->ao_divisor1), 14300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->ao_divisor2), 14310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd->scan_begin_arg), 14320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 143359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (tmp != cmd->scan_begin_arg) 143459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 143559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 143659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 143759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 143859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 4; 143959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1440cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check channel/gain list against card's limitations */ 144159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->chanlist && cmd->chanlist_len > 1) { 144259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_CHAN(cmd->chanlist[0]) != 0 || 14430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_CHAN(cmd->chanlist[1]) != 1) { 144459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, 14450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "channels must be ordered channel 0, channel 1 in chanlist\n"); 144659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 144759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 144859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 144959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 145059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 145159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 5; 145259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 145359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 145459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 145559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 14560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_cmd(struct comedi_device *dev, 14570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 145859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 1459d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1460ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &async->cmd; 146159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int i; 146259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 146359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1464cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set channel limits, gain */ 14655f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 146659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < cmd->chanlist_len; i++) { 1467cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable channel */ 146859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= 14690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i])); 1470cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set range */ 147159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]), 14720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_RANGE(cmd-> 14730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral chanlist[i])); 147459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 147559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1476cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable analog out before settings pacer source and count values */ 147759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 14785f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 147959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1480cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear fifo */ 148159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->ao_registers + DACFIFOCLR); 148259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1483cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* load counters */ 148459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 148559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, 14860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->ao_divisor1), 14870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->ao_divisor2), 14880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd->scan_begin_arg), 14890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags); 149059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 149159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ 149259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1, 14930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->ao_divisor1, 2); 149459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2, 14950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->ao_divisor2, 2); 149659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1497cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set number of conversions */ 14982d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (cmd->stop_src == TRIG_COUNT) 149959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg; 1500cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set pacer source */ 15015f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 150259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez switch (cmd->scan_begin_src) { 150359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case TRIG_TIMER: 150459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= DAC_PACER_INT; 150559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 150659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case TRIG_EXT: 150759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= DAC_PACER_EXT_RISE; 150859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 150959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez default: 15105f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 151159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "error setting dac pacer source"); 151259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 151359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 151459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 15155f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 151659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 151759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->inttrig = cb_pcidas_ao_inttrig; 151859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 151959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 152059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 152159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1522d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pembertonstatic int cb_pcidas_ao_inttrig(struct comedi_device *dev, 1523d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_subdevice *s, 1524d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton unsigned int trig_num) 152559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 152659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int num_bytes, num_points = thisboard->fifo_size; 1527d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1528ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 152959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 153059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 153159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (trig_num != 0) 153259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 153359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1534cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* load up fifo */ 153559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points) 153659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_points = devpriv->ao_count; 153759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 153859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer, 15390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_points * sizeof(short)); 1540790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton num_points = num_bytes / sizeof(short); 154159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 15422d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (cmd->stop_src == TRIG_COUNT) 154359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_count -= num_points; 1544cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* write data to board's fifo */ 154559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes); 154659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1547cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable dac half-full and empty interrupts */ 15485f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 154959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits |= DAEMIE | DAHFIE; 155059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 155194cc0b4a6ea924b69bb8e784eb977d6a61ae5aceRavishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "comedi: adc_fifo_bits are 0x%x\n", 155294cc0b4a6ea924b69bb8e784eb977d6a61ae5aceRavishankar karkala Mallikarjunayya devpriv->adc_fifo_bits); 155359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 1554cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable and clear interrupts */ 155559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | DAEMI | DAHFI, 15560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 155759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1558cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* start dac */ 155959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY; 156059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 156159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 156294cc0b4a6ea924b69bb8e784eb977d6a61ae5aceRavishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "comedi: sent 0x%x to dac control\n", 156394cc0b4a6ea924b69bb8e784eb977d6a61ae5aceRavishankar karkala Mallikarjunayya devpriv->ao_control_bits); 156459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 15655f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 156659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 156759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->inttrig = NULL; 156859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 156959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 157059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 157159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 157270265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t cb_pcidas_interrupt(int irq, void *d) 157359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 15740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_device *dev = (struct comedi_device *)d; 157534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s = dev->read_subdev; 1576d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async; 157759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int status, s5933_status; 157859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int half_fifo = thisboard->fifo_size / 2; 157959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int num_samples, i; 158059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int timeout = 10000; 158159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 158259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 15832d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (dev->attached == 0) 158459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return IRQ_NONE; 158559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 158659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async = s->async; 158759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events = 0; 158859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 158959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR); 159059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 159194cc0b4a6ea924b69bb8e784eb977d6a61ae5aceRavishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "intcsr 0x%x\n", s5933_status); 159294cc0b4a6ea924b69bb8e784eb977d6a61ae5aceRavishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "mbef 0x%x\n", 159394cc0b4a6ea924b69bb8e784eb977d6a61ae5aceRavishankar karkala Mallikarjunayya inl(devpriv->s5933_config + AMCC_OP_REG_MBEF)); 159459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 159559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 159659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if ((INTCSR_INTR_ASSERTED & s5933_status) == 0) 159759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return IRQ_NONE; 159859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1599cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* make sure mailbox 4 is empty */ 160059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4); 1601cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear interrupt on amcc s5933 */ 160259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS, 16030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->s5933_config + AMCC_OP_REG_INTCSR); 160459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 160559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez status = inw(devpriv->control_status + INT_ADCFIFO); 160659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 16072d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) 160859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "spurious interrupt"); 160959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 161059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1611cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check for analog output interrupt */ 16122d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (status & (DAHFI | DAEMI)) 161359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez handle_ao_interrupt(dev, status); 1614cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check for analog input interrupts */ 1615cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* if fifo half-full */ 161659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (status & ADHFI) { 1617cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* read data */ 161859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_samples = half_fifo; 161959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (async->cmd.stop_src == TRIG_COUNT && 16200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples > devpriv->count) { 162159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_samples = devpriv->count; 162259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 162359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer, 16240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples); 162559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cfc_write_array_to_buffer(s, devpriv->ai_buffer, 16260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples * sizeof(short)); 162759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->count -= num_samples; 162859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) { 162959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_EOA; 163059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_cancel(dev, s); 163159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1632cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear half-full interrupt latch */ 16335f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 163459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | INT, 16350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 16365f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 1637cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* else if fifo not empty */ 163859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else if (status & (ADNEI | EOBI)) { 163959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < timeout; i++) { 1640cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* break if fifo is empty */ 164159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if ((ADNE & inw(devpriv->control_status + 16420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral INT_ADCFIFO)) == 0) 164359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 164459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cfc_write_to_buffer(s, inw(devpriv->adc_fifo)); 164559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (async->cmd.stop_src == TRIG_COUNT && --devpriv->count == 0) { /* end of acquisition */ 164659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_cancel(dev, s); 164759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_EOA; 164859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 164959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 165059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1651cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear not-empty interrupt latch */ 16525f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 165359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | INT, 16540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 16555f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 165659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else if (status & EOAI) { 165759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, 165825985edcedea6396277003854657b5f3cb31a628Lucas De Marchi "bug! encountered end of acquisition interrupt?"); 1659cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear EOA interrupt latch */ 16605f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 166159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | EOAI, 16620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 16635f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 166459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1665cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check for fifo overflow */ 166659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (status & LADFUL) { 166759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "fifo overflow"); 1668cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear overflow interrupt latch */ 16695f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 167059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | LADFUL, 16710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 16725f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 167359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_cancel(dev, s); 167459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 167559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 167659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 167759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_event(dev, s); 167859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 167959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return IRQ_HANDLED; 168059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 168159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1682da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void handle_ao_interrupt(struct comedi_device *dev, unsigned int status) 168359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 168434c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s = dev->write_subdev; 1685d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1686ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &async->cmd; 168759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int half_fifo = thisboard->fifo_size / 2; 168859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int num_points; 16893a5e32ddcb04d7a2bed86323ca22da51d3a810bdGerard Lledo unsigned long flags; 169059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 169159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events = 0; 169259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 169359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (status & DAEMI) { 1694cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear dac empty interrupt latch */ 16955f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 169659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | DAEMI, 16970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 16985f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 169959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) { 170059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_NONE || 17010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->stop_src == TRIG_COUNT 17020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral && devpriv->ao_count)) { 170359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "dac fifo underflow"); 170459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_ao_cancel(dev, s); 170559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_ERROR; 170659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 170759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_EOA; 170859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 170959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else if (status & DAHFI) { 171059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int num_bytes; 171159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1712cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* figure out how many points we are writing to fifo */ 171359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_points = half_fifo; 171459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_COUNT && 17150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->ao_count < num_points) 171659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_points = devpriv->ao_count; 171759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_bytes = 17180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cfc_read_array_from_buffer(s, devpriv->ao_buffer, 17190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_points * sizeof(short)); 1720790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton num_points = num_bytes / sizeof(short); 172159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 17222d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (async->cmd.stop_src == TRIG_COUNT) 172359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_count -= num_points; 1724cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* write data to board's fifo */ 172559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, 17260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_points); 1727cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear half-full interrupt latch */ 17285f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 172959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | DAHFI, 17300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 17315f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 173259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 173359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 173459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_event(dev, s); 173559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 173659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1737d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton/* cancel analog input command */ 17380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_cancel(struct comedi_device *dev, 17390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 174059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 174159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 174259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 17435f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 1744cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable interrupts */ 174559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits &= ~INTE & ~EOAIE; 174659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO); 17475f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 174859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1749cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable start trigger source and burst mode */ 175059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + TRIG_CONTSTAT); 1751cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* software pacer source */ 175259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + ADCMUX_CONT); 175359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 175459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 175559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 175659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1757d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton/* cancel analog output command */ 1758d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pembertonstatic int cb_pcidas_ao_cancel(struct comedi_device *dev, 1759d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_subdevice *s) 176059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 176159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 176259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 17635f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 1764cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable interrupts */ 176559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE; 176659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO); 176759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1768cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable output */ 176959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK; 177059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 17715f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 177259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 177359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 177459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 177559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1776da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns, 17770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral int rounding_flags) 177859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 177959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), 17800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor2), ns, 17810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral rounding_flags & TRIG_ROUND_MASK); 178259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 178359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ 178459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1, 17850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->divisor1, 2); 178659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2, 17870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->divisor2, 2); 178859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 178959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1790da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void write_calibration_bitstream(struct comedi_device *dev, 17910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int register_bits, 17920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int bitstream, 17930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int bitstream_length) 179459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 179559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int write_delay = 1; 179659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bit; 179759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 179859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) { 179959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (bitstream & bit) 180059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez register_bits |= SERIAL_DATA_IN_BIT; 180159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else 180259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez register_bits &= ~SERIAL_DATA_IN_BIT; 18035f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(write_delay); 180459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(register_bits, devpriv->control_status + CALIBRATION_REG); 180559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 180659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 180759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1808da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int caldac_8800_write(struct comedi_device *dev, unsigned int address, 18090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral uint8_t value) 181059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 181159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int num_caldac_channels = 8; 181259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int bitstream_length = 11; 181359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bitstream = ((address & 0x7) << 8) | value; 18145f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman static const int caldac_8800_udelay = 1; 181559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 181659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (address >= num_caldac_channels) { 181759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "illegal caldac channel"); 181859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 181959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 182059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 182159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (value == devpriv->caldac_value[address]) 182259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 182359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 182459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->caldac_value[address] = value; 182559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 182659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream, 18270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bitstream_length); 182859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 18295f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(caldac_8800_udelay); 183059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev) | SELECT_8800_BIT, 18310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + CALIBRATION_REG); 18325f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(caldac_8800_udelay); 183359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 183459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 183559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 183659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 183759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1838da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int trimpot_7376_write(struct comedi_device *dev, uint8_t value) 183959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 184059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int bitstream_length = 7; 184159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bitstream = value & 0x7f; 184259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int register_bits; 18435f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman static const int ad7376_udelay = 1; 184459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 184559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT; 18465f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(ad7376_udelay); 184759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(register_bits, devpriv->control_status + CALIBRATION_REG); 184859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 184959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez write_calibration_bitstream(dev, register_bits, bitstream, 18500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bitstream_length); 185159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 18525f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(ad7376_udelay); 185359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 185459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 185559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 185659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 185759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 185859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* For 1602/16 only 185959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * ch 0 : adc gain 186059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * ch 1 : adc postgain offset */ 1861da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int trimpot_8402_write(struct comedi_device *dev, unsigned int channel, 18620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral uint8_t value) 186359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 186459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int bitstream_length = 10; 186559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff); 186659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int register_bits; 18675f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman static const int ad8402_udelay = 1; 186859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 186959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT; 18705f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(ad8402_udelay); 187159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(register_bits, devpriv->control_status + CALIBRATION_REG); 187259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 187359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez write_calibration_bitstream(dev, register_bits, bitstream, 18740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bitstream_length); 187559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 18765f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(ad8402_udelay); 187759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 187859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 187959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 188059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 188159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 188259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic int wait_for_nvram_ready(unsigned long s5933_base_addr) 188359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 188459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int timeout = 1000; 188559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int i; 188659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 188759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < timeout; i++) { 188859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if ((inb(s5933_base_addr + 18890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY) 18900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral == 0) 189159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 18925f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 189359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 189459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 189559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 189659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 18970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int nvram_read(struct comedi_device *dev, unsigned int address, 18982d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini uint8_t *data) 189959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 190059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long iobase = devpriv->s5933_config; 190159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 190259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (wait_for_nvram_ready(iobase) < 0) 190359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ETIMEDOUT; 190459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 190559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR, 19060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral iobase + AMCC_OP_REG_MCSR_NVCMD); 190759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); 190859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR, 19090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral iobase + AMCC_OP_REG_MCSR_NVCMD); 191059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); 191159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD); 191259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 191359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (wait_for_nvram_ready(iobase) < 0) 191459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ETIMEDOUT; 191559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 191659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA); 191759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 191859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 191959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 192059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 192159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 192259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * A convenient macro that defines init_module() and cleanup_module(), 192359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * as necessary. 192459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 1925727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __devinit driver_cb_pcidas_pci_probe(struct pci_dev *dev, 1926727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas const struct pci_device_id *ent) 1927727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 1928727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return comedi_pci_auto_config(dev, driver_cb_pcidas.driver_name); 1929727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 1930727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1931727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __devexit driver_cb_pcidas_pci_remove(struct pci_dev *dev) 1932727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 1933727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_pci_auto_unconfig(dev); 1934727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 1935727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1936727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic struct pci_driver driver_cb_pcidas_pci_driver = { 1937727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .id_table = cb_pcidas_pci_table, 1938727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .probe = &driver_cb_pcidas_pci_probe, 1939727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .remove = __devexit_p(&driver_cb_pcidas_pci_remove) 1940727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}; 1941727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1942727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __init driver_cb_pcidas_init_module(void) 1943727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 1944727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas int retval; 1945727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1946727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas retval = comedi_driver_register(&driver_cb_pcidas); 1947727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas if (retval < 0) 1948727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return retval; 1949727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1950727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas driver_cb_pcidas_pci_driver.name = (char *)driver_cb_pcidas.driver_name; 1951727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return pci_register_driver(&driver_cb_pcidas_pci_driver); 1952727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 1953727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1954727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __exit driver_cb_pcidas_cleanup_module(void) 1955727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 1956727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas pci_unregister_driver(&driver_cb_pcidas_pci_driver); 1957727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_driver_unregister(&driver_cb_pcidas); 1958727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 1959727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1960727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_init(driver_cb_pcidas_init_module); 1961727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_exit(driver_cb_pcidas_cleanup_module); 196290f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 196390f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 196490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 196590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 1966