cb_pcidas.c revision 5f74ea14c07fee91d3bdbaad88bff6264c6200e6
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. 5659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez*/ 5759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 5859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 5959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezTODO: 6059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 6159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezanalog triggering on 1602 series 6259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez*/ 6359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 6459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include "../comedidev.h" 6559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include <linux/delay.h> 6670265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slaby#include <linux/interrupt.h> 6759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 6859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include "8253.h" 6959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include "8255.h" 7059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include "amcc_s5933.h" 7159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include "comedi_pci.h" 7259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#include "comedi_fc.h" 7359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 74cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#undef CB_PCIDAS_DEBUG /* disable debugging code */ 75cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* #define CB_PCIDAS_DEBUG enable debugging code */ 7659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 77cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* PCI vendor number of ComputerBoards/MeasurementComputing */ 7859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define PCI_VENDOR_ID_CB 0x1307 79cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define TIMER_BASE 100 /* 10MHz master clock */ 80cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define AI_BUFFER_SIZE 1024 /* maximum fifo size of any supported board */ 81cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define AO_BUFFER_SIZE 1024 /* maximum fifo size of any supported board */ 8259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define NUM_CHANNELS_8800 8 8359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define NUM_CHANNELS_7376 1 8459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define NUM_CHANNELS_8402 2 8559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define NUM_CHANNELS_DAC08 1 8659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 8759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* PCI-DAS base addresses */ 8859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 89cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* indices of base address regions */ 9059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define S5933_BADRINDEX 0 9159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define CONT_STAT_BADRINDEX 1 9259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define ADC_FIFO_BADRINDEX 2 9359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define PACER_BADRINDEX 3 9459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define AO_BADRINDEX 4 95cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* sizes of io regions */ 9659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define CONT_STAT_SIZE 10 9759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define ADC_FIFO_SIZE 4 9859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define PACER_SIZE 12 9959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define AO_SIZE 4 10059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 10159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* Control/Status registers */ 102cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INT_ADCFIFO 0 /* INTERRUPT / ADC FIFO register */ 103cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INT_EOS 0x1 /* interrupt end of scan */ 104cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INT_FHF 0x2 /* interrupt fifo half full */ 105cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INT_FNE 0x3 /* interrupt fifo not empty */ 106cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INT_MASK 0x3 /* mask of interrupt select bits */ 107cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INTE 0x4 /* interrupt enable */ 108cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DAHFIE 0x8 /* dac half full interrupt enable */ 109cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define EOAIE 0x10 /* end of aquisition interrupt enable */ 110cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DAHFI 0x20 /* dac half full read status / write interrupt clear */ 111cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define EOAI 0x40 /* read end of acq. interrupt status / write clear */ 112cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define INT 0x80 /* read interrupt status / write clear */ 113cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define EOBI 0x200 /* read end of burst interrupt status */ 114cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADHFI 0x400 /* read half-full interrupt status */ 115cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADNEI 0x800 /* read fifo not empty interrupt latch status */ 116cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADNE 0x1000 /* read, fifo not empty (realtime, not latched) status */ 117cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DAEMIE 0x1000 /* write, dac empty interrupt enable */ 118cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define LADFUL 0x2000 /* read fifo overflow / write clear */ 119cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DAEMI 0x4000 /* dac fifo empty interrupt status / write clear */ 120cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton 121cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADCMUX_CONT 2 /* ADC CHANNEL MUX AND CONTROL register */ 12259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define BEGIN_SCAN(x) ((x) & 0xf) 12359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define END_SCAN(x) (((x) & 0xf) << 4) 12459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define GAIN_BITS(x) (((x) & 0x3) << 8) 125cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define UNIP 0x800 /* Analog front-end unipolar for range */ 126cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define SE 0x400 /* Inputs in single-ended mode */ 127cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define PACER_MASK 0x3000 /* pacer source bits */ 128cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define PACER_INT 0x1000 /* internal pacer */ 129cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define PACER_EXT_FALL 0x2000 /* external falling edge */ 130cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define PACER_EXT_RISE 0x3000 /* external rising edge */ 131cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define EOC 0x4000 /* adc not busy */ 132cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton 133cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define TRIG_CONTSTAT 4 /* TRIGGER CONTROL/STATUS register */ 134cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define SW_TRIGGER 0x1 /* software start trigger */ 135cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define EXT_TRIGGER 0x2 /* external start trigger */ 136cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ANALOG_TRIGGER 0x3 /* external analog trigger */ 137cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define TRIGGER_MASK 0x3 /* mask of bits that determine start trigger */ 138cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define TGEN 0x10 /* enable external start trigger */ 139cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define BURSTE 0x20 /* burst mode enable */ 140cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define XTRCL 0x80 /* clear external trigger */ 141cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton 142cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define CALIBRATION_REG 6 /* CALIBRATION register */ 143cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define SELECT_8800_BIT 0x100 /* select 8800 caldac */ 144cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define SELECT_TRIMPOT_BIT 0x200 /* select ad7376 trim pot */ 145cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define SELECT_DAC08_BIT 0x400 /* select dac08 caldac */ 14659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define CAL_SRC_BITS(x) (((x) & 0x7) << 11) 147cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define CAL_EN_BIT 0x4000 /* read calibration source instead of analog input channel 0 */ 148cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define SERIAL_DATA_IN_BIT 0x8000 /* serial data stream going to 8800 and 7376 */ 14959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 150cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DAC_CSR 0x8 /* dac control and status register */ 15159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezenum dac_csr_bits { 152cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DACEN = 0x2, /* dac enable */ 153cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_MODE_UPDATE_BOTH = 0x80, /* update both dacs when dac0 is written */ 15459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 15559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range) 15659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 15759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return (range & 0x3) << (8 + 2 * (channel & 0x1)); 15859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 15959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic inline unsigned int DAC_RANGE_MASK(unsigned int channel) 16059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 16159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0x3 << (8 + 2 * (channel & 0x1)); 16259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 16359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 164cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* bits for 1602 series only */ 16559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezenum dac_csr_bits_1602 { 166cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_EMPTY = 0x1, /* dac fifo empty, read, write clear */ 167cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_START = 0x4, /* start/arm dac fifo operations */ 168cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_PACER_MASK = 0x18, /* bits that set dac pacer source */ 169cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_PACER_INT = 0x8, /* dac internal pacing */ 170cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_PACER_EXT_FALL = 0x10, /* dac external pacing, falling edge */ 171cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_PACER_EXT_RISE = 0x18, /* dac external pacing, rising edge */ 17259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 17359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic inline unsigned int DAC_CHAN_EN(unsigned int channel) 17459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 175cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton return 1 << (5 + (channel & 0x1)); /* enable channel 0 or 1 */ 17659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 17759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 17859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* analog input fifo */ 179cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADCDATA 0 /* ADC DATA register */ 180cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADCFIFOCLR 2 /* ADC FIFO CLEAR */ 18159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 182cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* pacer, counter, dio registers */ 18359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define ADC8254 0 18459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define DIO_8255 4 18559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define DAC8254 8 18659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 187cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output registers for 100x, 1200 series */ 18859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic inline unsigned int DAC_DATA_REG(unsigned int channel) 18959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 19059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 2 * (channel & 0x1); 19159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 19259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 19359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* analog output registers for 1602 series*/ 194cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DACDATA 0 /* DAC DATA register */ 195cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DACFIFOCLR 2 /* DAC FIFO CLEAR */ 19659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 197cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* bit in hexadecimal representation of range index that indicates unipolar input range */ 19859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define IS_UNIPOLAR 0x4 199cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog input ranges for most boards */ 2009ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange cb_pcidas_ranges = { 20159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 8, 20259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 20359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez BIP_RANGE(10), 20459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez BIP_RANGE(5), 20559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez BIP_RANGE(2.5), 20659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez BIP_RANGE(1.25), 20759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez UNI_RANGE(10), 20859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez UNI_RANGE(5), 20959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez UNI_RANGE(2.5), 21059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez UNI_RANGE(1.25) 21159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 21259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 21359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 214cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* pci-das1001 input ranges */ 2159ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange cb_pcidas_alt_ranges = { 21659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 8, 21759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 21859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez BIP_RANGE(10), 21959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez BIP_RANGE(1), 22059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez BIP_RANGE(0.1), 22159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez BIP_RANGE(0.01), 22259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez UNI_RANGE(10), 22359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez UNI_RANGE(1), 22459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez UNI_RANGE(0.1), 22559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez UNI_RANGE(0.01) 22659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 22759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 22859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 229cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output ranges */ 2309ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange cb_pcidas_ao_ranges = { 23159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 4, 23259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 23359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez BIP_RANGE(5), 23459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez BIP_RANGE(10), 23559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez UNI_RANGE(5), 23659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez UNI_RANGE(10), 23759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 23859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 23959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 24059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezenum trimpot_model { 24159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez AD7376, 24259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez AD8402, 24359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 24459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 2455c2670cba2a5fd1a27f938ae11b3a24518d999dbBill Pembertonstruct cb_pcidas_board { 24659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez const char *name; 24759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned short device_id; 248cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ai_se_chans; /* Inputs in single-ended mode */ 249cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ai_diff_chans; /* Inputs in differential mode */ 250cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ai_bits; /* analog input resolution */ 251cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ai_speed; /* fastest conversion period in ns */ 252cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ao_nchan; /* number of analog out channels */ 253cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int has_ao_fifo; /* analog output has fifo */ 254cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ao_scan_speed; /* analog output speed for 1602 series (for a scan, not conversion) */ 255cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int fifo_size; /* number of samples fifo can hold */ 2569ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pemberton const struct comedi_lrange *ranges; 25759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez enum trimpot_model trimpot; 25859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned has_dac08:1; 2595c2670cba2a5fd1a27f938ae11b3a24518d999dbBill Pemberton}; 26059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 2615c2670cba2a5fd1a27f938ae11b3a24518d999dbBill Pembertonstatic const struct cb_pcidas_board cb_pcidas_boards[] = { 26259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 26368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "pci-das1602/16", 26468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .device_id = 0x1, 26568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_se_chans = 16, 26668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_diff_chans = 8, 26768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_bits = 16, 26868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 5000, 26968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_nchan = 2, 27068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_ao_fifo = 1, 27168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_scan_speed = 10000, 27268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .fifo_size = 512, 27368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ranges = &cb_pcidas_ranges, 27468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .trimpot = AD8402, 27568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_dac08 = 1, 27659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez }, 27759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 27868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "pci-das1200", 27968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .device_id = 0xF, 28068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_se_chans = 16, 28168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_diff_chans = 8, 28268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_bits = 12, 28368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 3200, 28468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_nchan = 2, 28568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_ao_fifo = 0, 28668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .fifo_size = 1024, 28768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ranges = &cb_pcidas_ranges, 28868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .trimpot = AD7376, 28968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_dac08 = 0, 29059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez }, 29159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 29268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "pci-das1602/12", 29368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .device_id = 0x10, 29468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_se_chans = 16, 29568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_diff_chans = 8, 29668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_bits = 12, 29768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 3200, 29868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_nchan = 2, 29968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_ao_fifo = 1, 30068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_scan_speed = 4000, 30168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .fifo_size = 1024, 30268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ranges = &cb_pcidas_ranges, 30368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .trimpot = AD7376, 30468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_dac08 = 0, 30559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez }, 30659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 30768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "pci-das1200/jr", 30868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .device_id = 0x19, 30968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_se_chans = 16, 31068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_diff_chans = 8, 31168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_bits = 12, 31268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 3200, 31368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_nchan = 0, 31468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_ao_fifo = 0, 31568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .fifo_size = 1024, 31668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ranges = &cb_pcidas_ranges, 31768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .trimpot = AD7376, 31868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_dac08 = 0, 31959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez }, 32059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 32168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "pci-das1602/16/jr", 32268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .device_id = 0x1C, 32368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_se_chans = 16, 32468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_diff_chans = 8, 32568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_bits = 16, 32668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 5000, 32768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_nchan = 0, 32868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_ao_fifo = 0, 32968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .fifo_size = 512, 33068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ranges = &cb_pcidas_ranges, 33168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .trimpot = AD8402, 33268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_dac08 = 1, 33359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez }, 33459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 33568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "pci-das1000", 33668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .device_id = 0x4C, 33768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_se_chans = 16, 33868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_diff_chans = 8, 33968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_bits = 12, 34068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 4000, 34168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_nchan = 0, 34268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_ao_fifo = 0, 34368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .fifo_size = 1024, 34468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ranges = &cb_pcidas_ranges, 34568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .trimpot = AD7376, 34668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_dac08 = 0, 34759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez }, 34859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 34968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "pci-das1001", 35068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .device_id = 0x1a, 35168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_se_chans = 16, 35268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_diff_chans = 8, 35368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_bits = 12, 35468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 6800, 35568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_nchan = 2, 35668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_ao_fifo = 0, 35768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .fifo_size = 1024, 35868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ranges = &cb_pcidas_alt_ranges, 35968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .trimpot = AD7376, 36068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_dac08 = 0, 36159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez }, 36259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 36368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "pci-das1002", 36468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .device_id = 0x1b, 36568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_se_chans = 16, 36668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_diff_chans = 8, 36768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_bits = 12, 36868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 6800, 36968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_nchan = 2, 37068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_ao_fifo = 0, 37168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .fifo_size = 1024, 37268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ranges = &cb_pcidas_ranges, 37368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .trimpot = AD7376, 37468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .has_dac08 = 0, 37559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez }, 37659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 37759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 37859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = { 37959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez {PCI_VENDOR_ID_CB, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 38059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez {PCI_VENDOR_ID_CB, 0x000f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 38159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez {PCI_VENDOR_ID_CB, 0x0010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 38259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez {PCI_VENDOR_ID_CB, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 38359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez {PCI_VENDOR_ID_CB, 0x001c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 38459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez {PCI_VENDOR_ID_CB, 0x004c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 38559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez {PCI_VENDOR_ID_CB, 0x001a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 38659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez {PCI_VENDOR_ID_CB, 0x001b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 38759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez {0} 38859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 38959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 39059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezMODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table); 39159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 39259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 39359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Useful for shorthand access to the particular board structure 39459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 3955c2670cba2a5fd1a27f938ae11b3a24518d999dbBill Pemberton#define thisboard ((const struct cb_pcidas_board *)dev->board_ptr) 39659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 39759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* this structure is for data unique to this hardware driver. If 39859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez several hardware drivers keep similar information in this structure, 39971b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton feel free to suggest moving the variable to the struct comedi_device struct. */ 400c77e25898523395b56e1d120195e1ad2e3efa14dBill Pembertonstruct cb_pcidas_private { 40159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* would be useful for a PCI device */ 40259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez struct pci_dev *pci_dev; 403cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* base addresses */ 40459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long s5933_config; 40559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long control_status; 40659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long adc_fifo; 40759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long pacer_counter_dio; 40859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long ao_registers; 409cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* divisors of master clock for analog input pacing */ 41059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int divisor1; 41159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int divisor2; 412cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int count; /* number of analog input samples remaining */ 413cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int adc_fifo_bits; /* bits to write to interupt/adcfifo register */ 414cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int s5933_intcsr_bits; /* bits to write to amcc s5933 interrupt control/status register */ 415cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int ao_control_bits; /* bits to write to ao control and status register */ 416790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short ai_buffer[AI_BUFFER_SIZE]; 417790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short ao_buffer[AO_BUFFER_SIZE]; 418cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* divisors of master clock for analog output pacing */ 41959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int ao_divisor1; 42059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int ao_divisor2; 421cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int ao_count; /* number of analog output samples remaining */ 422cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ao_value[2]; /* remember what the analog outputs are set to, to allow readback */ 423cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton unsigned int caldac_value[NUM_CHANNELS_8800]; /* for readback of caldac */ 424cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton unsigned int trimpot_value[NUM_CHANNELS_8402]; /* for readback of trimpot */ 42559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int dac08_value; 42659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int calibration_source; 427c77e25898523395b56e1d120195e1ad2e3efa14dBill Pemberton}; 42859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 42959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 43059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * most drivers define the following macro to make it easy to 43159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * access the private structure. 43259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 433c77e25898523395b56e1d120195e1ad2e3efa14dBill Pemberton#define devpriv ((struct cb_pcidas_private *)dev->private) 43459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 43559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 436139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pemberton * The struct comedi_driver structure tells the Comedi core module 43759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * which functions to call to configure/deconfigure (attach/detach) 43859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * the board, and also about the kernel module that contains 43959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * the device code. 44059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 441da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_attach(struct comedi_device *dev, struct comedi_devconfig *it); 442da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_detach(struct comedi_device *dev); 443139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_cb_pcidas = { 44468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "cb_pcidas", 44568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 44668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = cb_pcidas_attach, 44768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = cb_pcidas_detach, 44859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 44959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 450d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pembertonstatic int cb_pcidas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice * s, 451814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 452814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, 453814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 454814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev, struct comedi_subdevice *s, 455814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 456814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev, struct comedi_subdevice *s, 457814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 458814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int cb_pcidas_ao_readback_insn(struct comedi_device *dev, struct comedi_subdevice *s, 459814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 460814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int cb_pcidas_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s); 461814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int cb_pcidas_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, 462814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_cmd *cmd); 463814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int cb_pcidas_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s); 464d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pembertonstatic int cb_pcidas_ao_inttrig(struct comedi_device *dev, 465d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_subdevice *subdev, 466d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton unsigned int trig_num); 467814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int cb_pcidas_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, 468814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_cmd *cmd); 46970265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t cb_pcidas_interrupt(int irq, void *d); 470814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void handle_ao_interrupt(struct comedi_device *dev, unsigned int status); 471814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int cb_pcidas_cancel(struct comedi_device *dev, struct comedi_subdevice *s); 472814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int cb_pcidas_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s); 473814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns, 47459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int round_flags); 475814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int eeprom_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, 476814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 477814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int caldac_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, 478814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 479814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int caldac_write_insn(struct comedi_device *dev, struct comedi_subdevice *s, 480814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 481814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int trimpot_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, 482814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 483814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int cb_pcidas_trimpot_write(struct comedi_device *dev, unsigned int channel, 484790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int value); 485814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int trimpot_write_insn(struct comedi_device *dev, struct comedi_subdevice *s, 486814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 487814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int dac08_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, 488814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 489814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int dac08_write(struct comedi_device *dev, unsigned int value); 490814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int dac08_write_insn(struct comedi_device *dev, struct comedi_subdevice *s, 491814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 492814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int caldac_8800_write(struct comedi_device *dev, unsigned int address, 49359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez uint8_t value); 494814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int trimpot_7376_write(struct comedi_device *dev, uint8_t value); 495814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int trimpot_8402_write(struct comedi_device *dev, unsigned int channel, 49659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez uint8_t value); 497814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int nvram_read(struct comedi_device *dev, unsigned int address, 498814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton uint8_t *data); 49959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 500814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic inline unsigned int cal_enable_bits(struct comedi_device *dev) 50159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 50259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source); 50359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 50459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 50559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 50659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Attach is called by the Comedi core to configure the driver 50759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * for a particular board. 50859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 509da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_attach(struct comedi_device *dev, struct comedi_devconfig *it) 51059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 51134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 51259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez struct pci_dev *pcidev; 51359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int index; 51459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int i; 51559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 51659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk("comedi%d: cb_pcidas: ", dev->minor); 51759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 51859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 51959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Allocate the private structure area. 52059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 521c77e25898523395b56e1d120195e1ad2e3efa14dBill Pemberton if (alloc_private(dev, sizeof(struct cb_pcidas_private)) < 0) 52259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ENOMEM; 52359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 52459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 52559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Probe the device to determine what device in the series it is. 52659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 52759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk("\n"); 52859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 52959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); 53059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez pcidev != NULL; 53159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) { 532cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* is it not a computer boards card? */ 53359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (pcidev->vendor != PCI_VENDOR_ID_CB) 53459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez continue; 535cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* loop through cards supported by this driver */ 5368629efa4cbf6f89a54a85af4b8bc31762af01800Bill Pemberton for (index = 0; index < ARRAY_SIZE(cb_pcidas_boards); index++) { 53759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cb_pcidas_boards[index].device_id != pcidev->device) 53859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez continue; 539cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* was a particular bus/slot requested? */ 54059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (it->options[0] || it->options[1]) { 541cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* are we on the wrong bus/slot? */ 54259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (pcidev->bus->number != it->options[0] || 54359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez PCI_SLOT(pcidev->devfn) != 54459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez it->options[1]) { 54559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez continue; 54659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 54759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 54859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->pci_dev = pcidev; 54959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->board_ptr = cb_pcidas_boards + index; 55059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez goto found; 55159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 55259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 55359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 55459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk("No supported ComputerBoards/MeasurementComputing card found on " 55559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez "requested position\n"); 55659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EIO; 55759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 55859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez found: 55959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 56059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk("Found %s on bus %i, slot %i\n", cb_pcidas_boards[index].name, 56159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez pcidev->bus->number, PCI_SLOT(pcidev->devfn)); 56259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 56359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* 56459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Enable PCI device and reserve I/O ports. 56559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 56659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (comedi_pci_enable(pcidev, "cb_pcidas")) { 56759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk(" Failed to enable PCI device and request regions\n"); 56859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EIO; 56959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 57059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* 57159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Initialize devpriv->control_status and devpriv->adc_fifo to point to 57259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * their base address. 57359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 57459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->s5933_config = 57559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX); 57659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status = 57759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX); 57859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo = 57959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX); 58059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->pacer_counter_dio = 58159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX); 58259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->ao_nchan) { 58359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_registers = 58459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez pci_resource_start(devpriv->pci_dev, AO_BADRINDEX); 58559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 586cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable and clear interrupts on amcc s5933 */ 58759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outl(INTCSR_INBOX_INTR_STATUS, 58859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->s5933_config + AMCC_OP_REG_INTCSR); 58959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 590cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* get irq */ 5915f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman if (request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt, 59259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez IRQF_SHARED, "cb_pcidas", dev)) { 59359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk(" unable to allocate irq %d\n", devpriv->pci_dev->irq); 59459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 59559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 59659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->irq = devpriv->pci_dev->irq; 59759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 598cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* Initialize dev->board_name */ 59959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->board_name = thisboard->name; 60059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 60159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 60259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Allocate the subdevice structures. 60359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 60459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (alloc_subdevices(dev, 7) < 0) 60559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ENOMEM; 60659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 60759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 0; 60859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* analog input subdevice */ 60959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->read_subdev = s; 61059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_AI; 61159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; 61259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* WARNING: Number of inputs in differential mode is ignored */ 61359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = thisboard->ai_se_chans; 61459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->len_chanlist = thisboard->ai_se_chans; 61559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = (1 << thisboard->ai_bits) - 1; 61659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->range_table = thisboard->ranges; 61759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = cb_pcidas_ai_rinsn; 61859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_config = ai_config_insn; 61959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->do_cmd = cb_pcidas_ai_cmd; 62059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->do_cmdtest = cb_pcidas_ai_cmdtest; 62159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->cancel = cb_pcidas_cancel; 62259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 62359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* analog output subdevice */ 62459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 1; 62559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->ao_nchan) { 62659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_AO; 62759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; 62859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = thisboard->ao_nchan; 629cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* analog out resolution is the same as analog input resolution, so use ai_bits */ 63059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = (1 << thisboard->ai_bits) - 1; 63159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->range_table = &cb_pcidas_ao_ranges; 63259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = cb_pcidas_ao_readback_insn; 63359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->has_ao_fifo) { 63459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->write_subdev = s; 63559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags |= SDF_CMD_WRITE; 63659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = cb_pcidas_ao_fifo_winsn; 63759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->do_cmdtest = cb_pcidas_ao_cmdtest; 63859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->do_cmd = cb_pcidas_ao_cmd; 63959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->cancel = cb_pcidas_ao_cancel; 64059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 64159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = cb_pcidas_ao_nofifo_winsn; 64259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 64359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 64459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_UNUSED; 64559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 64659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 64759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* 8255 */ 64859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 2; 64959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez subdev_8255_init(dev, s, NULL, devpriv->pacer_counter_dio + DIO_8255); 65059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 651cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* serial EEPROM, */ 65259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 3; 65359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_MEMORY; 65459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_INTERNAL; 65559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = 256; 65659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0xff; 65759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = eeprom_read_insn; 65859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 659cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* 8800 caldac */ 66059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 4; 66159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_CALIB; 66259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 66359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = NUM_CHANNELS_8800; 66459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0xff; 66559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = caldac_read_insn; 66659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = caldac_write_insn; 66759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < s->n_chan; i++) 66859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez caldac_8800_write(dev, i, s->maxdata / 2); 66959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 670cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* trim potentiometer */ 67159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 5; 67259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_CALIB; 67359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 67459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->trimpot == AD7376) { 67559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = NUM_CHANNELS_7376; 67659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0x7f; 67759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 67859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = NUM_CHANNELS_8402; 67959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0xff; 68059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 68159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = trimpot_read_insn; 68259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = trimpot_write_insn; 68359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < s->n_chan; i++) 68459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_trimpot_write(dev, i, s->maxdata / 2); 68559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 686cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* dac08 caldac */ 68759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 6; 68859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->has_dac08) { 68959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_CALIB; 69059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 69159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = NUM_CHANNELS_DAC08; 69259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = dac08_read_insn; 69359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = dac08_write_insn; 69459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0xff; 69559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dac08_write(dev, s->maxdata / 2); 69659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else 69759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_UNUSED; 69859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 699cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* make sure mailbox 4 is empty */ 70059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez inl(devpriv->s5933_config + AMCC_OP_REG_IMB4); 70159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* Set bits to enable incoming mailbox interrupts on amcc s5933. */ 70259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->s5933_intcsr_bits = 70359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) | 70459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez INTCSR_INBOX_FULL_INT; 705cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear and enable interrupt on amcc s5933 */ 70659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS, 70759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->s5933_config + AMCC_OP_REG_INTCSR); 70859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 70959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 71059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 71159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 71259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 71359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * cb_pcidas_detach is called to deconfigure a device. It should deallocate 71459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * resources. 71559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * This function is also called when _attach() fails, so it should be 71659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * careful not to release resources that were not necessarily 71759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * allocated by _attach(). dev->private and dev->subdevices are 71859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * deallocated automatically by the core. 71959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 720da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_detach(struct comedi_device *dev) 72159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 72259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk("comedi%d: cb_pcidas: remove\n", dev->minor); 72359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 72459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv) { 72559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv->s5933_config) { 726cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable and clear interrupts on amcc s5933 */ 72759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outl(INTCSR_INBOX_INTR_STATUS, 72859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->s5933_config + AMCC_OP_REG_INTCSR); 72959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 7305f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("detaching, incsr is 0x%x\n", 73159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez inl(devpriv->s5933_config + 73259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez AMCC_OP_REG_INTCSR)); 73359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 73459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 73559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 73659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (dev->irq) 7375f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 73859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (dev->subdevices) 73959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez subdev_8255_cleanup(dev, dev->subdevices + 2); 74059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv && devpriv->pci_dev) { 74159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv->s5933_config) { 74259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_pci_disable(devpriv->pci_dev); 74359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 74459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez pci_dev_put(devpriv->pci_dev); 74559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 74659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 74759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 74859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 74959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 75059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 75159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * "instructions" read/write data in "one-shot" or "software-triggered" 75259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * mode. 75359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 754da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, 755da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 75659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 75759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int n, i; 75859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bits; 75959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int timeout = 10000; 76059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int channel; 761cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable calibration input if appropriate */ 76259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (insn->chanspec & CR_ALT_SOURCE) { 76359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev), 76459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status + CALIBRATION_REG); 76559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez channel = 0; 76659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 76759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + CALIBRATION_REG); 76859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez channel = CR_CHAN(insn->chanspec); 76959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 770cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set mux limits and gain */ 77159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits = BEGIN_SCAN(channel) | 77259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez END_SCAN(channel) | GAIN_BITS(CR_RANGE(insn->chanspec)); 773cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set unipolar/bipolar */ 77459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_RANGE(insn->chanspec) & IS_UNIPOLAR) 77559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= UNIP; 776cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set singleended/differential */ 77759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_AREF(insn->chanspec) != AREF_DIFF) 77859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= SE; 77959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(bits, devpriv->control_status + ADCMUX_CONT); 78059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 78159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* clear fifo */ 78259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->adc_fifo + ADCFIFOCLR); 78359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 78459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* convert n samples */ 78559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (n = 0; n < insn->n; n++) { 78659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* trigger conversion */ 78759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->adc_fifo + ADCDATA); 78859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 78959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* wait for conversion to end */ 79059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* return -ETIMEDOUT if there is a timeout */ 79159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < timeout; i++) { 79259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (inw(devpriv->control_status + ADCMUX_CONT) & EOC) 79359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 79459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 79559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (i == timeout) 79659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ETIMEDOUT; 79759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 79859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* read data */ 79959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[n] = inw(devpriv->adc_fifo + ADCDATA); 80059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 80159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 80259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* return the number of samples read/written */ 80359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return n; 80459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 80559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 806da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ai_config_calibration_source(struct comedi_device *dev, unsigned int *data) 80759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 80859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int num_calibration_sources = 8; 809790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int source = data[1]; 81059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 81159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (source >= num_calibration_sources) { 81259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk("invalid calibration source: %i\n", source); 81359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 81459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 81559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 81659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->calibration_source = source; 81759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 81859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 2; 81959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 82059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 821da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, 822da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 82359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 82459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int id = data[0]; 82559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 82659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez switch (id) { 82759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case INSN_CONFIG_ALT_SOURCE: 82859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return ai_config_calibration_source(dev, data); 82959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 83059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez default: 83159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 83259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 83359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 83459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 83559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 83659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 837cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output insn for pcidas-1000 and 1200 series */ 838da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev, struct comedi_subdevice *s, 839da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 84059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 84159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int channel; 84259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 84359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 844cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set channel and range */ 84559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez channel = CR_CHAN(insn->chanspec); 8465f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 84759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits &= 84859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez ~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel); 84959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= 85059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec)); 85159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 8525f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 85359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 854cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* remember value for readback */ 85559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_value[channel] = data[0]; 856cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* send data */ 85759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(data[0], devpriv->ao_registers + DAC_DATA_REG(channel)); 85859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 85959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 86059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 86159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 862cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output insn for pcidas-1602 series */ 863da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev, struct comedi_subdevice *s, 864da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 86559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 86659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int channel; 86759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 86859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 869cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear dac fifo */ 87059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->ao_registers + DACFIFOCLR); 87159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 872cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set channel and range */ 87359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez channel = CR_CHAN(insn->chanspec); 8745f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 87559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits &= 87659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez ~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) & ~DAC_RANGE_MASK(channel) & 87759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez ~DAC_PACER_MASK; 87859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= 87959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez DACEN | DAC_RANGE(channel, 88059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez CR_RANGE(insn->chanspec)) | DAC_CHAN_EN(channel) | DAC_START; 88159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 8825f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 88359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 884cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* remember value for readback */ 88559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_value[channel] = data[0]; 886cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* send data */ 88759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(data[0], devpriv->ao_registers + DACDATA); 88859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 88959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 89059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 89159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 892cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output readback insn */ 893cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* XXX loses track of analog output value back after an analog ouput command is executed */ 894da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_ao_readback_insn(struct comedi_device *dev, struct comedi_subdevice *s, 895da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 89659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 89759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)]; 89859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 89959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 90059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 90159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 902da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int eeprom_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, 903da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 90459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 90559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez uint8_t nvram_data; 90659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int retval; 90759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 90859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data); 90959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (retval < 0) 91059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return retval; 91159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 91259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = nvram_data; 91359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 91459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 91559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 91659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 917da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int caldac_write_insn(struct comedi_device *dev, struct comedi_subdevice *s, 918da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 91959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 92059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez const unsigned int channel = CR_CHAN(insn->chanspec); 92159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 92259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return caldac_8800_write(dev, channel, data[0]); 92359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 92459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 925da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int caldac_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, 926da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 92759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 92859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)]; 92959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 93059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 93159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 93259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 93359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 1602/16 pregain offset */ 934da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dac08_write(struct comedi_device *dev, unsigned int value) 93559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 93659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv->dac08_value == value) 93759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 93859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 93959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->dac08_value = value; 94059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 94159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev) | (value & 0xff), 94259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status + CALIBRATION_REG); 9435f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 94459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev) | SELECT_DAC08_BIT | (value & 0xff), 94559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status + CALIBRATION_REG); 9465f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 94759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev) | (value & 0xff), 94859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status + CALIBRATION_REG); 9495f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 95059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 95159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 95259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 95359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 954da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dac08_write_insn(struct comedi_device *dev, struct comedi_subdevice *s, 955da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 95659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 95759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return dac08_write(dev, data[0]); 95859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 95959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 960da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dac08_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, 961da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 96259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 96359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = devpriv->dac08_value; 96459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 96559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 96659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 96759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 968da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_trimpot_write(struct comedi_device *dev, 969790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int channel, unsigned int value) 97059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 97159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv->trimpot_value[channel] == value) 97259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 97359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 97459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->trimpot_value[channel] = value; 97559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez switch (thisboard->trimpot) { 97659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case AD7376: 97759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez trimpot_7376_write(dev, value); 97859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 97959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case AD8402: 98059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez trimpot_8402_write(dev, channel, value); 98159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 98259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez default: 98359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "driver bug?"); 98459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 98559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 98659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 98759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 98859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 98959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 99059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 991da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int trimpot_write_insn(struct comedi_device *dev, struct comedi_subdevice *s, 992da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 99359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 99459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int channel = CR_CHAN(insn->chanspec); 99559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 99659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return cb_pcidas_trimpot_write(dev, channel, data[0]); 99759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 99859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 999da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int trimpot_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, 1000da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 100159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 100259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int channel = CR_CHAN(insn->chanspec); 100359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 100459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = devpriv->trimpot_value[channel]; 100559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 100659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 100759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 100859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1009da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, 1010da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_cmd *cmd) 101159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 101259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int err = 0; 101359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int tmp; 101459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int i, gain, start_chan; 101559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 101659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* cmdtest tests a particular command to see if it is valid. 101759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Using the cmdtest ioctl, a user can create a valid cmd 101859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * and then have it executes by the cmd ioctl. 101959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * 102059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * cmdtest returns 1,2,3,4 or 0, depending on which tests 102159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * the command passes. */ 102259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 102359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 1: make sure trigger sources are trivially valid */ 102459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 102559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->start_src; 102659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->start_src &= TRIG_NOW | TRIG_EXT; 102759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->start_src || tmp != cmd->start_src) 102859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 102959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 103059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_begin_src; 103159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; 103259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 103359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 103459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 103559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->convert_src; 103659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT; 103759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->convert_src || tmp != cmd->convert_src) 103859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 103959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 104059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_end_src; 104159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_end_src &= TRIG_COUNT; 104259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 104359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 104459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 104559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->stop_src; 104659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 104759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->stop_src || tmp != cmd->stop_src) 104859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 104959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 105059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 105159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 105259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 105359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 2: make sure trigger sources are unique and mutually compatible */ 105459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 105559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) 105659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 105759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src != TRIG_FOLLOW && 105859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_src != TRIG_TIMER && 105959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_src != TRIG_EXT) 106059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 106159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src != TRIG_TIMER && 106259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) 106359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 106459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 106559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 106659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1067cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* make sure trigger sources are compatible with each other */ 106859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW) 106959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 107059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW) 107159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 107259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_src == TRIG_EXT && 107359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez (cmd->convert_src == TRIG_EXT 107459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez || cmd->scan_begin_src == TRIG_EXT)) 107559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 107659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 107759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 107859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 2; 107959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 108059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 3: make sure arguments are trivially compatible */ 108159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 108259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_arg != 0) { 108359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->start_arg = 0; 108459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 108559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 108659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 108759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 108859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_arg < 108959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez thisboard->ai_speed * cmd->chanlist_len) { 109059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_arg = 109159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez thisboard->ai_speed * cmd->chanlist_len; 109259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 109359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 109459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 109559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_TIMER) { 109659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_arg < thisboard->ai_speed) { 109759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->convert_arg = thisboard->ai_speed; 109859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 109959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 110059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 110159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 110259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_end_arg != cmd->chanlist_len) { 110359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_end_arg = cmd->chanlist_len; 110459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 110559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 110659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_NONE) { 110759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* TRIG_NONE */ 110859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_arg != 0) { 110959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->stop_arg = 0; 111059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 111159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 111259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 111359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 111459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 111559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 3; 111659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 111759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 4: fix up any arguments */ 111859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 111959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 112059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_begin_arg; 112159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, 112259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez &(devpriv->divisor1), &(devpriv->divisor2), 112359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez &(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK); 112459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (tmp != cmd->scan_begin_arg) 112559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 112659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 112759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_TIMER) { 112859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->convert_arg; 112959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, 113059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez &(devpriv->divisor1), &(devpriv->divisor2), 113159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK); 113259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (tmp != cmd->convert_arg) 113359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 113459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 113559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 113659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 113759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 4; 113859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1139cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check channel/gain list against card's limitations */ 114059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->chanlist) { 114159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez gain = CR_RANGE(cmd->chanlist[0]); 114259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez start_chan = CR_CHAN(cmd->chanlist[0]); 114359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 1; i < cmd->chanlist_len; i++) { 114459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_CHAN(cmd->chanlist[i]) != 114559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez (start_chan + i) % s->n_chan) { 114659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, 114759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez "entries in chanlist must be consecutive channels, counting upwards\n"); 114859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 114959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 115059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_RANGE(cmd->chanlist[i]) != gain) { 115159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, 115259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez "entries in chanlist must all have the same gain\n"); 115359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 115459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 115559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 115659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 115759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 115859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 115959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 5; 116059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 116159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 116259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 116359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1164da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 116559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 1166d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1167ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &async->cmd; 116859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bits; 116959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 117059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1171cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* make sure CAL_EN_BIT is disabled */ 117259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + CALIBRATION_REG); 1173cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* initialize before settings pacer source and count values */ 117459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + TRIG_CONTSTAT); 1175cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear fifo */ 117659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->adc_fifo + ADCFIFOCLR); 117759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1178cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set mux limits, gain and pacer source */ 117959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) | 118059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) | 118159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez GAIN_BITS(CR_RANGE(cmd->chanlist[0])); 1182cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set unipolar/bipolar */ 118359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR) 118459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= UNIP; 1185cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set singleended/differential */ 118659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF) 118759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= SE; 1188cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set pacer source */ 118959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT) 119059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= PACER_EXT_RISE; 119159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else 119259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= PACER_INT; 119359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(bits, devpriv->control_status + ADCMUX_CONT); 119459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 119559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 11965f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("comedi: sent 0x%x to adcmux control\n", bits); 119759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 119859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1199cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* load counters */ 120059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_TIMER) 120159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_load_counters(dev, &cmd->convert_arg, 120259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->flags & TRIG_ROUND_MASK); 120359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else if (cmd->scan_begin_src == TRIG_TIMER) 120459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_load_counters(dev, &cmd->scan_begin_arg, 120559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->flags & TRIG_ROUND_MASK); 120659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1207cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set number of conversions */ 120859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_COUNT) { 120959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->count = cmd->chanlist_len * cmd->stop_arg; 121059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1211cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable interrupts */ 12125f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 121359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits |= INTE; 121459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits &= ~INT_MASK; 121559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->flags & TRIG_WAKE_EOS) { 121659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) 1217cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton devpriv->adc_fifo_bits |= INT_EOS; /* interrupt end of burst */ 121859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else 1219cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton devpriv->adc_fifo_bits |= INT_FNE; /* interrupt fifo not empty */ 122059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 1221cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton devpriv->adc_fifo_bits |= INT_FHF; /* interrupt fifo half full */ 122259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 122359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 12245f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits); 122559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 1226cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable (and clear) interrupts */ 122759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL, 122859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status + INT_ADCFIFO); 12295f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 123059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1231cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set start trigger and burst mode */ 123259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits = 0; 123359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_src == TRIG_NOW) 123459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= SW_TRIGGER; 123559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else if (cmd->start_src == TRIG_EXT) 123659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= EXT_TRIGGER | TGEN | XTRCL; 123759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else { 123859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "bug!"); 123959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 124059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 124159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) 124259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= BURSTE; 124359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(bits, devpriv->control_status + TRIG_CONTSTAT); 124459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 12455f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("comedi: sent 0x%x to trig control\n", bits); 124659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 124759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 124859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 124959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 125059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1251da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, 1252da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_cmd *cmd) 125359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 125459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int err = 0; 125559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int tmp; 125659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 125759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* cmdtest tests a particular command to see if it is valid. 125859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Using the cmdtest ioctl, a user can create a valid cmd 125959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * and then have it executes by the cmd ioctl. 126059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * 126159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * cmdtest returns 1,2,3,4 or 0, depending on which tests 126259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * the command passes. */ 126359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 126459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 1: make sure trigger sources are trivially valid */ 126559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 126659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->start_src; 126759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->start_src &= TRIG_INT; 126859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->start_src || tmp != cmd->start_src) 126959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 127059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 127159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_begin_src; 127259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; 127359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 127459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 127559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 127659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->convert_src; 127759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->convert_src &= TRIG_NOW; 127859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->convert_src || tmp != cmd->convert_src) 127959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 128059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 128159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_end_src; 128259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_end_src &= TRIG_COUNT; 128359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 128459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 128559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 128659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->stop_src; 128759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 128859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->stop_src || tmp != cmd->stop_src) 128959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 129059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 129159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 129259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 129359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 129459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 2: make sure trigger sources are unique and mutually compatible */ 129559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 129659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src != TRIG_TIMER && 129759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_src != TRIG_EXT) 129859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 129959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 130059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 130159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 130259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 130359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 2; 130459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 130559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 3: make sure arguments are trivially compatible */ 130659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 130759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_arg != 0) { 130859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->start_arg = 0; 130959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 131059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 131159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 131259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 131359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_arg < thisboard->ao_scan_speed) { 131459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_arg = thisboard->ao_scan_speed; 131559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 131659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 131759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 131859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 131959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_end_arg != cmd->chanlist_len) { 132059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_end_arg = cmd->chanlist_len; 132159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 132259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 132359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_NONE) { 132459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* TRIG_NONE */ 132559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_arg != 0) { 132659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->stop_arg = 0; 132759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 132859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 132959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 133059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 133159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 133259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 3; 133359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 133459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 4: fix up any arguments */ 133559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 133659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 133759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_begin_arg; 133859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, 133959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez &(devpriv->ao_divisor1), &(devpriv->ao_divisor2), 134059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez &(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK); 134159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (tmp != cmd->scan_begin_arg) 134259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 134359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 134459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 134559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 134659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 4; 134759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1348cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check channel/gain list against card's limitations */ 134959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->chanlist && cmd->chanlist_len > 1) { 135059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_CHAN(cmd->chanlist[0]) != 0 || 135159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez CR_CHAN(cmd->chanlist[1]) != 1) { 135259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, 135359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez "channels must be ordered channel 0, channel 1 in chanlist\n"); 135459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 135559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 135659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 135759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 135859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 135959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 5; 136059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 136159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 136259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 136359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1364da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 136559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 1366d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1367ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &async->cmd; 136859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int i; 136959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 137059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1371cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set channel limits, gain */ 13725f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 137359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < cmd->chanlist_len; i++) { 1374cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable channel */ 137559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= 137659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i])); 1377cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set range */ 137859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]), 137959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez CR_RANGE(cmd->chanlist[i])); 138059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 138159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1382cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable analog out before settings pacer source and count values */ 138359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 13845f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 138559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1386cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear fifo */ 138759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->ao_registers + DACFIFOCLR); 138859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1389cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* load counters */ 139059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 139159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, 139259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez &(devpriv->ao_divisor1), &(devpriv->ao_divisor2), 139359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez &(cmd->scan_begin_arg), cmd->flags); 139459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 139559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ 139659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1, 139759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_divisor1, 2); 139859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2, 139959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_divisor2, 2); 140059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1401cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set number of conversions */ 140259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_COUNT) { 140359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg; 140459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1405cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set pacer source */ 14065f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 140759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez switch (cmd->scan_begin_src) { 140859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case TRIG_TIMER: 140959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= DAC_PACER_INT; 141059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 141159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case TRIG_EXT: 141259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= DAC_PACER_EXT_RISE; 141359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 141459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez default: 14155f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 141659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "error setting dac pacer source"); 141759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 141859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 141959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 14205f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 142159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 142259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->inttrig = cb_pcidas_ao_inttrig; 142359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 142459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 142559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 142659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1427d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pembertonstatic int cb_pcidas_ao_inttrig(struct comedi_device *dev, 1428d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_subdevice *s, 1429d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton unsigned int trig_num) 143059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 143159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int num_bytes, num_points = thisboard->fifo_size; 1432d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1433ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 143459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 143559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 143659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (trig_num != 0) 143759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 143859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1439cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* load up fifo */ 144059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points) 144159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_points = devpriv->ao_count; 144259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 144359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer, 1444790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton num_points * sizeof(short)); 1445790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton num_points = num_bytes / sizeof(short); 144659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 144759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_COUNT) { 144859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_count -= num_points; 144959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1450cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* write data to board's fifo */ 145159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes); 145259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1453cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable dac half-full and empty interrupts */ 14545f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 145559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits |= DAEMIE | DAHFIE; 145659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 14575f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits); 145859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 1459cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable and clear interrupts */ 146059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | DAEMI | DAHFI, 146159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status + INT_ADCFIFO); 146259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1463cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* start dac */ 146459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY; 146559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 146659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 14675f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("comedi: sent 0x%x to dac control\n", 146859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits); 146959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 14705f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 147159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 147259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->inttrig = NULL; 147359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 147459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 147559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 147659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 147770265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t cb_pcidas_interrupt(int irq, void *d) 147859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 147971b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton struct comedi_device *dev = (struct comedi_device *) d; 148034c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s = dev->read_subdev; 1481d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async; 148259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int status, s5933_status; 148359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int half_fifo = thisboard->fifo_size / 2; 148459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int num_samples, i; 148559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int timeout = 10000; 148659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 148759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 148859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (dev->attached == 0) { 148959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return IRQ_NONE; 149059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 149159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 149259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async = s->async; 149359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events = 0; 149459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 149559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR); 149659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 14975f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("intcsr 0x%x\n", s5933_status); 14985f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("mbef 0x%x\n", inl(devpriv->s5933_config + AMCC_OP_REG_MBEF)); 149959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 150059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 150159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if ((INTCSR_INTR_ASSERTED & s5933_status) == 0) 150259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return IRQ_NONE; 150359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1504cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* make sure mailbox 4 is empty */ 150559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4); 1506cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear interrupt on amcc s5933 */ 150759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS, 150859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->s5933_config + AMCC_OP_REG_INTCSR); 150959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 151059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez status = inw(devpriv->control_status + INT_ADCFIFO); 151159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 151259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) { 151359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "spurious interrupt"); 151459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 151559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 151659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1517cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check for analog output interrupt */ 151859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (status & (DAHFI | DAEMI)) { 151959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez handle_ao_interrupt(dev, status); 152059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1521cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check for analog input interrupts */ 1522cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* if fifo half-full */ 152359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (status & ADHFI) { 1524cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* read data */ 152559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_samples = half_fifo; 152659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (async->cmd.stop_src == TRIG_COUNT && 152759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_samples > devpriv->count) { 152859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_samples = devpriv->count; 152959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 153059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer, 153159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_samples); 153259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cfc_write_array_to_buffer(s, devpriv->ai_buffer, 1533790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton num_samples * sizeof(short)); 153459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->count -= num_samples; 153559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) { 153659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_EOA; 153759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_cancel(dev, s); 153859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1539cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear half-full interrupt latch */ 15405f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 154159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | INT, 154259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status + INT_ADCFIFO); 15435f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 1544cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* else if fifo not empty */ 154559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else if (status & (ADNEI | EOBI)) { 154659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < timeout; i++) { 1547cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* break if fifo is empty */ 154859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if ((ADNE & inw(devpriv->control_status + 154959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez INT_ADCFIFO)) == 0) 155059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 155159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cfc_write_to_buffer(s, inw(devpriv->adc_fifo)); 155259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (async->cmd.stop_src == TRIG_COUNT && --devpriv->count == 0) { /* end of acquisition */ 155359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_cancel(dev, s); 155459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_EOA; 155559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 155659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 155759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1558cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear not-empty interrupt latch */ 15595f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 156059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | INT, 156159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status + INT_ADCFIFO); 15625f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 156359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else if (status & EOAI) { 156459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, 156559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez "bug! encountered end of aquisition interrupt?"); 1566cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear EOA interrupt latch */ 15675f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 156859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | EOAI, 156959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status + INT_ADCFIFO); 15705f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 157159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1572cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check for fifo overflow */ 157359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (status & LADFUL) { 157459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "fifo overflow"); 1575cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear overflow interrupt latch */ 15765f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 157759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | LADFUL, 157859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status + INT_ADCFIFO); 15795f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 158059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_cancel(dev, s); 158159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 158259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 158359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 158459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_event(dev, s); 158559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 158659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return IRQ_HANDLED; 158759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 158859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1589da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void handle_ao_interrupt(struct comedi_device *dev, unsigned int status) 159059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 159134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s = dev->write_subdev; 1592d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1593ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &async->cmd; 159459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int half_fifo = thisboard->fifo_size / 2; 159559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int num_points; 159659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int flags; 159759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 159859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events = 0; 159959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 160059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (status & DAEMI) { 1601cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear dac empty interrupt latch */ 16025f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 160359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | DAEMI, 160459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status + INT_ADCFIFO); 16055f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 160659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) { 160759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_NONE || 160859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez (cmd->stop_src == TRIG_COUNT 160959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez && devpriv->ao_count)) { 161059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "dac fifo underflow"); 161159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_ao_cancel(dev, s); 161259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_ERROR; 161359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 161459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_EOA; 161559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 161659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else if (status & DAHFI) { 161759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int num_bytes; 161859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1619cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* figure out how many points we are writing to fifo */ 162059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_points = half_fifo; 162159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_COUNT && 162259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_count < num_points) 162359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_points = devpriv->ao_count; 162459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_bytes = 162559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cfc_read_array_from_buffer(s, devpriv->ao_buffer, 1626790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton num_points * sizeof(short)); 1627790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton num_points = num_bytes / sizeof(short); 162859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 162959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (async->cmd.stop_src == TRIG_COUNT) { 163059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_count -= num_points; 163159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1632cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* write data to board's fifo */ 163359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, 163459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_points); 1635cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear half-full interrupt latch */ 16365f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 163759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | DAHFI, 163859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status + INT_ADCFIFO); 16395f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 164059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 164159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 164259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_event(dev, s); 164359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 164459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1645d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton/* cancel analog input command */ 1646da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 164759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 164859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 164959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 16505f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 1651cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable interrupts */ 165259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits &= ~INTE & ~EOAIE; 165359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO); 16545f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 165559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1656cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable start trigger source and burst mode */ 165759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + TRIG_CONTSTAT); 1658cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* software pacer source */ 165959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + ADCMUX_CONT); 166059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 166159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 166259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 166359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1664d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton/* cancel analog output command */ 1665d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pembertonstatic int cb_pcidas_ao_cancel(struct comedi_device *dev, 1666d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_subdevice *s) 166759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 166859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 166959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 16705f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 1671cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable interrupts */ 167259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE; 167359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO); 167459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1675cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable output */ 167659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK; 167759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 16785f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 167959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 168059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 168159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 168259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1683da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns, 168459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int rounding_flags) 168559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 168659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), 168759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez &(devpriv->divisor2), ns, rounding_flags & TRIG_ROUND_MASK); 168859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 168959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ 169059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1, 169159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->divisor1, 2); 169259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2, 169359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->divisor2, 2); 169459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 169559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1696da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void write_calibration_bitstream(struct comedi_device *dev, 169759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int register_bits, unsigned int bitstream, 169859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bitstream_length) 169959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 170059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int write_delay = 1; 170159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bit; 170259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 170359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) { 170459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (bitstream & bit) 170559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez register_bits |= SERIAL_DATA_IN_BIT; 170659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else 170759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez register_bits &= ~SERIAL_DATA_IN_BIT; 17085f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(write_delay); 170959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(register_bits, devpriv->control_status + CALIBRATION_REG); 171059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 171159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 171259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1713da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int caldac_8800_write(struct comedi_device *dev, unsigned int address, 171459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez uint8_t value) 171559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 171659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int num_caldac_channels = 8; 171759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int bitstream_length = 11; 171859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bitstream = ((address & 0x7) << 8) | value; 17195f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman static const int caldac_8800_udelay = 1; 172059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 172159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (address >= num_caldac_channels) { 172259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "illegal caldac channel"); 172359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 172459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 172559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 172659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (value == devpriv->caldac_value[address]) 172759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 172859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 172959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->caldac_value[address] = value; 173059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 173159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream, 173259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bitstream_length); 173359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 17345f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(caldac_8800_udelay); 173559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev) | SELECT_8800_BIT, 173659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status + CALIBRATION_REG); 17375f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(caldac_8800_udelay); 173859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 173959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 174059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 174159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 174259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1743da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int trimpot_7376_write(struct comedi_device *dev, uint8_t value) 174459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 174559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int bitstream_length = 7; 174659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bitstream = value & 0x7f; 174759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int register_bits; 17485f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman static const int ad7376_udelay = 1; 174959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 175059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT; 17515f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(ad7376_udelay); 175259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(register_bits, devpriv->control_status + CALIBRATION_REG); 175359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 175459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez write_calibration_bitstream(dev, register_bits, bitstream, 175559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bitstream_length); 175659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 17575f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(ad7376_udelay); 175859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 175959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 176059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 176159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 176259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 176359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* For 1602/16 only 176459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * ch 0 : adc gain 176559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * ch 1 : adc postgain offset */ 1766da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int trimpot_8402_write(struct comedi_device *dev, unsigned int channel, 176759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez uint8_t value) 176859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 176959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int bitstream_length = 10; 177059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff); 177159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int register_bits; 17725f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman static const int ad8402_udelay = 1; 177359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 177459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT; 17755f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(ad8402_udelay); 177659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(register_bits, devpriv->control_status + CALIBRATION_REG); 177759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 177859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez write_calibration_bitstream(dev, register_bits, bitstream, 177959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bitstream_length); 178059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 17815f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(ad8402_udelay); 178259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 178359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 178459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 178559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 178659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 178759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic int wait_for_nvram_ready(unsigned long s5933_base_addr) 178859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 178959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int timeout = 1000; 179059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int i; 179159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 179259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < timeout; i++) { 179359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if ((inb(s5933_base_addr + 179459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY) 179559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez == 0) 179659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 17975f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 179859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 179959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 180059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 180159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1802da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int nvram_read(struct comedi_device *dev, unsigned int address, uint8_t *data) 180359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 180459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long iobase = devpriv->s5933_config; 180559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 180659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (wait_for_nvram_ready(iobase) < 0) 180759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ETIMEDOUT; 180859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 180959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR, 181059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez iobase + AMCC_OP_REG_MCSR_NVCMD); 181159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); 181259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR, 181359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez iobase + AMCC_OP_REG_MCSR_NVCMD); 181459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); 181559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD); 181659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 181759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (wait_for_nvram_ready(iobase) < 0) 181859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ETIMEDOUT; 181959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 182059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA); 182159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 182259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 182359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 182459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 182559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 182659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * A convenient macro that defines init_module() and cleanup_module(), 182759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * as necessary. 182859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 182959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezCOMEDI_PCI_INITCLEANUP(driver_cb_pcidas, cb_pcidas_pci_table); 1830