das1800.c revision ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3f
1a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* 2a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi/drivers/das1800.c 3a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess Driver for Keitley das1700/das1800 series boards 4a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net> 5a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 6a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess COMEDI - Linux Control and Measurement Device Interface 7a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess Copyright (C) 2000 David A. Schleef <ds@schleef.org> 8a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 9a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess This program is free software; you can redistribute it and/or modify 10a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess it under the terms of the GNU General Public License as published by 11a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess the Free Software Foundation; either version 2 of the License, or 12a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess (at your option) any later version. 13a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 14a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess This program is distributed in the hope that it will be useful, 15a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess but WITHOUT ANY WARRANTY; without even the implied warranty of 16a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess GNU General Public License for more details. 18a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 19a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess You should have received a copy of the GNU General Public License 20a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess along with this program; if not, write to the Free Software 21a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 23a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess************************************************************************ 24a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess*/ 25a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* 26a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessDriver: das1800 27a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessDescription: Keithley Metrabyte DAS1800 (& compatibles) 28a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessAuthor: Frank Mori Hess <fmhess@users.sourceforge.net> 29a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessDevices: [Keithley Metrabyte] DAS-1701ST (das-1701st), 30a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao), 31a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da), 32a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da), 33a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st), 34a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc), 35a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st), 36a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr), 37a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc), 38a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess DAS-1802AO (das-1802ao) 39a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessStatus: works 40a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 41a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessThe waveform analog output on the 'ao' cards is not supported. 42a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessIf you need it, send me (Frank Hess) an email. 43a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 44a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessConfiguration options: 45a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess [0] - I/O port base address 46a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess [1] - IRQ (optional, required for timed or externally triggered conversions) 47a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess [2] - DMA0 (optional, requires irq) 48a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess [3] - DMA1 (optional, requires irq and dma0) 49a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess*/ 50a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* 51a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 52a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessThis driver supports the following Keithley boards: 53a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 54a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1701st 55a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1701st-da 56a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1701ao 57a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1702st 58a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1702st-da 59a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1702hr 60a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1702hr-da 61a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1702ao 62a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1801st 63a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1801st-da 64a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1801hc 65a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1801ao 66a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1802st 67a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1802st-da 68a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1802hr 69a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1802hr-da 70a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1802hc 71a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessdas-1802ao 72a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 73a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessOptions: 74a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess [0] - base io address 75a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess [1] - irq (optional, required for timed or externally triggered conversions) 76a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess [2] - dma0 (optional, requires irq) 77a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess [3] - dma1 (optional, requires irq and dma0) 78a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 79a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessirq can be omitted, although the cmd interface will not work without it. 80a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 81a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessanalog input cmd triggers supported: 82a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess start_src: TRIG_NOW | TRIG_EXT 83a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess scan_begin_src: TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT 84a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess scan_end_src: TRIG_COUNT 85a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess convert_src: TRIG_TIMER | TRIG_EXT (TRIG_EXT requires scan_begin_src == TRIG_FOLLOW) 86a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess stop_src: TRIG_COUNT | TRIG_EXT | TRIG_NONE 87a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 88a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessscan_begin_src triggers TRIG_TIMER and TRIG_EXT use the card's 89a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess'burst mode' which limits the valid conversion time to 64 microseconds 90a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess(convert_arg <= 64000). This limitation does not apply if scan_begin_src 91a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessis TRIG_FOLLOW. 92a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 93a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessNOTES: 94a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessOnly the DAS-1801ST has been tested by me. 95a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessUnipolar and bipolar ranges cannot be mixed in the channel/gain list. 96a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 97a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessTODO: 98a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess Make it automatically allocate irq and dma channels if they are not specified 99a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess Add support for analog out on 'ao' cards 100a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess read insn for analog out 101a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess*/ 102a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 103a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include "../comedidev.h" 104a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 105a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include <linux/ioport.h> 106a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include <asm/dma.h> 107a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 108a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include "8253.h" 109a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include "comedi_fc.h" 110a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 111a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// misc. defines 112a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_SIZE 16 //uses 16 io addresses 113a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define FIFO_SIZE 1024 // 1024 sample fifo 114a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define TIMER_BASE 200 // 5 Mhz master clock 115a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define UNIPOLAR 0x4 // bit that determines whether input range is uni/bipolar 116a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_BUF_SIZE 0x1ff00 // size in bytes of dma buffers 117a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 118a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* Registers for the das1800 */ 119a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_FIFO 0x0 120a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_QRAM 0x0 121a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_DAC 0x0 122a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_SELECT 0x2 123a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define ADC 0x0 124a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define QRAM 0x1 125a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAC(a) (0x2 + a) 126a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_DIGITAL 0x3 127a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_CONTROL_A 0x4 128a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define FFEN 0x1 129a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CGEN 0x4 130a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CGSL 0x8 131a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define TGEN 0x10 132a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define TGSL 0x20 133a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define ATEN 0x80 134a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_CONTROL_B 0x5 135a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH5 0x1 136a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH6 0x2 137a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH7 0x3 138a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH5_CH6 0x5 139a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH6_CH7 0x6 140a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH7_CH5 0x7 141a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_ENABLED 0x3 //mask used to determine if dma is enabled 142a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_DUAL 0x4 143a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ3 0x8 144a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ5 0x10 145a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ7 0x18 146a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ10 0x28 147a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ11 0x30 148a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ15 0x38 149a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define FIMD 0x40 150a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_CONTROL_C 0X6 151a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IPCLK 0x1 152a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define XPCLK 0x3 153a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define BMDE 0x4 154a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CMEN 0x8 155a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define UQEN 0x10 156a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define SD 0x40 157a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define UB 0x80 158a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_STATUS 0x7 159a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// bits that prevent interrupt status bits (and CVEN) from being cleared on write 160a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CLEAR_INTR_MASK (CVEN_MASK | 0x1f) 161a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define INT 0x1 162a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMATC 0x2 163a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CT0TC 0x8 164a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define OVF 0x10 165a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define FHF 0x20 166a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define FNE 0x40 167a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CVEN_MASK 0x40 // masks CVEN on write 168a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CVEN 0x80 169a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_BURST_LENGTH 0x8 170a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_BURST_RATE 0x9 171a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_QRAM_ADDRESS 0xa 172a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_COUNTER 0xc 173a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 174a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IOBASE2 0x400 //offset of additional ioports used on 'ao' cards 175a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 176a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessenum { 177a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1701st, das1701st_da, das1702st, das1702st_da, das1702hr, 178a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1702hr_da, 179a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da, 180a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao 181a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 182a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 18371b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int das1800_attach(struct comedi_device * dev, comedi_devconfig * it); 18471b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int das1800_detach(struct comedi_device * dev); 18571b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int das1800_probe(struct comedi_device * dev); 18634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_cancel(struct comedi_device * dev, struct comedi_subdevice * s); 187a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessstatic irqreturn_t das1800_interrupt(int irq, void *d PT_REGS_ARG); 18834c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s); 18971b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic void das1800_ai_handler(struct comedi_device * dev); 19034c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic void das1800_handle_dma(struct comedi_device * dev, struct comedi_subdevice * s, 191a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int status); 19234c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic void das1800_flush_dma(struct comedi_device * dev, struct comedi_subdevice * s); 19334c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic void das1800_flush_dma_channel(struct comedi_device * dev, struct comedi_subdevice * s, 194a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int channel, uint16_t * buffer); 19571b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic void das1800_handle_fifo_half_full(struct comedi_device * dev, 19634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice * s); 19771b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic void das1800_handle_fifo_not_empty(struct comedi_device * dev, 19834c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice * s); 19934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, 200ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd * cmd); 20134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s); 20234c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 203790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 20434c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s, 205790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 20634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s, 207790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 20834c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s, 209790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 210a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 21171b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int das1800_set_frequency(struct comedi_device * dev); 212a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessstatic unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode); 213ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pembertonstatic unsigned int suggest_transfer_size(struct comedi_cmd * cmd); 214a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 215a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// analog input ranges 2169ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_ai_das1801 = { 217a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 8, 218a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 219a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-5, 5), 220a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-1, 1), 221a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-0.1, 0.1), 222a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-0.02, 0.02), 223a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 5), 224a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 1), 225a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 0.1), 226a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 0.02), 227a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 228a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 229a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 2309ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_ai_das1802 = { 231a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 8, 232a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 233a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-10, 10), 234a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-5, 5), 235a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-2.5, 2.5), 236a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-1.25, 1.25), 237a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 10), 238a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 5), 239a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 2.5), 240a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 1.25), 241a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 242a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 243a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 244a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hesstypedef struct das1800_board_struct { 245a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const char *name; 246a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int ai_speed; /* max conversion period in nanoseconds */ 247a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int resolution; /* bits of ai resolution */ 248a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int qram_len; /* length of card's channel / gain queue */ 249a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int common; /* supports AREF_COMMON flag */ 250a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int do_n_chan; /* number of digital output channels */ 251a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */ 252a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int ao_n_chan; /* number of analog out channels */ 2539ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pemberton const struct comedi_lrange *range_ai; /* available input ranges */ 254a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} das1800_board; 255a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 256a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* Warning: the maximum conversion speeds listed below are 257a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * not always achievable depending on board setup (see 258a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * user manual.) 259a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 260a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessstatic const das1800_board das1800_boards[] = { 261a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 262a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1701st", 263a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:6250, 264a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 265a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 266a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 267a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 268a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:0, 269a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:0, 270a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1801, 271a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 272a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 273a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1701st-da", 274a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:6250, 275a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 276a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 277a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 278a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 279a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:1, 280a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:4, 281a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1801, 282a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 283a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 284a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1702st", 285a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:6250, 286a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 287a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 288a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 289a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 290a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:0, 291a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:0, 292a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1802, 293a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 294a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 295a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1702st-da", 296a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:6250, 297a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 298a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 299a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 300a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 301a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:1, 302a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:4, 303a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1802, 304a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 305a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 306a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1702hr", 307a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:20000, 308a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:16, 309a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 310a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 311a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 312a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:0, 313a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:0, 314a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1802, 315a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 316a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 317a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1702hr-da", 318a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:20000, 319a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:16, 320a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 321a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 322a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 323a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:1, 324a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:2, 325a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1802, 326a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 327a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 328a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1701ao", 329a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:6250, 330a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 331a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 332a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 333a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 334a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:2, 335a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:2, 336a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1801, 337a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 338a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 339a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1702ao", 340a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:6250, 341a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 342a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 343a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 344a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 345a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:2, 346a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:2, 347a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1802, 348a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 349a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 350a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1801st", 351a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:3000, 352a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 353a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 354a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 355a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 356a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:0, 357a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:0, 358a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1801, 359a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 360a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 361a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1801st-da", 362a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:3000, 363a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 364a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 365a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 366a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 367a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:0, 368a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:4, 369a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1801, 370a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 371a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 372a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1802st", 373a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:3000, 374a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 375a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 376a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 377a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 378a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:0, 379a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:0, 380a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1802, 381a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 382a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 383a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1802st-da", 384a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:3000, 385a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 386a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 387a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 388a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 389a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:1, 390a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:4, 391a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1802, 392a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 393a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 394a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1802hr", 395a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:10000, 396a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:16, 397a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 398a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 399a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 400a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:0, 401a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:0, 402a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1802, 403a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 404a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 405a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1802hr-da", 406a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:10000, 407a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:16, 408a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 409a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 410a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 411a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:1, 412a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:2, 413a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1802, 414a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 415a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 416a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1801hc", 417a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:3000, 418a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 419a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:64, 420a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 0, 421a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:8, 422a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:1, 423a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:2, 424a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1801, 425a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 426a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 427a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1802hc", 428a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:3000, 429a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 430a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:64, 431a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 0, 432a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:8, 433a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:1, 434a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:2, 435a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1802, 436a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 437a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 438a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1801ao", 439a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:3000, 440a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 441a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 442a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 443a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 444a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:2, 445a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:2, 446a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1801, 447a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 448a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 449a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess name: "das-1802ao", 450a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ai_speed:3000, 451a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess resolution:12, 452a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess qram_len:256, 453a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess common: 1, 454a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess do_n_chan:4, 455a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_ability:2, 456a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ao_n_chan:2, 457a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_ai:&range_ai_das1802, 458a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 459a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 460a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 461a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* 462a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * Useful for shorthand access to the particular board structure 463a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 464a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define thisboard ((const das1800_board *)dev->board_ptr) 465a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 466a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hesstypedef struct { 467a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess volatile unsigned int count; /* number of data points left to be taken */ 468a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */ 469a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */ 470a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int do_bits; /* digital output bits */ 471a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int irq_dma_bits; /* bits for control register b */ 472a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* dma bits for control register b, stored so that dma can be 473a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * turned on and off */ 474a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int dma_bits; 475a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma0; /* dma channels used */ 476a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma1; 477a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess volatile unsigned int dma_current; /* dma channel currently in use */ 478a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess uint16_t *ai_buf0; /* pointers to dma buffers */ 479a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess uint16_t *ai_buf1; 480a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */ 481a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */ 482a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */ 483a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess short ao_update_bits; /* remembers the last write to the 'update' dac */ 484a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} das1800_private; 485a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 486a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define devpriv ((das1800_private *)dev->private) 487a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 488a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// analog out range for boards with basic analog out 4899ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_ao_1 = { 490a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1, 491a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 492a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-10, 10), 493a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 494a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 495a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 496a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// analog out range for 'ao' boards 497a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* 4989ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_ao_2 = { 499a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 2, 500a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 501a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-10, 10), 502a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-5, 5), 503a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 504a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 505a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess*/ 506a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 507139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_das1800 = { 508a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess driver_name:"das1800", 509a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess module:THIS_MODULE, 510a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess attach:das1800_attach, 511a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess detach:das1800_detach, 512a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess num_names:sizeof(das1800_boards) / sizeof(das1800_board), 513a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess board_name:&das1800_boards[0].name, 514a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess offset:sizeof(das1800_board), 515a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 516a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 517a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* 518a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * A convenient macro that defines init_module() and cleanup_module(), 519a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * as necessary. 520a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 521a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessCOMEDI_INITCLEANUP(driver_das1800); 522a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 52371b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int das1800_init_dma(struct comedi_device * dev, unsigned int dma0, 524a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma1) 525a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 526a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long flags; 527a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 528a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // need an irq to do dma 529a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->irq && dma0) { 530a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess //encode dma0 and dma1 into 2 digit hexadecimal for switch 531a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch ((dma0 & 0x7) | (dma1 << 4)) { 532a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x5: // dma0 == 5 533a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH5; 534a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 535a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x6: // dma0 == 6 536a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH6; 537a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 538a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x7: // dma0 == 7 539a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH7; 540a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 541a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x65: // dma0 == 5, dma1 == 6 542a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH5_CH6; 543a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 544a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x76: // dma0 == 6, dma1 == 7 545a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH6_CH7; 546a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 547a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x57: // dma0 == 7, dma1 == 5 548a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH7_CH5; 549a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 550a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 551a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" only supports dma channels 5 through 7\n" 552a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess " Dual dma only allows the following combinations:\n" 553a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess " dma 5,6 / 6,7 / or 7,5\n"); 554a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 555a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 556a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 557a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (request_dma(dma0, driver_das1800.driver_name)) { 558a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" failed to allocate dma channel %i\n", dma0); 559a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 560a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 561a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma0 = dma0; 562a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = dma0; 563a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma1) { 564a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (request_dma(dma1, driver_das1800.driver_name)) { 565a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" failed to allocate dma channel %i\n", 566a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dma1); 567a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 568a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 569a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma1 = dma1; 570a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 571a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 572a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf0 == NULL) 573a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 574a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf0; 575a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma1) { 576a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->ai_buf1 = 577a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 578a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf1 == NULL) 579a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 580a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 581a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess flags = claim_dma_lock(); 582a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma0); 583a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_mode(devpriv->dma0, DMA_MODE_READ); 584a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma1) { 585a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma1); 586a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_mode(devpriv->dma1, DMA_MODE_READ); 587a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 588a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_dma_lock(flags); 589a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 590a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 591a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 592a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 59371b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int das1800_attach(struct comedi_device * dev, comedi_devconfig * it) 594a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 59534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 596a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long iobase = it->options[0]; 597a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int irq = it->options[1]; 598a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma0 = it->options[2]; 599a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma1 = it->options[3]; 600a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long iobase2; 601a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int board; 602a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int retval; 603a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 604a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* allocate and initialize dev->private */ 605a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (alloc_private(dev, sizeof(das1800_private)) < 0) 606a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 607a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 608a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name, 609a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess iobase); 610a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (irq) { 611a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(", irq %u", irq); 612a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma0) { 613a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(", dma %u", dma0); 614a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma1) 615a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" and %u", dma1); 616a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 617a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 618a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk("\n"); 619a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 620a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (iobase == 0) { 621a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" io base address required\n"); 622a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 623a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 624a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 625a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* check if io addresses are available */ 626a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name)) { 627a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase, iobase + DAS1800_SIZE - 1); 628a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EIO; 629a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 630a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->iobase = iobase; 631a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 632a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess board = das1800_probe(dev); 633a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board < 0) { 634a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" unable to determine board type\n"); 635a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENODEV; 636a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 637a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 638a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->board_ptr = das1800_boards + board; 639a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->board_name = thisboard->name; 640a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 641a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // if it is an 'ao' board with fancy analog out then we need extra io ports 642a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (thisboard->ao_ability == 2) { 643a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess iobase2 = iobase + IOBASE2; 644a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!request_region(iobase2, DAS1800_SIZE, 645a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess driver_das1800.driver_name)) { 646a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase2, iobase2 + DAS1800_SIZE - 1); 647a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EIO; 648a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 649a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->iobase2 = iobase2; 650a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 651a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 652a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* grab our IRQ */ 653a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (irq) { 654a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (comedi_request_irq(irq, das1800_interrupt, 0, 655a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess driver_das1800.driver_name, dev)) { 656a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" unable to allocate irq %u\n", irq); 657a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 658a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 659a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 660a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->irq = irq; 661a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 662a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // set bits that tell card which irq to use 663a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (irq) { 664a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0: 665a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 666a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 3: 667a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x8; 668a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 669a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 5: 670a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x10; 671a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 672a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 7: 673a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x18; 674a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 675a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 10: 676a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x28; 677a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 678a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 11: 679a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x30; 680a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 681a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 15: 682a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x38; 683a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 684a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 685a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" irq out of range\n"); 686a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 687a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 688a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 689a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 690a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess retval = das1800_init_dma(dev, dma0, dma1); 691a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (retval < 0) 692a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return retval; 693a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 694a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf0 == NULL) { 695a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->ai_buf0 = 696a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL); 697a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf0 == NULL) 698a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 699a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 700a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 701a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (alloc_subdevices(dev, 4) < 0) 702a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 703a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 704a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* analog input subdevice */ 705a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s = dev->subdevices + 0; 706a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->read_subdev = s; 707a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_AI; 708a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ; 709a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (thisboard->common) 710a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags |= SDF_COMMON; 711a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->n_chan = thisboard->qram_len; 712a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->len_chanlist = thisboard->qram_len; 713a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->maxdata = (1 << thisboard->resolution) - 1; 714a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->range_table = thisboard->range_ai; 715a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->do_cmd = das1800_ai_do_cmd; 716a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->do_cmdtest = das1800_ai_do_cmdtest; 717a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->insn_read = das1800_ai_rinsn; 718a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->poll = das1800_ai_poll; 719a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->cancel = das1800_cancel; 720a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 721a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* analog out */ 722a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s = dev->subdevices + 1; 723a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (thisboard->ao_ability == 1) { 724a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_AO; 725a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags = SDF_WRITABLE; 726a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->n_chan = thisboard->ao_n_chan; 727a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->maxdata = (1 << thisboard->resolution) - 1; 728a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->range_table = &range_ao_1; 729a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->insn_write = das1800_ao_winsn; 730a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 731a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_UNUSED; 732a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 733a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 734a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* di */ 735a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s = dev->subdevices + 2; 736a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_DI; 737a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags = SDF_READABLE; 738a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->n_chan = 4; 739a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->maxdata = 1; 740a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->range_table = &range_digital; 741a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->insn_bits = das1800_di_rbits; 742a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 743a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* do */ 744a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s = dev->subdevices + 3; 745a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_DO; 746a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags = SDF_WRITABLE | SDF_READABLE; 747a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->n_chan = thisboard->do_n_chan; 748a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->maxdata = 1; 749a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->range_table = &range_digital; 750a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->insn_bits = das1800_do_wbits; 751a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 752a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, dev->read_subdev); 753a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 754a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // initialize digital out channels 755a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL); 756a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 757a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // initialize analog out channels 758a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (thisboard->ao_ability == 1) { 759a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // select 'update' dac channel for baseAddress + 0x0 760a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(DAC(thisboard->ao_n_chan - 1), 761a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->iobase + DAS1800_SELECT); 762a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 763a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 764a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 765a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 766a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 767a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 76871b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int das1800_detach(struct comedi_device * dev) 769a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 770a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* only free stuff if it has been allocated by _attach */ 771a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->iobase) 772a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_region(dev->iobase, DAS1800_SIZE); 773a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->irq) 774a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_free_irq(dev->irq, dev); 775a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->private) { 776a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->iobase2) 777a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_region(devpriv->iobase2, DAS1800_SIZE); 778a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma0) 779a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess free_dma(devpriv->dma0); 780a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma1) 781a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess free_dma(devpriv->dma1); 782a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf0) 783a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess kfree(devpriv->ai_buf0); 784a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf1) 785a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess kfree(devpriv->ai_buf1); 786a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 787a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 788a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk("comedi%d: %s: remove\n", dev->minor, 789a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess driver_das1800.driver_name); 790a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 791a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 792a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 793a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 794a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* probes and checks das-1800 series board type 795a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 79671b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int das1800_probe(struct comedi_device * dev) 797a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 798a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int id; 799a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int board; 800a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 801a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */ 802a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess board = ((das1800_board *) dev->board_ptr) - das1800_boards; 803a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 804a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (id) { 805a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x3: 806a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1801st_da || board == das1802st_da || 807a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess board == das1701st_da || board == das1702st_da) { 808a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 809a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_boards[board].name); 810a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 811a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 812a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model (probed, not recommended): das-1800st-da series\n"); 813a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1801st; 814a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 815a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x4: 816a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1802hr_da || board == das1702hr_da) { 817a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 818a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_boards[board].name); 819a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 820a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 821a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model (probed, not recommended): das-1802hr-da\n"); 822a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1802hr; 823a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 824a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x5: 825a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1801ao || board == das1802ao || 826a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess board == das1701ao || board == das1702ao) { 827a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 828a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_boards[board].name); 829a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 830a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 831a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model (probed, not recommended): das-1800ao series\n"); 832a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1801ao; 833a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 834a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x6: 835a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1802hr || board == das1702hr) { 836a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 837a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_boards[board].name); 838a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 839a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 840a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model (probed, not recommended): das-1802hr\n"); 841a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1802hr; 842a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 843a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x7: 844a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1801st || board == das1802st || 845a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess board == das1701st || board == das1702st) { 846a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 847a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_boards[board].name); 848a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 849a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 850a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model (probed, not recommended): das-1800st series\n"); 851a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1801st; 852a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 853a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x8: 854a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1801hc || board == das1802hc) { 855a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 856a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_boards[board].name); 857a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 858a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 859a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model (probed, not recommended): das-1800hc series\n"); 860a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1801hc; 861a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 862a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 863a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: probe returned 0x%x (unknown, please report)\n", id); 864a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 865a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 866a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 867a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 868a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 869a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 87034c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s) 871a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 872a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long flags; 873a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 874a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // prevent race with interrupt handler 875a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_spin_lock_irqsave(&dev->spinlock, flags); 876a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_ai_handler(dev); 877a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_spin_unlock_irqrestore(&dev->spinlock, flags); 878a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 879a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return s->async->buf_write_count - s->async->buf_read_count; 880a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 881a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 882a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessstatic irqreturn_t das1800_interrupt(int irq, void *d PT_REGS_ARG) 883a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 88471b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton struct comedi_device *dev = d; 885a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int status; 886a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 887a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->attached == 0) { 888a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, "premature interrupt"); 889a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return IRQ_HANDLED; 890a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 891a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 892a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* Prevent race with das1800_ai_poll() on multi processor systems. 893a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * Also protects indirect addressing in das1800_ai_handler */ 894a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess spin_lock(&dev->spinlock); 895a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess status = inb(dev->iobase + DAS1800_STATUS); 896a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 897a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if interrupt was not caused by das-1800 */ 898a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!(status & INT)) { 899a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess spin_unlock(&dev->spinlock); 900a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return IRQ_NONE; 901a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 902a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* clear the interrupt status bit INT */ 903a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS); 904a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // handle interrupt 905a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_ai_handler(dev); 906a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 907a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess spin_unlock(&dev->spinlock); 908a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return IRQ_HANDLED; 909a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 910a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 911a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// the guts of the interrupt handler, that is shared with das1800_ai_poll 91271b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic void das1800_ai_handler(struct comedi_device * dev) 913a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 91434c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */ 915d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 916ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &async->cmd; 917a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int status = inb(dev->iobase + DAS1800_STATUS); 918a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 919a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events = 0; 920a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // select adc for base address + 0 921a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(ADC, dev->iobase + DAS1800_SELECT); 922a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // dma buffer full 923a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->irq_dma_bits & DMA_ENABLED) { 924a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // look for data from dma transfer even if dma terminal count hasn't happened yet 925a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_dma(dev, s, status); 926a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else if (status & FHF) { // if fifo half full 927a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_fifo_half_full(dev, s); 928a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else if (status & FNE) { // if fifo not empty 929a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_fifo_not_empty(dev, s); 930a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 931a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 932a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events |= COMEDI_CB_BLOCK; 933a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if the card's fifo has overflowed */ 934a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (status & OVF) { 935a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // clear OVF interrupt bit 936a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS); 937a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, "DAS1800 FIFO overflow"); 938a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, s); 939a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 940a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_event(dev, s); 941a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 942a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 943a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // stop taking data if appropriate 944a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* stop_src TRIG_EXT */ 945a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (status & CT0TC) { 946a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // clear CT0TC interrupt bit 947a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS); 948a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // make sure we get all remaining data from board before quitting 949a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->irq_dma_bits & DMA_ENABLED) 950a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_flush_dma(dev, s); 951a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess else 952a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_fifo_not_empty(dev, s); 953a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, s); /* disable hardware conversions */ 954a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events |= COMEDI_CB_EOA; 955a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { // stop_src TRIG_COUNT 956a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, s); /* disable hardware conversions */ 957a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events |= COMEDI_CB_EOA; 958a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 959a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 960a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_event(dev, s); 961a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 962a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 963a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 964a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 96534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic void das1800_handle_dma(struct comedi_device * dev, struct comedi_subdevice * s, 966a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int status) 967a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 968a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long flags; 969a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 970a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 971a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess flags = claim_dma_lock(); 972a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_flush_dma_channel(dev, s, devpriv->dma_current, 973a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf); 974a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // re-enable dma channel 975a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_addr(devpriv->dma_current, 976a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess virt_to_bus(devpriv->dma_current_buf)); 977a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size); 978a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess enable_dma(devpriv->dma_current); 979a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_dma_lock(flags); 980a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 981a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (status & DMATC) { 982a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // clear DMATC interrupt bit 983a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS); 984a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // switch dma channels for next time, if appropriate 985a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dual_dma) { 986a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // read data from the other channel next time 987a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma_current == devpriv->dma0) { 988a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma1; 989a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf1; 990a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 991a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma0; 992a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf0; 993a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 994a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 995a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 996a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 997a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 998a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 999a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 100071b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic inline uint16_t munge_bipolar_sample(const struct comedi_device * dev, 1001a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess uint16_t sample) 1002a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1003a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess sample += 1 << (thisboard->resolution - 1); 1004a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return sample; 1005a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1006a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 100771b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic void munge_data(struct comedi_device * dev, uint16_t * array, 1008a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int num_elements) 1009a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1010a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int i; 1011a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int unipolar; 1012a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1013a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* see if card is using a unipolar or bipolar range so we can munge data correctly */ 1014a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 1015a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1016a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* convert to unsigned type if we are in a bipolar mode */ 1017a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!unipolar) { 1018a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (i = 0; i < num_elements; i++) { 1019a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess array[i] = munge_bipolar_sample(dev, array[i]); 1020a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1021a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1022a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1023a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1024a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* Utility function used by das1800_flush_dma() and das1800_handle_dma(). 1025a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * Assumes dma lock is held */ 102634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic void das1800_flush_dma_channel(struct comedi_device * dev, struct comedi_subdevice * s, 1027a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int channel, uint16_t * buffer) 1028a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1029a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int num_bytes, num_samples; 1030ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 1031a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1032a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(channel); 1033a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1034a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* clear flip-flop to make sure 2-byte registers 1035a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * get set correctly */ 1036a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess clear_dma_ff(channel); 1037a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1038a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // figure out how many points to read 1039a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel); 1040790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton num_samples = num_bytes / sizeof(short); 1041a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1042a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if we only need some of the points */ 1043a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples) 1044a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess num_samples = devpriv->count; 1045a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1046a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess munge_data(dev, buffer, num_samples); 1047a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cfc_write_array_to_buffer(s, buffer, num_bytes); 1048a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (s->async->cmd.stop_src == TRIG_COUNT) 1049a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->count -= num_samples; 1050a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1051a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1052a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1053a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1054a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* flushes remaining data from board when external trigger has stopped aquisition 1055a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * and we are using dma transfers */ 105634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic void das1800_flush_dma(struct comedi_device * dev, struct comedi_subdevice * s) 1057a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1058a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long flags; 1059a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1060a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1061a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess flags = claim_dma_lock(); 1062a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_flush_dma_channel(dev, s, devpriv->dma_current, 1063a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf); 1064a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1065a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dual_dma) { 1066a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // switch to other channel and flush it 1067a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma_current == devpriv->dma0) { 1068a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma1; 1069a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf1; 1070a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 1071a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma0; 1072a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf0; 1073a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1074a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_flush_dma_channel(dev, s, devpriv->dma_current, 1075a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf); 1076a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1077a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1078a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_dma_lock(flags); 1079a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1080a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // get any remaining samples in fifo 1081a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_fifo_not_empty(dev, s); 1082a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1083a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1084a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1085a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 108671b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic void das1800_handle_fifo_half_full(struct comedi_device * dev, 108734c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice * s) 1088a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1089a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int numPoints = 0; /* number of points to read */ 1090ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 1091a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1092a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess numPoints = FIFO_SIZE / 2; 1093a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if we only need some of the points */ 1094a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints) 1095a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess numPoints = devpriv->count; 1096a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints); 1097a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess munge_data(dev, devpriv->ai_buf0, numPoints); 1098a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cfc_write_array_to_buffer(s, devpriv->ai_buf0, 1099a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess numPoints * sizeof(devpriv->ai_buf0[0])); 1100a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT) 1101a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->count -= numPoints; 1102a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1103a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1104a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 110571b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic void das1800_handle_fifo_not_empty(struct comedi_device * dev, 110634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice * s) 1107a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1108790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short dpnt; 1109a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int unipolar; 1110ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 1111a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1112a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 1113a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1114a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess while (inb(dev->iobase + DAS1800_STATUS) & FNE) { 1115a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) 1116a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1117a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dpnt = inw(dev->iobase + DAS1800_FIFO); 1118a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* convert to unsigned type if we are in a bipolar mode */ 1119a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!unipolar) ; 1120a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dpnt = munge_bipolar_sample(dev, dpnt); 1121a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cfc_write_to_buffer(s, dpnt); 1122a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT) 1123a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->count--; 1124a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1125a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1126a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1127a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1128a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 112934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_cancel(struct comedi_device * dev, struct comedi_subdevice * s) 1130a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1131a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ 1132a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ 1133a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ 1134a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma0) 1135a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma0); 1136a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma1) 1137a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma1); 1138a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1139a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1140a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1141a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* test analog input cmd */ 114234c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, 1143ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd * cmd) 1144a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1145a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int err = 0; 1146a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int tmp; 1147a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int tmp_arg; 1148a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int i; 1149a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int unipolar; 1150a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1151a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* step 1: make sure trigger sources are trivially valid */ 1152a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1153a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->start_src; 1154a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->start_src &= TRIG_NOW | TRIG_EXT; 1155a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->start_src || tmp != cmd->start_src) 1156a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1157a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1158a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->scan_begin_src; 1159a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; 1160a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 1161a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1162a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1163a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->convert_src; 1164a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->convert_src &= TRIG_TIMER | TRIG_EXT; 1165a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->convert_src || tmp != cmd->convert_src) 1166a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1167a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1168a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->scan_end_src; 1169a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_end_src &= TRIG_COUNT; 1170a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 1171a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1172a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1173a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->stop_src; 1174a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE; 1175a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->stop_src || tmp != cmd->stop_src) 1176a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1177a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1178a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1179a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 1; 1180a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1181a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* step 2: make sure trigger sources are unique and mutually compatible */ 1182a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1183a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // uniqueness check 1184a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) 1185a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1186a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_begin_src != TRIG_FOLLOW && 1187a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_begin_src != TRIG_TIMER && 1188a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_begin_src != TRIG_EXT) 1189a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1190a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) 1191a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1192a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src != TRIG_COUNT && 1193a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT) 1194a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1195a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess //compatibility check 1196a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_begin_src != TRIG_FOLLOW && 1197a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->convert_src != TRIG_TIMER) 1198a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1199a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1200a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1201a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 2; 1202a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1203a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* step 3: make sure arguments are trivially compatible */ 1204a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1205a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->start_arg != 0) { 1206a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->start_arg = 0; 1207a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1208a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1209a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_src == TRIG_TIMER) { 1210a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_arg < thisboard->ai_speed) { 1211a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->convert_arg = thisboard->ai_speed; 1212a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1213a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1214a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1215a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->chanlist_len) { 1216a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->chanlist_len = 1; 1217a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1218a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1219a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_end_arg != cmd->chanlist_len) { 1220a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_end_arg = cmd->chanlist_len; 1221a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1222a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1223a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1224a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd->stop_src) { 1225a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_COUNT: 1226a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->stop_arg) { 1227a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->stop_arg = 1; 1228a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1229a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1230a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1231a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_NONE: 1232a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_arg != 0) { 1233a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->stop_arg = 0; 1234a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1235a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1236a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1237a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1238a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1239a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1240a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1241a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1242a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 3; 1243a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1244a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* step 4: fix up any arguments */ 1245a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1246a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_src == TRIG_TIMER) { 1247a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // if we are not in burst mode 1248a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_begin_src == TRIG_FOLLOW) { 1249a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp_arg = cmd->convert_arg; 1250a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* calculate counter values that give desired timing */ 1251a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1252a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(devpriv->divisor1), &(devpriv->divisor2), 1253a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(cmd->convert_arg), 1254a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->flags & TRIG_ROUND_MASK); 1255a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (tmp_arg != cmd->convert_arg) 1256a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1257a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1258a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // if we are in burst mode 1259a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess else { 1260a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // check that convert_arg is compatible 1261a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp_arg = cmd->convert_arg; 1262a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->convert_arg = 1263a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess burst_convert_arg(cmd->convert_arg, 1264a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->flags & TRIG_ROUND_MASK); 1265a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (tmp_arg != cmd->convert_arg) 1266a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1267a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1268a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_begin_src == TRIG_TIMER) { 1269a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // if scans are timed faster than conversion rate allows 1270a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_arg * cmd->chanlist_len > 1271a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_begin_arg) { 1272a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_begin_arg = 1273a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->convert_arg * 1274a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->chanlist_len; 1275a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1276a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1277a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp_arg = cmd->scan_begin_arg; 1278a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* calculate counter values that give desired timing */ 1279a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1280a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(devpriv->divisor1), 1281a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(devpriv->divisor2), 1282a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(cmd->scan_begin_arg), 1283a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->flags & TRIG_ROUND_MASK); 1284a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (tmp_arg != cmd->scan_begin_arg) 1285a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1286a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1287a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1288a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1289a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1290a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1291a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 4; 1292a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1293a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // make sure user is not trying to mix unipolar and bipolar ranges 1294a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->chanlist) { 1295a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR; 1296a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (i = 1; i < cmd->chanlist_len; i++) { 1297a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) { 1298a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, 1299a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess "unipolar and bipolar ranges cannot be mixed in the chanlist"); 1300a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1301a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1302a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1303a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1304a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1305a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1306a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1307a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 5; 1308a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1309a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1310a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1311a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1312a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* analog input cmd interface */ 1313a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1314a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// first, some utility functions used in the main ai_do_cmd() 1315a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1316a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// returns appropriate bits for control register a, depending on command 1317ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pembertonstatic int control_a_bits(struct comedi_cmd cmd) 1318a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1319a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int control_a; 1320a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1321a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_a = FFEN; //enable fifo 1322a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.stop_src == TRIG_EXT) { 1323a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_a |= ATEN; 1324a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1325a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd.start_src) { 1326a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_EXT: 1327a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_a |= TGEN | CGSL; 1328a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1329a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_NOW: 1330a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_a |= CGEN; 1331a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1332a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1333a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1334a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1335a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1336a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return control_a; 1337a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1338a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1339a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// returns appropriate bits for control register c, depending on command 1340ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pembertonstatic int control_c_bits(struct comedi_cmd cmd) 1341a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1342a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int control_c; 1343a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int aref; 1344a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1345a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* set clock source to internal or external, select analog reference, 1346a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * select unipolar / bipolar 1347a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 1348a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess aref = CR_AREF(cmd.chanlist[0]); 1349a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c = UQEN; //enable upper qram addresses 1350a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (aref != AREF_DIFF) 1351a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= SD; 1352a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (aref == AREF_COMMON) 1353a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= CMEN; 1354a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if a unipolar range was selected */ 1355a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR) 1356a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= UB; 1357a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd.scan_begin_src) { 1358a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_FOLLOW: // not in burst mode 1359a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd.convert_src) { 1360a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_TIMER: 1361a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* trig on cascaded counters */ 1362a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= IPCLK; 1363a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1364a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_EXT: 1365a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* trig on falling edge of external trigger */ 1366a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= XPCLK; 1367a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1368a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1369a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1370a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1371a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1372a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_TIMER: 1373a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // burst mode with internal pacer clock 1374a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= BMDE | IPCLK; 1375a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1376a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_EXT: 1377a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // burst mode with external trigger 1378a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= BMDE | XPCLK; 1379a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1380a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1381a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1382a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1383a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1384a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return control_c; 1385a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1386a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1387a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// sets up counters 1388ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pembertonstatic int setup_counters(struct comedi_device * dev, struct comedi_cmd cmd) 1389a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1390a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // setup cascaded counters for conversion/scan frequency 1391a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd.scan_begin_src) { 1392a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_FOLLOW: // not in burst mode 1393a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.convert_src == TRIG_TIMER) { 1394a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* set conversion frequency */ 1395a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1396a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(devpriv->divisor1), &(devpriv->divisor2), 1397a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(cmd.convert_arg), 1398a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd.flags & TRIG_ROUND_MASK); 1399a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (das1800_set_frequency(dev) < 0) { 1400a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 1401a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1402a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1403a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1404a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_TIMER: // in burst mode 1405a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* set scan frequency */ 1406a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), 1407a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(devpriv->divisor2), &(cmd.scan_begin_arg), 1408a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd.flags & TRIG_ROUND_MASK); 1409a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (das1800_set_frequency(dev) < 0) { 1410a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 1411a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1412a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1413a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1414a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1415a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1416a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1417a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // setup counter 0 for 'about triggering' 1418a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.stop_src == TRIG_EXT) { 1419a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // load counter 0 in mode 0 1420a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0); 1421a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1422a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1423a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1424a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1425a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1426a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// sets up dma 1427ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pembertonstatic void setup_dma(struct comedi_device * dev, struct comedi_cmd cmd) 1428a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1429a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long lock_flags; 1430a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1431a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1432a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0) 1433a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1434a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1435a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* determine a reasonable dma transfer size */ 1436a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_transfer_size = suggest_transfer_size(&cmd); 1437a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess lock_flags = claim_dma_lock(); 1438a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma0); 1439a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* clear flip-flop to make sure 2-byte registers for 1440a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * count and address get set correctly */ 1441a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess clear_dma_ff(devpriv->dma0); 1442a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0)); 1443a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // set appropriate size of transfer 1444a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_count(devpriv->dma0, devpriv->dma_transfer_size); 1445a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma0; 1446a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf0; 1447a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess enable_dma(devpriv->dma0); 1448a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // set up dual dma if appropriate 1449a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dual_dma) { 1450a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma1); 1451a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* clear flip-flop to make sure 2-byte registers for 1452a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * count and address get set correctly */ 1453a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess clear_dma_ff(devpriv->dma1); 1454a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1)); 1455a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // set appropriate size of transfer 1456a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_count(devpriv->dma1, devpriv->dma_transfer_size); 1457a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess enable_dma(devpriv->dma1); 1458a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1459a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_dma_lock(lock_flags); 1460a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1461a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1462a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1463a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1464a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// programs channel/gain list into card 1465ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pembertonstatic void program_chanlist(struct comedi_device * dev, struct comedi_cmd cmd) 1466a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1467a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int i, n, chan_range; 1468a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long irq_flags; 1469a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const int range_mask = 0x3; //masks unipolar/bipolar bit off range 1470a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const int range_bitshift = 8; 1471a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1472a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess n = cmd.chanlist_len; 1473a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // spinlock protects indirect addressing 1474a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_spin_lock_irqsave(&dev->spinlock, irq_flags); 1475a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1476a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */ 1477a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* make channel / gain list */ 1478a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (i = 0; i < n; i++) { 1479a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess chan_range = 1480a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess CR_CHAN(cmd.chanlist[i]) | ((CR_RANGE(cmd. 1481a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess chanlist[i]) & range_mask) << 1482a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_bitshift); 1483a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(chan_range, dev->iobase + DAS1800_QRAM); 1484a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1485a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1486a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1487a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1488a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1489a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1490a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1491a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// analog input do_cmd 149234c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s) 1493a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1494a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int ret; 1495a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int control_a, control_c; 1496d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1497ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd cmd = async->cmd; 1498a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1499a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!dev->irq) { 1500a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, 1501a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess "no irq assigned for das-1800, cannot do hardware conversions"); 1502a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 1503a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1504a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1505a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* disable dma on TRIG_WAKE_EOS, or TRIG_RT 1506a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * (because dma in handler is unsafe at hard real-time priority) */ 1507a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) { 1508a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits &= ~DMA_ENABLED; 1509a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 1510a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= devpriv->dma_bits; 1511a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1512a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // interrupt on end of conversion for TRIG_WAKE_EOS 1513a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.flags & TRIG_WAKE_EOS) { 1514a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // interrupt fifo not empty 1515a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits &= ~FIMD; 1516a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 1517a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // interrupt fifo half full 1518a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= FIMD; 1519a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1520a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // determine how many conversions we need 1521a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.stop_src == TRIG_COUNT) { 1522a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->count = cmd.stop_arg * cmd.chanlist_len; 1523a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1524a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1525a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, s); 1526a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1527a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // determine proper bits for control registers 1528a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_a = control_a_bits(cmd); 1529a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c = control_c_bits(cmd); 1530a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1531a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* setup card and start */ 1532a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess program_chanlist(dev, cmd); 1533a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ret = setup_counters(dev, cmd); 1534a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (ret < 0) { 1535a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, "Error setting up counters"); 1536a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return ret; 1537a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1538a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess setup_dma(dev, cmd); 1539a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(control_c, dev->iobase + DAS1800_CONTROL_C); 1540a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // set conversion rate and length for burst mode 1541a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (control_c & BMDE) { 1542a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // program conversion period with number of microseconds minus 1 1543a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(cmd.convert_arg / 1000 - 1, 1544a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->iobase + DAS1800_BURST_RATE); 1545a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH); 1546a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1547a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); // enable irq/dma 1548a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */ 1549a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1550a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1551a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1552a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1553a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1554a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* read analog input */ 155534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 1556790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data) 1557a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1558a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int i, n; 1559a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int chan, range, aref, chan_range; 1560a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int timeout = 1000; 1561a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess short dpnt; 1562a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int conv_flags = 0; 1563a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long irq_flags; 1564a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1565a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* set up analog reference and unipolar / bipolar mode */ 1566a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess aref = CR_AREF(insn->chanspec); 1567a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess conv_flags |= UQEN; 1568a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (aref != AREF_DIFF) 1569a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess conv_flags |= SD; 1570a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (aref == AREF_COMMON) 1571a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess conv_flags |= CMEN; 1572a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if a unipolar range was selected */ 1573a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (CR_RANGE(insn->chanspec) & UNIPOLAR) 1574a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess conv_flags |= UB; 1575a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1576a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */ 1577a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1578a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */ 1579a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(FFEN, dev->iobase + DAS1800_CONTROL_A); 1580a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1581a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess chan = CR_CHAN(insn->chanspec); 1582a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* mask of unipolar/bipolar bit from range */ 1583a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range = CR_RANGE(insn->chanspec) & 0x3; 1584a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess chan_range = chan | (range << 8); 1585a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_spin_lock_irqsave(&dev->spinlock, irq_flags); 1586a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1587a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */ 1588a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(chan_range, dev->iobase + DAS1800_QRAM); 1589a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1590a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */ 1591a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1592a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (n = 0; n < insn->n; n++) { 1593a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* trigger conversion */ 1594a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0, dev->iobase + DAS1800_FIFO); 1595a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (i = 0; i < timeout; i++) { 1596a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (inb(dev->iobase + DAS1800_STATUS) & FNE) 1597a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1598a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1599a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (i == timeout) { 1600a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, "timeout"); 1601a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ETIME; 1602a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1603a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dpnt = inw(dev->iobase + DAS1800_FIFO); 1604a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* shift data to offset binary for bipolar ranges */ 1605a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if ((conv_flags & UB) == 0) 1606a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dpnt += 1 << (thisboard->resolution - 1); 1607a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[n] = dpnt; 1608a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1609a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1610a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1611a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return n; 1612a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1613a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1614a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* writes to an analog output channel */ 161534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s, 1616790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data) 1617a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1618a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int chan = CR_CHAN(insn->chanspec); 1619a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// int range = CR_RANGE(insn->chanspec); 1620a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int update_chan = thisboard->ao_n_chan - 1; 1621a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess short output; 1622a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long irq_flags; 1623a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1624a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // card expects two's complement data 1625a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess output = data[0] - (1 << (thisboard->resolution - 1)); 1626a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // if the write is to the 'update' channel, we need to remember its value 1627a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (chan == update_chan) 1628a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->ao_update_bits = output; 1629a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // write to channel 1630a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_spin_lock_irqsave(&dev->spinlock, irq_flags); 1631a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */ 1632a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(output, dev->iobase + DAS1800_DAC); 1633a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // now we need to write to 'update' channel to update all dac channels 1634a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (chan != update_chan) { 1635a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */ 1636a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 1637a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1638a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1639a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1640a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 1; 1641a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1642a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1643a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* reads from digital input channels */ 164434c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s, 1645790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data) 1646a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1647a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1648a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf; 1649a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[0] = 0; 1650a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1651a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 2; 1652a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1653a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1654a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* writes to digital output channels */ 165534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das1800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s, 1656790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data) 1657a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1658790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int wbits; 1659a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1660a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // only set bits that have been masked 1661a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[0] &= (1 << s->n_chan) - 1; 1662a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess wbits = devpriv->do_bits; 1663a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess wbits &= ~data[0]; 1664a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess wbits |= data[0] & data[1]; 1665a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->do_bits = wbits; 1666a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1667a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL); 1668a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1669a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[1] = devpriv->do_bits; 1670a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1671a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 2; 1672a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1673a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1674a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* loads counters with divisor1, divisor2 from private structure */ 167571b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int das1800_set_frequency(struct comedi_device * dev) 1676a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1677a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int err = 0; 1678a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1679a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // counter 1, mode 2 1680a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1, 1681a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 2)) 1682a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1683a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // counter 2, mode 2 1684a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2, 1685a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 2)) 1686a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1687a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1688a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 1689a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1690a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1691a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1692a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1693a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* converts requested conversion timing to timing compatible with 1694a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * hardware, used only when card is in 'burst mode' 1695a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 1696a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessstatic unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode) 1697a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1698a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int micro_sec; 1699a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1700a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // in burst mode, the maximum conversion time is 64 microseconds 1701a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (convert_arg > 64000) 1702a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess convert_arg = 64000; 1703a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1704a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // the conversion time must be an integral number of microseconds 1705a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (round_mode) { 1706a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_ROUND_NEAREST: 1707a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1708a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess micro_sec = (convert_arg + 500) / 1000; 1709a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1710a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_ROUND_DOWN: 1711a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess micro_sec = convert_arg / 1000; 1712a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1713a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_ROUND_UP: 1714a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess micro_sec = (convert_arg - 1) / 1000 + 1; 1715a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1716a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1717a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1718a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // return number of nanoseconds 1719a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return micro_sec * 1000; 1720a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1721a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1722a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess// utility function that suggests a dma transfer size based on the conversion period 'ns' 1723ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pembertonstatic unsigned int suggest_transfer_size(struct comedi_cmd * cmd) 1724a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1725a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int size = DMA_BUF_SIZE; 1726a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess static const int sample_size = 2; // size in bytes of one sample from board 1727a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int fill_time = 300000000; // target time in nanoseconds for filling dma buffer 1728a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int max_size; // maximum size we will allow for a transfer 1729a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1730a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // make dma buffer fill in 0.3 seconds for timed modes 1731a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd->scan_begin_src) { 1732a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_FOLLOW: // not in burst mode 1733a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_src == TRIG_TIMER) 1734a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = (fill_time / cmd->convert_arg) * sample_size; 1735a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1736a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_TIMER: 1737a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) * 1738a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess sample_size; 1739a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1740a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1741a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = DMA_BUF_SIZE; 1742a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1743a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1744a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1745a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // set a minimum and maximum size allowed 1746a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess max_size = DMA_BUF_SIZE; 1747a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess // if we are taking limited number of conversions, limit transfer size to that 1748a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT && 1749a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->stop_arg * cmd->chanlist_len * sample_size < max_size) 1750a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess max_size = cmd->stop_arg * cmd->chanlist_len * sample_size; 1751a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1752a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (size > max_size) 1753a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = max_size; 1754a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (size < sample_size) 1755a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = sample_size; 1756a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1757a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return size; 1758a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1759