cb_pcidas.c revision 16f08494f4523de348988763b74e5756d482978b
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} 1590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral 16059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic inline unsigned int DAC_RANGE_MASK(unsigned int channel) 16159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 16259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0x3 << (8 + 2 * (channel & 0x1)); 16359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 16459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 165cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* bits for 1602 series only */ 16659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezenum dac_csr_bits_1602 { 167cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_EMPTY = 0x1, /* dac fifo empty, read, write clear */ 168cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_START = 0x4, /* start/arm dac fifo operations */ 169cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_PACER_MASK = 0x18, /* bits that set dac pacer source */ 170cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_PACER_INT = 0x8, /* dac internal pacing */ 171cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_PACER_EXT_FALL = 0x10, /* dac external pacing, falling edge */ 172cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton DAC_PACER_EXT_RISE = 0x18, /* dac external pacing, rising edge */ 17359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 17459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic inline unsigned int DAC_CHAN_EN(unsigned int channel) 17559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 176cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton return 1 << (5 + (channel & 0x1)); /* enable channel 0 or 1 */ 17759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 17859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 17959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* analog input fifo */ 180cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADCDATA 0 /* ADC DATA register */ 181cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define ADCFIFOCLR 2 /* ADC FIFO CLEAR */ 18259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 183cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* pacer, counter, dio registers */ 18459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define ADC8254 0 18559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define DIO_8255 4 18659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define DAC8254 8 18759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 188cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output registers for 100x, 1200 series */ 18959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic inline unsigned int DAC_DATA_REG(unsigned int channel) 19059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 19159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 2 * (channel & 0x1); 19259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 19359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 19459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* analog output registers for 1602 series*/ 195cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DACDATA 0 /* DAC DATA register */ 196cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton#define DACFIFOCLR 2 /* DAC FIFO CLEAR */ 19759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 198cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* bit in hexadecimal representation of range index that indicates unipolar input range */ 19959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#define IS_UNIPOLAR 0x4 200cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog input ranges for most boards */ 2019ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange cb_pcidas_ranges = { 20259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 8, 20359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 2040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(10), 2050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(5), 2060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(2.5), 2070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(1.25), 2080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(10), 2090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(5), 2100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(2.5), 2110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(1.25) 2120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 21359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 21459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 215cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* pci-das1001 input ranges */ 2169ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange cb_pcidas_alt_ranges = { 21759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 8, 21859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 2190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(10), 2200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(1), 2210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(0.1), 2220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(0.01), 2230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(10), 2240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(1), 2250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(0.1), 2260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(0.01) 2270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 22859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 22959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 230cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output ranges */ 2319ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange cb_pcidas_ao_ranges = { 23259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 4, 23359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 2340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(5), 2350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(10), 2360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(5), 2370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(10), 2380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 23959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 24059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 24159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezenum trimpot_model { 24259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez AD7376, 24359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez AD8402, 24459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 24559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 2465c2670cba2a5fd1a27f938ae11b3a24518d999dbBill Pembertonstruct cb_pcidas_board { 24759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez const char *name; 24859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned short device_id; 249cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ai_se_chans; /* Inputs in single-ended mode */ 250cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ai_diff_chans; /* Inputs in differential mode */ 251cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ai_bits; /* analog input resolution */ 252cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ai_speed; /* fastest conversion period in ns */ 253cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ao_nchan; /* number of analog out channels */ 254cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int has_ao_fifo; /* analog output has fifo */ 255cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ao_scan_speed; /* analog output speed for 1602 series (for a scan, not conversion) */ 256cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int fifo_size; /* number of samples fifo can hold */ 2579ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pemberton const struct comedi_lrange *ranges; 25859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez enum trimpot_model trimpot; 25959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned has_dac08:1; 2605c2670cba2a5fd1a27f938ae11b3a24518d999dbBill Pemberton}; 26159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 2625c2670cba2a5fd1a27f938ae11b3a24518d999dbBill Pembertonstatic const struct cb_pcidas_board cb_pcidas_boards[] = { 26359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 2640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1602/16", 2650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x1, 2660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 2670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 2680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 16, 2690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 5000, 2700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 2, 2710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 1, 2720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_scan_speed = 10000, 2730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 512, 2740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 2750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD8402, 2760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 1, 2770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 27859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 2790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1200", 2800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0xF, 2810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 2820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 2830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 12, 2840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3200, 2850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 2, 2860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 0, 2870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 1024, 2880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 2890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD7376, 2900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 0, 2910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 29259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 2930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1602/12", 2940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x10, 2950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 2960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 2970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 12, 2980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3200, 2990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 2, 3000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 1, 3010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_scan_speed = 4000, 3020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 1024, 3030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 3040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD7376, 3050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 0, 3060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 30759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 3080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1200/jr", 3090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x19, 3100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 3110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 3120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 12, 3130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3200, 3140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 0, 3150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 0, 3160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 1024, 3170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 3180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD7376, 3190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 0, 3200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 32159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 3220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1602/16/jr", 3230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x1C, 3240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 3250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 3260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 16, 3270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 5000, 3280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 0, 3290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 0, 3300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 512, 3310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 3320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD8402, 3330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 1, 3340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 33559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 3360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1000", 3370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x4C, 3380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 3390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 3400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 12, 3410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 4000, 3420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 0, 3430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 0, 3440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 1024, 3450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 3460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD7376, 3470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 0, 3480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 34959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 3500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1001", 3510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x1a, 3520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 3530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 3540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 12, 3550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 6800, 3560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 2, 3570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 0, 3580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 1024, 3590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_alt_ranges, 3600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD7376, 3610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 0, 3620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 36359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez { 3640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-das1002", 3650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x1b, 3660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_se_chans = 16, 3670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_diff_chans = 8, 3680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_bits = 12, 3690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 6800, 3700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_nchan = 2, 3710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_ao_fifo = 0, 3720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fifo_size = 1024, 3730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidas_ranges, 3740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .trimpot = AD7376, 3750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .has_dac08 = 0, 3760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 37759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 37859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 37959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = { 38016f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) }, 38116f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) }, 38216f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) }, 38316f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) }, 38416f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) }, 38516f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) }, 38616f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) }, 38716f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) }, 38816f08494f4523de348988763b74e5756d482978bJavier Martinez Canillas { 0 } 38959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 39059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 39159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan MartinezMODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table); 39259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 39359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 39459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Useful for shorthand access to the particular board structure 39559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 3965c2670cba2a5fd1a27f938ae11b3a24518d999dbBill Pemberton#define thisboard ((const struct cb_pcidas_board *)dev->board_ptr) 39759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 39859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* this structure is for data unique to this hardware driver. If 39959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez several hardware drivers keep similar information in this structure, 40071b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton feel free to suggest moving the variable to the struct comedi_device struct. */ 401c77e25898523395b56e1d120195e1ad2e3efa14dBill Pembertonstruct cb_pcidas_private { 40259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* would be useful for a PCI device */ 40359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez struct pci_dev *pci_dev; 404cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* base addresses */ 40559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long s5933_config; 40659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long control_status; 40759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long adc_fifo; 40859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long pacer_counter_dio; 40959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long ao_registers; 410cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* divisors of master clock for analog input pacing */ 41159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int divisor1; 41259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int divisor2; 413cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int count; /* number of analog input samples remaining */ 414cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int adc_fifo_bits; /* bits to write to interupt/adcfifo register */ 415cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int s5933_intcsr_bits; /* bits to write to amcc s5933 interrupt control/status register */ 416cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int ao_control_bits; /* bits to write to ao control and status register */ 417790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short ai_buffer[AI_BUFFER_SIZE]; 418790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short ao_buffer[AO_BUFFER_SIZE]; 419cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* divisors of master clock for analog output pacing */ 42059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int ao_divisor1; 42159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int ao_divisor2; 422cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton volatile unsigned int ao_count; /* number of analog output samples remaining */ 423cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton int ao_value[2]; /* remember what the analog outputs are set to, to allow readback */ 424cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton unsigned int caldac_value[NUM_CHANNELS_8800]; /* for readback of caldac */ 425cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton unsigned int trimpot_value[NUM_CHANNELS_8402]; /* for readback of trimpot */ 42659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int dac08_value; 42759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int calibration_source; 428c77e25898523395b56e1d120195e1ad2e3efa14dBill Pemberton}; 42959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 43059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 43159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * most drivers define the following macro to make it easy to 43259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * access the private structure. 43359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 434c77e25898523395b56e1d120195e1ad2e3efa14dBill Pemberton#define devpriv ((struct cb_pcidas_private *)dev->private) 43559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 43659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 437139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pemberton * The struct comedi_driver structure tells the Comedi core module 43859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * which functions to call to configure/deconfigure (attach/detach) 43959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * the board, and also about the kernel module that contains 44059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * the device code. 44159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 4420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_attach(struct comedi_device *dev, 4430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 444da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_detach(struct comedi_device *dev); 445139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_cb_pcidas = { 44668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "cb_pcidas", 44768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 44868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = cb_pcidas_attach, 44968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = cb_pcidas_detach, 45059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez}; 45159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 4520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ai_rinsn(struct comedi_device *dev, 4530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 455814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, 4560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 4570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev, 4580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 4600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 4610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev, 4620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 4640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 4650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_readback_insn(struct comedi_device *dev, 4660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 4680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 4690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ai_cmd(struct comedi_device *dev, 4700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 4710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ai_cmdtest(struct comedi_device *dev, 4720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd); 4740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_cmd(struct comedi_device *dev, 4750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 476d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pembertonstatic int cb_pcidas_ao_inttrig(struct comedi_device *dev, 477d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_subdevice *subdev, 478d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton unsigned int trig_num); 4790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_cmdtest(struct comedi_device *dev, 4800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd); 48270265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t cb_pcidas_interrupt(int irq, void *d); 483814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void handle_ao_interrupt(struct comedi_device *dev, unsigned int status); 4840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_cancel(struct comedi_device *dev, 4850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 4860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_cancel(struct comedi_device *dev, 4870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 488814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns, 4890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral int round_flags); 4900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int eeprom_read_insn(struct comedi_device *dev, 4910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 4930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int caldac_read_insn(struct comedi_device *dev, 4940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 4960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int caldac_write_insn(struct comedi_device *dev, 4970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 4990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int trimpot_read_insn(struct comedi_device *dev, 5000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 5020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_trimpot_write(struct comedi_device *dev, 5030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int channel, unsigned int value); 5040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int trimpot_write_insn(struct comedi_device *dev, 5050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 5070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dac08_read_insn(struct comedi_device *dev, 5080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_insn *insn, 5090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 510814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int dac08_write(struct comedi_device *dev, unsigned int value); 5110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dac08_write_insn(struct comedi_device *dev, 5120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 514814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int caldac_8800_write(struct comedi_device *dev, unsigned int address, 5150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral uint8_t value); 516814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int trimpot_7376_write(struct comedi_device *dev, uint8_t value); 517814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int trimpot_8402_write(struct comedi_device *dev, unsigned int channel, 5180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral uint8_t value); 519814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int nvram_read(struct comedi_device *dev, unsigned int address, 5202d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini uint8_t *data); 52159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 522814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic inline unsigned int cal_enable_bits(struct comedi_device *dev) 52359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 52459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source); 52559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 52659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 52759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 52859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Attach is called by the Comedi core to configure the driver 52959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * for a particular board. 53059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 5310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_attach(struct comedi_device *dev, 5320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it) 53359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 53434c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 53520fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy struct pci_dev *pcidev = NULL; 53659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int index; 53759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int i; 53859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 53959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk("comedi%d: cb_pcidas: ", dev->minor); 54059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 54159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 54259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Allocate the private structure area. 54359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 544c77e25898523395b56e1d120195e1ad2e3efa14dBill Pemberton if (alloc_private(dev, sizeof(struct cb_pcidas_private)) < 0) 54559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ENOMEM; 54659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 54759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 54859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Probe the device to determine what device in the series it is. 54959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 55059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk("\n"); 55159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 55220fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy for_each_pci_dev(pcidev) { 553cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* is it not a computer boards card? */ 55459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (pcidev->vendor != PCI_VENDOR_ID_CB) 55559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez continue; 556cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* loop through cards supported by this driver */ 5578629efa4cbf6f89a54a85af4b8bc31762af01800Bill Pemberton for (index = 0; index < ARRAY_SIZE(cb_pcidas_boards); index++) { 55859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cb_pcidas_boards[index].device_id != pcidev->device) 55959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez continue; 560cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* was a particular bus/slot requested? */ 56159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (it->options[0] || it->options[1]) { 562cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* are we on the wrong bus/slot? */ 56359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (pcidev->bus->number != it->options[0] || 5640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pcidev->devfn) != it->options[1]) { 56559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez continue; 56659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 56759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 56859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->pci_dev = pcidev; 56959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->board_ptr = cb_pcidas_boards + index; 57059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez goto found; 57159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 57259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 57359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 57459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk("No supported ComputerBoards/MeasurementComputing card found on " 5750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "requested position\n"); 57659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EIO; 57759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 5780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralfound: 57959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 58059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk("Found %s on bus %i, slot %i\n", cb_pcidas_boards[index].name, 5810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pcidev->bus->number, PCI_SLOT(pcidev->devfn)); 58259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 58359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* 58459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Enable PCI device and reserve I/O ports. 58559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 58659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (comedi_pci_enable(pcidev, "cb_pcidas")) { 58759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk(" Failed to enable PCI device and request regions\n"); 58859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EIO; 58959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 59059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* 59159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Initialize devpriv->control_status and devpriv->adc_fifo to point to 59259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * their base address. 59359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 59459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->s5933_config = 5950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX); 59659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->control_status = 5970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX); 59859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo = 5990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX); 60059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->pacer_counter_dio = 6010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX); 60259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->ao_nchan) { 60359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_registers = 6040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_resource_start(devpriv->pci_dev, AO_BADRINDEX); 60559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 606cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable and clear interrupts on amcc s5933 */ 60759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outl(INTCSR_INBOX_INTR_STATUS, 6080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->s5933_config + AMCC_OP_REG_INTCSR); 60959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 610cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* get irq */ 6115f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman if (request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt, 61259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez IRQF_SHARED, "cb_pcidas", dev)) { 61359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk(" unable to allocate irq %d\n", devpriv->pci_dev->irq); 61459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 61559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 61659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->irq = devpriv->pci_dev->irq; 61759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 618cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* Initialize dev->board_name */ 61959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->board_name = thisboard->name; 62059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 62159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 62259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Allocate the subdevice structures. 62359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 62459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (alloc_subdevices(dev, 7) < 0) 62559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ENOMEM; 62659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 62759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 0; 62859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* analog input subdevice */ 62959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->read_subdev = s; 63059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_AI; 63159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; 63259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* WARNING: Number of inputs in differential mode is ignored */ 63359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = thisboard->ai_se_chans; 63459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->len_chanlist = thisboard->ai_se_chans; 63559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = (1 << thisboard->ai_bits) - 1; 63659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->range_table = thisboard->ranges; 63759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = cb_pcidas_ai_rinsn; 63859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_config = ai_config_insn; 63959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->do_cmd = cb_pcidas_ai_cmd; 64059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->do_cmdtest = cb_pcidas_ai_cmdtest; 64159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->cancel = cb_pcidas_cancel; 64259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 64359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* analog output subdevice */ 64459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 1; 64559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->ao_nchan) { 64659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_AO; 64759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; 64859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = thisboard->ao_nchan; 649cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* analog out resolution is the same as analog input resolution, so use ai_bits */ 65059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = (1 << thisboard->ai_bits) - 1; 65159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->range_table = &cb_pcidas_ao_ranges; 65259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = cb_pcidas_ao_readback_insn; 65359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->has_ao_fifo) { 65459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dev->write_subdev = s; 65559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags |= SDF_CMD_WRITE; 65659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = cb_pcidas_ao_fifo_winsn; 65759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->do_cmdtest = cb_pcidas_ao_cmdtest; 65859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->do_cmd = cb_pcidas_ao_cmd; 65959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->cancel = cb_pcidas_ao_cancel; 66059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 66159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = cb_pcidas_ao_nofifo_winsn; 66259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 66359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 66459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_UNUSED; 66559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 66659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 66759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* 8255 */ 66859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 2; 66959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez subdev_8255_init(dev, s, NULL, devpriv->pacer_counter_dio + DIO_8255); 67059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 671cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* serial EEPROM, */ 67259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 3; 67359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_MEMORY; 67459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_INTERNAL; 67559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = 256; 67659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0xff; 67759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = eeprom_read_insn; 67859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 679cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* 8800 caldac */ 68059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 4; 68159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_CALIB; 68259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 68359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = NUM_CHANNELS_8800; 68459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0xff; 68559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = caldac_read_insn; 68659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = caldac_write_insn; 68759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < s->n_chan; i++) 68859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez caldac_8800_write(dev, i, s->maxdata / 2); 68959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 690cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* trim potentiometer */ 69159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 5; 69259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_CALIB; 69359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 69459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->trimpot == AD7376) { 69559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = NUM_CHANNELS_7376; 69659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0x7f; 69759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 69859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = NUM_CHANNELS_8402; 69959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0xff; 70059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 70159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = trimpot_read_insn; 70259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = trimpot_write_insn; 70359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < s->n_chan; i++) 70459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_trimpot_write(dev, i, s->maxdata / 2); 70559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 706cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* dac08 caldac */ 70759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s = dev->subdevices + 6; 70859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (thisboard->has_dac08) { 70959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_CALIB; 71059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 71159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->n_chan = NUM_CHANNELS_DAC08; 71259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_read = dac08_read_insn; 71359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->insn_write = dac08_write_insn; 71459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->maxdata = 0xff; 71559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez dac08_write(dev, s->maxdata / 2); 71659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else 71759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s->type = COMEDI_SUBD_UNUSED; 71859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 719cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* make sure mailbox 4 is empty */ 72059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez inl(devpriv->s5933_config + AMCC_OP_REG_IMB4); 72159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* Set bits to enable incoming mailbox interrupts on amcc s5933. */ 72259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->s5933_intcsr_bits = 7230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) | 7240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral INTCSR_INBOX_FULL_INT; 725cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear and enable interrupt on amcc s5933 */ 72659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS, 7270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->s5933_config + AMCC_OP_REG_INTCSR); 72859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 72959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 73059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 73159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 73259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 73359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * cb_pcidas_detach is called to deconfigure a device. It should deallocate 73459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * resources. 73559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * This function is also called when _attach() fails, so it should be 73659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * careful not to release resources that were not necessarily 73759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * allocated by _attach(). dev->private and dev->subdevices are 73859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * deallocated automatically by the core. 73959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 740da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_detach(struct comedi_device *dev) 74159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 74259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk("comedi%d: cb_pcidas: remove\n", dev->minor); 74359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 74459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv) { 74559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv->s5933_config) { 746cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable and clear interrupts on amcc s5933 */ 74759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outl(INTCSR_INBOX_INTR_STATUS, 7480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->s5933_config + AMCC_OP_REG_INTCSR); 74959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 7505f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("detaching, incsr is 0x%x\n", 7510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR)); 75259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 75359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 75459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 75559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (dev->irq) 7565f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 75759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (dev->subdevices) 75859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez subdev_8255_cleanup(dev, dev->subdevices + 2); 75959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv && devpriv->pci_dev) { 7602d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (devpriv->s5933_config) 76159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_pci_disable(devpriv->pci_dev); 76259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez pci_dev_put(devpriv->pci_dev); 76359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 76459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 76559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 76659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 76759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 76859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 76959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * "instructions" read/write data in "one-shot" or "software-triggered" 77059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * mode. 77159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 7720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ai_rinsn(struct comedi_device *dev, 7730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 7740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 77559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 77659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int n, i; 77759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bits; 77859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int timeout = 10000; 77959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int channel; 780cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable calibration input if appropriate */ 78159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (insn->chanspec & CR_ALT_SOURCE) { 78259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev), 7830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + CALIBRATION_REG); 78459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez channel = 0; 78559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 78659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + CALIBRATION_REG); 78759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez channel = CR_CHAN(insn->chanspec); 78859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 789cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set mux limits and gain */ 79059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits = BEGIN_SCAN(channel) | 7910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral END_SCAN(channel) | GAIN_BITS(CR_RANGE(insn->chanspec)); 792cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set unipolar/bipolar */ 79359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_RANGE(insn->chanspec) & IS_UNIPOLAR) 79459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= UNIP; 795cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set singleended/differential */ 79659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_AREF(insn->chanspec) != AREF_DIFF) 79759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= SE; 79859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(bits, devpriv->control_status + ADCMUX_CONT); 79959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 80059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* clear fifo */ 80159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->adc_fifo + ADCFIFOCLR); 80259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 80359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* convert n samples */ 80459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (n = 0; n < insn->n; n++) { 80559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* trigger conversion */ 80659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->adc_fifo + ADCDATA); 80759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 80859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* wait for conversion to end */ 80959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* return -ETIMEDOUT if there is a timeout */ 81059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < timeout; i++) { 81159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (inw(devpriv->control_status + ADCMUX_CONT) & EOC) 81259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 81359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 81459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (i == timeout) 81559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ETIMEDOUT; 81659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 81759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* read data */ 81859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[n] = inw(devpriv->adc_fifo + ADCDATA); 81959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 82059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 82159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* return the number of samples read/written */ 82259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return n; 82359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 82459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 8250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ai_config_calibration_source(struct comedi_device *dev, 8260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 82759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 82859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int num_calibration_sources = 8; 829790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int source = data[1]; 83059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 83159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (source >= num_calibration_sources) { 83259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez printk("invalid calibration source: %i\n", source); 83359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 83459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 83559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 83659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->calibration_source = source; 83759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 83859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 2; 83959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 84059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 841da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, 8420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 84359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 84459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int id = data[0]; 84559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 84659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez switch (id) { 84759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case INSN_CONFIG_ALT_SOURCE: 84859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return ai_config_calibration_source(dev, data); 84959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 85059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez default: 85159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 85259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 85359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 85459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 85559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 85659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 857cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output insn for pcidas-1000 and 1200 series */ 8580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev, 8590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 8600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 8610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 86259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 86359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int channel; 86459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 86559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 866cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set channel and range */ 86759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez channel = CR_CHAN(insn->chanspec); 8685f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 86959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits &= 8700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel); 87159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= 8720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec)); 87359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 8745f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 87559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 876cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* remember value for readback */ 87759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_value[channel] = data[0]; 878cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* send data */ 87959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(data[0], devpriv->ao_registers + DAC_DATA_REG(channel)); 88059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 88159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 88259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 88359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 884cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output insn for pcidas-1602 series */ 8850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev, 8860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 8870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 88859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 88959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int channel; 89059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 89159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 892cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear dac fifo */ 89359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->ao_registers + DACFIFOCLR); 89459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 895cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set channel and range */ 89659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez channel = CR_CHAN(insn->chanspec); 8975f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 89859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits &= 8990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) & ~DAC_RANGE_MASK(channel) & 9000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ~DAC_PACER_MASK; 90159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= 9020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral DACEN | DAC_RANGE(channel, 9030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_RANGE(insn-> 9040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral chanspec)) | DAC_CHAN_EN(channel) | 9050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral DAC_START; 90659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 9075f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 90859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 909cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* remember value for readback */ 91059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_value[channel] = data[0]; 911cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* send data */ 91259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(data[0], devpriv->ao_registers + DACDATA); 91359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 91459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 91559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 91659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 917cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* analog output readback insn */ 918cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton/* XXX loses track of analog output value back after an analog ouput command is executed */ 9190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_readback_insn(struct comedi_device *dev, 9200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 9210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 9220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 92359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 92459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)]; 92559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 92659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 92759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 92859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 9290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int eeprom_read_insn(struct comedi_device *dev, 9300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 9310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 93259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 93359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez uint8_t nvram_data; 93459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int retval; 93559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 93659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data); 93759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (retval < 0) 93859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return retval; 93959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 94059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = nvram_data; 94159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 94259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 94359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 94459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 9450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int caldac_write_insn(struct comedi_device *dev, 9460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 9470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 94859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 94959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez const unsigned int channel = CR_CHAN(insn->chanspec); 95059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 95159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return caldac_8800_write(dev, channel, data[0]); 95259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 95359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 9540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int caldac_read_insn(struct comedi_device *dev, 9550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 9560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 95759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 95859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)]; 95959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 96059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 96159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 96259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 96359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 1602/16 pregain offset */ 964da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dac08_write(struct comedi_device *dev, unsigned int value) 96559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 96659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv->dac08_value == value) 96759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 96859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 96959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->dac08_value = value; 97059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 97159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev) | (value & 0xff), 9720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + CALIBRATION_REG); 9735f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 97459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev) | SELECT_DAC08_BIT | (value & 0xff), 9750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + CALIBRATION_REG); 9765f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 97759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev) | (value & 0xff), 9780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + CALIBRATION_REG); 9795f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 98059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 98159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 98259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 98359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 9840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dac08_write_insn(struct comedi_device *dev, 9850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 9860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 98759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 98859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return dac08_write(dev, data[0]); 98959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 99059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 9910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dac08_read_insn(struct comedi_device *dev, 9920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_insn *insn, 9930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 99459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 99559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = devpriv->dac08_value; 99659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 99759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 99859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 99959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1000da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidas_trimpot_write(struct comedi_device *dev, 10010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int channel, unsigned int value) 100259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 100359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (devpriv->trimpot_value[channel] == value) 100459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 100559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 100659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->trimpot_value[channel] = value; 100759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez switch (thisboard->trimpot) { 100859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case AD7376: 100959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez trimpot_7376_write(dev, value); 101059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 101159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case AD8402: 101259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez trimpot_8402_write(dev, channel, value); 101359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 101459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez default: 101559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "driver bug?"); 101659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 101759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 101859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 101959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 102059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 102159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 102259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 10230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int trimpot_write_insn(struct comedi_device *dev, 10240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 10250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 102659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 102759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int channel = CR_CHAN(insn->chanspec); 102859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 102959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return cb_pcidas_trimpot_write(dev, channel, data[0]); 103059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 103159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 10320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int trimpot_read_insn(struct comedi_device *dev, 10330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 10340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 103559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 103659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int channel = CR_CHAN(insn->chanspec); 103759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 103859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez data[0] = devpriv->trimpot_value[channel]; 103959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 104059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 104159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 104259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 10430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ai_cmdtest(struct comedi_device *dev, 10440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 10450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd) 104659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 104759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int err = 0; 104859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int tmp; 104959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int i, gain, start_chan; 105059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 105159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* cmdtest tests a particular command to see if it is valid. 105259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Using the cmdtest ioctl, a user can create a valid cmd 105359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * and then have it executes by the cmd ioctl. 105459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * 105559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * cmdtest returns 1,2,3,4 or 0, depending on which tests 105659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * the command passes. */ 105759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 105859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 1: make sure trigger sources are trivially valid */ 105959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 106059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->start_src; 106159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->start_src &= TRIG_NOW | TRIG_EXT; 106259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->start_src || tmp != cmd->start_src) 106359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 106459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 106559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_begin_src; 106659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; 106759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 106859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 106959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 107059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->convert_src; 107159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT; 107259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->convert_src || tmp != cmd->convert_src) 107359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 107459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 107559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_end_src; 107659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_end_src &= TRIG_COUNT; 107759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 107859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 107959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 108059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->stop_src; 108159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 108259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->stop_src || tmp != cmd->stop_src) 108359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 108459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 108559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 108659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 108759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 108859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 2: make sure trigger sources are unique and mutually compatible */ 108959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 109059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) 109159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 109259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src != TRIG_FOLLOW && 10930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_src != TRIG_TIMER && 10940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_src != TRIG_EXT) 109559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 109659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src != TRIG_TIMER && 10970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) 109859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 109959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 110059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 110159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1102cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* make sure trigger sources are compatible with each other */ 110359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW) 110459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 110559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW) 110659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 110759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_src == TRIG_EXT && 11080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)) 110959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 111059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 111159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 111259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 2; 111359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 111459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 3: make sure arguments are trivially compatible */ 111559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 111659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_arg != 0) { 111759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->start_arg = 0; 111859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 111959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 112059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 112159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 112259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_arg < 11230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral thisboard->ai_speed * cmd->chanlist_len) { 112459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_arg = 11250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral thisboard->ai_speed * cmd->chanlist_len; 112659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 112759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 112859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 112959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_TIMER) { 113059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_arg < thisboard->ai_speed) { 113159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->convert_arg = thisboard->ai_speed; 113259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 113359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 113459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 113559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 113659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_end_arg != cmd->chanlist_len) { 113759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_end_arg = cmd->chanlist_len; 113859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 113959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 114059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_NONE) { 114159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* TRIG_NONE */ 114259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_arg != 0) { 114359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->stop_arg = 0; 114459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 114559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 114659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 114759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 114859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 114959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 3; 115059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 115159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 4: fix up any arguments */ 115259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 115359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 115459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_begin_arg; 115559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, 11560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor1), 11570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor2), 11580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd->scan_begin_arg), 11590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 116059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (tmp != cmd->scan_begin_arg) 116159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 116259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 116359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_TIMER) { 116459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->convert_arg; 116559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, 11660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor1), 11670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor2), 11680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd->convert_arg), 11690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 117059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (tmp != cmd->convert_arg) 117159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 117259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 117359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 117459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 117559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 4; 117659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1177cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check channel/gain list against card's limitations */ 117859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->chanlist) { 117959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez gain = CR_RANGE(cmd->chanlist[0]); 118059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez start_chan = CR_CHAN(cmd->chanlist[0]); 118159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 1; i < cmd->chanlist_len; i++) { 118259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_CHAN(cmd->chanlist[i]) != 11830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (start_chan + i) % s->n_chan) { 118459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, 11850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must be consecutive channels, counting upwards\n"); 118659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 118759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 118859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_RANGE(cmd->chanlist[i]) != gain) { 118959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, 11900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must all have the same gain\n"); 119159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 119259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 119359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 119459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 119559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 119659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 119759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 5; 119859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 119959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 120059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 120159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 12020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ai_cmd(struct comedi_device *dev, 12030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 120459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 1205d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1206ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &async->cmd; 120759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bits; 120859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 120959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1210cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* make sure CAL_EN_BIT is disabled */ 121159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + CALIBRATION_REG); 1212cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* initialize before settings pacer source and count values */ 121359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + TRIG_CONTSTAT); 1214cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear fifo */ 121559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->adc_fifo + ADCFIFOCLR); 121659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1217cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set mux limits, gain and pacer source */ 121859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) | 12190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) | 12200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral GAIN_BITS(CR_RANGE(cmd->chanlist[0])); 1221cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set unipolar/bipolar */ 122259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR) 122359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= UNIP; 1224cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set singleended/differential */ 122559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF) 122659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= SE; 1227cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set pacer source */ 122859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT) 122959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= PACER_EXT_RISE; 123059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else 123159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= PACER_INT; 123259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(bits, devpriv->control_status + ADCMUX_CONT); 123359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 123459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 12355f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("comedi: sent 0x%x to adcmux control\n", bits); 123659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 123759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1238cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* load counters */ 123959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_TIMER) 124059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_load_counters(dev, &cmd->convert_arg, 12410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 124259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else if (cmd->scan_begin_src == TRIG_TIMER) 124359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_load_counters(dev, &cmd->scan_begin_arg, 12440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 124559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1246cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set number of conversions */ 12472d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (cmd->stop_src == TRIG_COUNT) 124859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->count = cmd->chanlist_len * cmd->stop_arg; 1249cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable interrupts */ 12505f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 125159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits |= INTE; 125259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits &= ~INT_MASK; 125359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->flags & TRIG_WAKE_EOS) { 125459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) 1255cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton devpriv->adc_fifo_bits |= INT_EOS; /* interrupt end of burst */ 125659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else 1257cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton devpriv->adc_fifo_bits |= INT_FNE; /* interrupt fifo not empty */ 125859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else { 1259cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton devpriv->adc_fifo_bits |= INT_FHF; /* interrupt fifo half full */ 126059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 126159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 12625f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits); 126359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 1264cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable (and clear) interrupts */ 126559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL, 12660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 12675f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 126859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1269cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set start trigger and burst mode */ 127059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits = 0; 127159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_src == TRIG_NOW) 127259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= SW_TRIGGER; 127359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else if (cmd->start_src == TRIG_EXT) 127459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= EXT_TRIGGER | TGEN | XTRCL; 127559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else { 127659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "bug!"); 127759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 127859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 127959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) 128059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez bits |= BURSTE; 128159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(bits, devpriv->control_status + TRIG_CONTSTAT); 128259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 12835f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("comedi: sent 0x%x to trig control\n", bits); 128459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 128559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 128659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 128759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 128859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 12890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_cmdtest(struct comedi_device *dev, 12900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 12910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd) 129259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 129359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int err = 0; 129459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int tmp; 129559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 129659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* cmdtest tests a particular command to see if it is valid. 129759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * Using the cmdtest ioctl, a user can create a valid cmd 129859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * and then have it executes by the cmd ioctl. 129959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * 130059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * cmdtest returns 1,2,3,4 or 0, depending on which tests 130159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * the command passes. */ 130259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 130359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 1: make sure trigger sources are trivially valid */ 130459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 130559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->start_src; 130659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->start_src &= TRIG_INT; 130759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->start_src || tmp != cmd->start_src) 130859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 130959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 131059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_begin_src; 131159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; 131259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 131359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 131459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 131559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->convert_src; 131659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->convert_src &= TRIG_NOW; 131759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->convert_src || tmp != cmd->convert_src) 131859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 131959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 132059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_end_src; 132159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_end_src &= TRIG_COUNT; 132259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 132359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 132459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 132559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->stop_src; 132659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 132759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (!cmd->stop_src || tmp != cmd->stop_src) 132859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 132959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 133059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 133159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 133259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 133359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 2: make sure trigger sources are unique and mutually compatible */ 133459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 133559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src != TRIG_TIMER && 13360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_src != TRIG_EXT) 133759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 133859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 133959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 134059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 134159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 134259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 2; 134359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 134459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 3: make sure arguments are trivially compatible */ 134559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 134659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->start_arg != 0) { 134759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->start_arg = 0; 134859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 134959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 135059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 135159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 135259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_arg < thisboard->ao_scan_speed) { 135359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_begin_arg = thisboard->ao_scan_speed; 135459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 135559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 135659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 135759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 135859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_end_arg != cmd->chanlist_len) { 135959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->scan_end_arg = cmd->chanlist_len; 136059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 136159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 136259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_NONE) { 136359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* TRIG_NONE */ 136459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_arg != 0) { 136559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cmd->stop_arg = 0; 136659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 136759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 136859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 136959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 137059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 137159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 3; 137259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 137359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* step 4: fix up any arguments */ 137459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 137559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 137659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez tmp = cmd->scan_begin_arg; 137759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, 13780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->ao_divisor1), 13790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->ao_divisor2), 13800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd->scan_begin_arg), 13810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 138259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (tmp != cmd->scan_begin_arg) 138359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 138459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 138559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 138659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 138759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 4; 138859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1389cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check channel/gain list against card's limitations */ 139059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->chanlist && cmd->chanlist_len > 1) { 139159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (CR_CHAN(cmd->chanlist[0]) != 0 || 13920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_CHAN(cmd->chanlist[1]) != 1) { 139359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, 13940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "channels must be ordered channel 0, channel 1 in chanlist\n"); 139559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez err++; 139659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 139759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 139859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 139959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (err) 140059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 5; 140159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 140259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 140359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 140459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 14050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_ao_cmd(struct comedi_device *dev, 14060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 140759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 1408d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1409ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &async->cmd; 141059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int i; 141159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 141259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1413cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set channel limits, gain */ 14145f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 141559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < cmd->chanlist_len; i++) { 1416cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable channel */ 141759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= 14180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i])); 1419cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set range */ 142059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]), 14210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_RANGE(cmd-> 14220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral chanlist[i])); 142359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 142459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1425cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable analog out before settings pacer source and count values */ 142659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 14275f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 142859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1429cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear fifo */ 143059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->ao_registers + DACFIFOCLR); 143159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1432cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* load counters */ 143359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 143459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, 14350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->ao_divisor1), 14360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->ao_divisor2), 14370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd->scan_begin_arg), 14380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags); 143959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 144059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ 144159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1, 14420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->ao_divisor1, 2); 144359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2, 14440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->ao_divisor2, 2); 144559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1446cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set number of conversions */ 14472d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (cmd->stop_src == TRIG_COUNT) 144859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg; 1449cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* set pacer source */ 14505f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 145159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez switch (cmd->scan_begin_src) { 145259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case TRIG_TIMER: 145359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= DAC_PACER_INT; 145459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 145559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez case TRIG_EXT: 145659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= DAC_PACER_EXT_RISE; 145759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 145859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez default: 14595f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 146059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "error setting dac pacer source"); 146159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 146259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 146359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 14645f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 146559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 146659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->inttrig = cb_pcidas_ao_inttrig; 146759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 146859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 146959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 147059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1471d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pembertonstatic int cb_pcidas_ao_inttrig(struct comedi_device *dev, 1472d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_subdevice *s, 1473d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton unsigned int trig_num) 147459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 147559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int num_bytes, num_points = thisboard->fifo_size; 1476d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1477ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 147859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 147959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 148059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (trig_num != 0) 148159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -EINVAL; 148259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1483cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* load up fifo */ 148459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points) 148559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_points = devpriv->ao_count; 148659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 148759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer, 14880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_points * sizeof(short)); 1489790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton num_points = num_bytes / sizeof(short); 149059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 14912d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (cmd->stop_src == TRIG_COUNT) 149259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_count -= num_points; 1493cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* write data to board's fifo */ 149459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes); 149559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1496cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable dac half-full and empty interrupts */ 14975f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 149859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits |= DAEMIE | DAHFIE; 149959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 15005f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits); 150159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 1502cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* enable and clear interrupts */ 150359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | DAEMI | DAHFI, 15040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 150559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1506cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* start dac */ 150759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY; 150859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 150959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 15100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk("comedi: sent 0x%x to dac control\n", devpriv->ao_control_bits); 151159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 15125f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 151359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 151459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->inttrig = NULL; 151559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 151659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 151759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 151859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 151970265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t cb_pcidas_interrupt(int irq, void *d) 152059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 15210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_device *dev = (struct comedi_device *)d; 152234c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s = dev->read_subdev; 1523d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async; 152459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int status, s5933_status; 152559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez int half_fifo = thisboard->fifo_size / 2; 152659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int num_samples, i; 152759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int timeout = 10000; 152859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 152959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 15302d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (dev->attached == 0) 153159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return IRQ_NONE; 153259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 153359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async = s->async; 153459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events = 0; 153559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 153659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR); 153759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 15385f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("intcsr 0x%x\n", s5933_status); 15395f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman printk("mbef 0x%x\n", inl(devpriv->s5933_config + AMCC_OP_REG_MBEF)); 154059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 154159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 154259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if ((INTCSR_INTR_ASSERTED & s5933_status) == 0) 154359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return IRQ_NONE; 154459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1545cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* make sure mailbox 4 is empty */ 154659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4); 1547cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear interrupt on amcc s5933 */ 154859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS, 15490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->s5933_config + AMCC_OP_REG_INTCSR); 155059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 155159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez status = inw(devpriv->control_status + INT_ADCFIFO); 155259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#ifdef CB_PCIDAS_DEBUG 15532d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) 155459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "spurious interrupt"); 155559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez#endif 155659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1557cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check for analog output interrupt */ 15582d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (status & (DAHFI | DAEMI)) 155959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez handle_ao_interrupt(dev, status); 1560cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check for analog input interrupts */ 1561cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* if fifo half-full */ 156259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (status & ADHFI) { 1563cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* read data */ 156459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_samples = half_fifo; 156559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (async->cmd.stop_src == TRIG_COUNT && 15660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples > devpriv->count) { 156759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_samples = devpriv->count; 156859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 156959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer, 15700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples); 157159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cfc_write_array_to_buffer(s, devpriv->ai_buffer, 15720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples * sizeof(short)); 157359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->count -= num_samples; 157459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) { 157559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_EOA; 157659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_cancel(dev, s); 157759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1578cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear half-full interrupt latch */ 15795f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 158059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | INT, 15810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 15825f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 1583cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* else if fifo not empty */ 158459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else if (status & (ADNEI | EOBI)) { 158559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < timeout; i++) { 1586cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* break if fifo is empty */ 158759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if ((ADNE & inw(devpriv->control_status + 15880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral INT_ADCFIFO)) == 0) 158959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 159059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cfc_write_to_buffer(s, inw(devpriv->adc_fifo)); 159159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (async->cmd.stop_src == TRIG_COUNT && --devpriv->count == 0) { /* end of acquisition */ 159259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_cancel(dev, s); 159359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_EOA; 159459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez break; 159559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 159659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1597cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear not-empty interrupt latch */ 15985f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 159959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | INT, 16000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 16015f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 160259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else if (status & EOAI) { 160359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, 16040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "bug! encountered end of aquisition interrupt?"); 1605cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear EOA interrupt latch */ 16065f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 160759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | EOAI, 16080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 16095f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 161059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 1611cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* check for fifo overflow */ 161259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (status & LADFUL) { 161359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "fifo overflow"); 1614cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear overflow interrupt latch */ 16155f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 161659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | LADFUL, 16170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 16185f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 161959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_cancel(dev, s); 162059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 162159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 162259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 162359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_event(dev, s); 162459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 162559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return IRQ_HANDLED; 162659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 162759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1628da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void handle_ao_interrupt(struct comedi_device *dev, unsigned int status) 162959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 163034c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s = dev->write_subdev; 1631d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1632ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &async->cmd; 163359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int half_fifo = thisboard->fifo_size / 2; 163459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int num_points; 16353a5e32ddcb04d7a2bed86323ca22da51d3a810bdGerard Lledo unsigned long flags; 163659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 163759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events = 0; 163859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 163959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (status & DAEMI) { 1640cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear dac empty interrupt latch */ 16415f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 164259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | DAEMI, 16430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 16445f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 164559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) { 164659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_NONE || 16470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->stop_src == TRIG_COUNT 16480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral && devpriv->ao_count)) { 164959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "dac fifo underflow"); 165059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez cb_pcidas_ao_cancel(dev, s); 165159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_ERROR; 165259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 165359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez async->events |= COMEDI_CB_EOA; 165459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 165559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } else if (status & DAHFI) { 165659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int num_bytes; 165759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1658cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* figure out how many points we are writing to fifo */ 165959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_points = half_fifo; 166059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (cmd->stop_src == TRIG_COUNT && 16610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->ao_count < num_points) 166259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_points = devpriv->ao_count; 166359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez num_bytes = 16640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cfc_read_array_from_buffer(s, devpriv->ao_buffer, 16650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_points * sizeof(short)); 1666790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton num_points = num_bytes / sizeof(short); 166759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 16682d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini if (async->cmd.stop_src == TRIG_COUNT) 166959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_count -= num_points; 1670cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* write data to board's fifo */ 167159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, 16720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_points); 1673cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* clear half-full interrupt latch */ 16745f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 167559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits | DAHFI, 16760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + INT_ADCFIFO); 16775f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 167859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 167959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 168059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_event(dev, s); 168159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 168259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1683d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton/* cancel analog input command */ 16840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidas_cancel(struct comedi_device *dev, 16850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 168659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 168759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 168859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 16895f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 1690cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable interrupts */ 169159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits &= ~INTE & ~EOAIE; 169259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO); 16935f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 169459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1695cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable start trigger source and burst mode */ 169659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + TRIG_CONTSTAT); 1697cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* software pacer source */ 169859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(0, devpriv->control_status + ADCMUX_CONT); 169959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 170059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 170159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 170259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1703d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton/* cancel analog output command */ 1704d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pembertonstatic int cb_pcidas_ao_cancel(struct comedi_device *dev, 1705d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_subdevice *s) 170659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 170759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long flags; 170859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 17095f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 1710cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable interrupts */ 171159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE; 171259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO); 171359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1714cf530aa4385c97f668d76c8268d509ef9edebb70Bill Pemberton /* disable output */ 171559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK; 171659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 17175f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 171859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 171959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 172059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 172159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1722da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns, 17230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral int rounding_flags) 172459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 172559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), 17260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor2), ns, 17270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral rounding_flags & TRIG_ROUND_MASK); 172859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 172959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ 173059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1, 17310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->divisor1, 2); 173259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2, 17330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->divisor2, 2); 173459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 173559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1736da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void write_calibration_bitstream(struct comedi_device *dev, 17370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int register_bits, 17380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int bitstream, 17390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int bitstream_length) 174059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 174159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int write_delay = 1; 174259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bit; 174359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 174459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) { 174559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (bitstream & bit) 174659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez register_bits |= SERIAL_DATA_IN_BIT; 174759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez else 174859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez register_bits &= ~SERIAL_DATA_IN_BIT; 17495f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(write_delay); 175059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(register_bits, devpriv->control_status + CALIBRATION_REG); 175159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 175259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 175359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1754da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int caldac_8800_write(struct comedi_device *dev, unsigned int address, 17550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral uint8_t value) 175659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 175759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int num_caldac_channels = 8; 175859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int bitstream_length = 11; 175959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bitstream = ((address & 0x7) << 8) | value; 17605f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman static const int caldac_8800_udelay = 1; 176159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 176259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (address >= num_caldac_channels) { 176359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez comedi_error(dev, "illegal caldac channel"); 176459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 176559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 176659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 176759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (value == devpriv->caldac_value[address]) 176859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 176959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 177059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez devpriv->caldac_value[address] = value; 177159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 177259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream, 17730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bitstream_length); 177459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 17755f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(caldac_8800_udelay); 177659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev) | SELECT_8800_BIT, 17770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->control_status + CALIBRATION_REG); 17785f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(caldac_8800_udelay); 177959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 178059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 178159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 1; 178259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 178359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 1784da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int trimpot_7376_write(struct comedi_device *dev, uint8_t value) 178559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 178659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int bitstream_length = 7; 178759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bitstream = value & 0x7f; 178859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int register_bits; 17895f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman static const int ad7376_udelay = 1; 179059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 179159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT; 17925f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(ad7376_udelay); 179359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(register_bits, devpriv->control_status + CALIBRATION_REG); 179459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 179559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez write_calibration_bitstream(dev, register_bits, bitstream, 17960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bitstream_length); 179759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 17985f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(ad7376_udelay); 179959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 180059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 180159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 180259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 180359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 180459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* For 1602/16 only 180559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * ch 0 : adc gain 180659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * ch 1 : adc postgain offset */ 1807da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int trimpot_8402_write(struct comedi_device *dev, unsigned int channel, 18080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral uint8_t value) 180959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 181059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int bitstream_length = 10; 181159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff); 181259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int register_bits; 18135f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman static const int ad8402_udelay = 1; 181459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 181559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT; 18165f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(ad8402_udelay); 181759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(register_bits, devpriv->control_status + CALIBRATION_REG); 181859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 181959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez write_calibration_bitstream(dev, register_bits, bitstream, 18200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bitstream_length); 182159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 18225f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(ad8402_udelay); 182359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 182459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 182559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 182659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 182759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 182859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinezstatic int wait_for_nvram_ready(unsigned long s5933_base_addr) 182959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 183059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez static const int timeout = 1000; 183159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned int i; 183259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 183359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez for (i = 0; i < timeout; i++) { 183459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if ((inb(s5933_base_addr + 18350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY) 18360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral == 0) 183759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 18385f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 183959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez } 184059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -1; 184159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 184259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 18430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int nvram_read(struct comedi_device *dev, unsigned int address, 18442d238b2972bf365153ae8d699177c7a19a5f3056Andrea Gelmini uint8_t *data) 184559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez{ 184659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez unsigned long iobase = devpriv->s5933_config; 184759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 184859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (wait_for_nvram_ready(iobase) < 0) 184959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ETIMEDOUT; 185059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 185159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR, 18520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral iobase + AMCC_OP_REG_MCSR_NVCMD); 185359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); 185459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR, 18550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral iobase + AMCC_OP_REG_MCSR_NVCMD); 185659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); 185759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD); 185859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 185959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez if (wait_for_nvram_ready(iobase) < 0) 186059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return -ETIMEDOUT; 186159c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 186259c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA); 186359c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 186459c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez return 0; 186559c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez} 186659c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez 186759c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez/* 186859c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * A convenient macro that defines init_module() and cleanup_module(), 186959c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez * as necessary. 187059c7dd3dc37dc42339406d08f1cde4d6194a4ccfIvan Martinez */ 1871727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __devinit driver_cb_pcidas_pci_probe(struct pci_dev *dev, 1872727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas const struct pci_device_id *ent) 1873727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 1874727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return comedi_pci_auto_config(dev, driver_cb_pcidas.driver_name); 1875727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 1876727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1877727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __devexit driver_cb_pcidas_pci_remove(struct pci_dev *dev) 1878727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 1879727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_pci_auto_unconfig(dev); 1880727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 1881727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1882727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic struct pci_driver driver_cb_pcidas_pci_driver = { 1883727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .id_table = cb_pcidas_pci_table, 1884727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .probe = &driver_cb_pcidas_pci_probe, 1885727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .remove = __devexit_p(&driver_cb_pcidas_pci_remove) 1886727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}; 1887727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1888727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __init driver_cb_pcidas_init_module(void) 1889727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 1890727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas int retval; 1891727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1892727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas retval = comedi_driver_register(&driver_cb_pcidas); 1893727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas if (retval < 0) 1894727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return retval; 1895727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1896727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas driver_cb_pcidas_pci_driver.name = (char *)driver_cb_pcidas.driver_name; 1897727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return pci_register_driver(&driver_cb_pcidas_pci_driver); 1898727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 1899727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1900727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __exit driver_cb_pcidas_cleanup_module(void) 1901727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 1902727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas pci_unregister_driver(&driver_cb_pcidas_pci_driver); 1903727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_driver_unregister(&driver_cb_pcidas); 1904727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 1905727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 1906727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_init(driver_cb_pcidas_init_module); 1907727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_exit(driver_cb_pcidas_cleanup_module); 190890f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 190990f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 191090f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 191190f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 1912