das1800.c revision 25436dc9d84f1be60ff549c9ab712bba2835f284
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 10325436dc9d84f1be60ff549c9ab712bba2835f284Greg Kroah-Hartman#include <linux/interrupt.h> 104a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include "../comedidev.h" 105a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 106a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include <linux/ioport.h> 107a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include <asm/dma.h> 108a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 109a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include "8253.h" 110a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include "comedi_fc.h" 111a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 112a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* misc. defines */ 113a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define DAS1800_SIZE 16 /* uses 16 io addresses */ 114a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define FIFO_SIZE 1024 /* 1024 sample fifo */ 115a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define TIMER_BASE 200 /* 5 Mhz master clock */ 116a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define UNIPOLAR 0x4 /* bit that determines whether input range is uni/bipolar */ 117a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define DMA_BUF_SIZE 0x1ff00 /* size in bytes of dma buffers */ 118a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 119a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* Registers for the das1800 */ 120a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_FIFO 0x0 121a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_QRAM 0x0 122a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_DAC 0x0 123a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_SELECT 0x2 124a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define ADC 0x0 125a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define QRAM 0x1 126a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAC(a) (0x2 + a) 127a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_DIGITAL 0x3 128a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_CONTROL_A 0x4 129a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define FFEN 0x1 130a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CGEN 0x4 131a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CGSL 0x8 132a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define TGEN 0x10 133a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define TGSL 0x20 134a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define ATEN 0x80 135a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_CONTROL_B 0x5 136a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH5 0x1 137a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH6 0x2 138a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH7 0x3 139a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH5_CH6 0x5 140a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH6_CH7 0x6 141a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH7_CH5 0x7 142a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define DMA_ENABLED 0x3 /* mask used to determine if dma is enabled */ 143a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_DUAL 0x4 144a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ3 0x8 145a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ5 0x10 146a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ7 0x18 147a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ10 0x28 148a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ11 0x30 149a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ15 0x38 150a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define FIMD 0x40 151a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_CONTROL_C 0X6 152a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IPCLK 0x1 153a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define XPCLK 0x3 154a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define BMDE 0x4 155a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CMEN 0x8 156a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define UQEN 0x10 157a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define SD 0x40 158a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define UB 0x80 159a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_STATUS 0x7 160a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* bits that prevent interrupt status bits (and CVEN) from being cleared on write */ 161a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CLEAR_INTR_MASK (CVEN_MASK | 0x1f) 162a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define INT 0x1 163a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMATC 0x2 164a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CT0TC 0x8 165a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define OVF 0x10 166a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define FHF 0x20 167a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define FNE 0x40 168a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define CVEN_MASK 0x40 /* masks CVEN on write */ 169a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CVEN 0x80 170a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_BURST_LENGTH 0x8 171a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_BURST_RATE 0x9 172a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_QRAM_ADDRESS 0xa 173a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_COUNTER 0xc 174a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 175a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define IOBASE2 0x400 /* offset of additional ioports used on 'ao' cards */ 176a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 177a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessenum { 178a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1701st, das1701st_da, das1702st, das1702st_da, das1702hr, 179a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1702hr_da, 180a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da, 181a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao 182a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 183a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 184814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_attach(struct comedi_device *dev, struct comedi_devconfig *it); 185814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_detach(struct comedi_device *dev); 186814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_probe(struct comedi_device *dev); 187814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s); 18870265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t das1800_interrupt(int irq, void *d); 189814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s); 190814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void das1800_ai_handler(struct comedi_device *dev); 191814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void das1800_handle_dma(struct comedi_device *dev, struct comedi_subdevice *s, 192a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int status); 193814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void das1800_flush_dma(struct comedi_device *dev, struct comedi_subdevice *s); 194814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void das1800_flush_dma_channel(struct comedi_device *dev, struct comedi_subdevice *s, 195814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton unsigned int channel, uint16_t *buffer); 196814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void das1800_handle_fifo_half_full(struct comedi_device *dev, 197814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_subdevice *s); 198814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void das1800_handle_fifo_not_empty(struct comedi_device *dev, 199814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_subdevice *s); 200814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, 201814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_cmd *cmd); 202814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s); 203814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, 204814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 205814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, 206814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 207814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, 208814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 209814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, 210814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton struct comedi_insn *insn, unsigned int *data); 211814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton 212814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_set_frequency(struct comedi_device *dev); 213a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessstatic unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode); 214814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic unsigned int suggest_transfer_size(struct comedi_cmd *cmd); 215a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 216a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* analog input ranges */ 2179ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_ai_das1801 = { 218a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 8, 219a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 220a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-5, 5), 221a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-1, 1), 222a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-0.1, 0.1), 223a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-0.02, 0.02), 224a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 5), 225a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 1), 226a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 0.1), 227a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 0.02), 228a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 229a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 230a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 2319ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_ai_das1802 = { 232a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 8, 233a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 234a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-10, 10), 235a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-5, 5), 236a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-2.5, 2.5), 237a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-1.25, 1.25), 238a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 10), 239a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 5), 240a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 2.5), 241a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(0, 1.25), 242a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 243a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 244a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 245ce422cf3569444116d7d826b274bd59cc34d3b28Bill Pembertonstruct das1800_board { 246a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const char *name; 247a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int ai_speed; /* max conversion period in nanoseconds */ 248a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int resolution; /* bits of ai resolution */ 249a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int qram_len; /* length of card's channel / gain queue */ 250a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int common; /* supports AREF_COMMON flag */ 251a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int do_n_chan; /* number of digital output channels */ 252a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */ 253a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int ao_n_chan; /* number of analog out channels */ 2549ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pemberton const struct comedi_lrange *range_ai; /* available input ranges */ 255ce422cf3569444116d7d826b274bd59cc34d3b28Bill Pemberton}; 256a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 257a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* Warning: the maximum conversion speeds listed below are 258a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * not always achievable depending on board setup (see 259a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * user manual.) 260a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 261ce422cf3569444116d7d826b274bd59cc34d3b28Bill Pembertonstatic const struct das1800_board das1800_boards[] = { 262a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 26368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1701st", 26468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 6250, 26568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 26668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 26768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 26868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 26968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 0, 27068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 0, 27168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1801, 272a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 273a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 27468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1701st-da", 27568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 6250, 27668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 27768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 27868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 27968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 28068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 1, 28168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 4, 28268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1801, 283a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 284a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 28568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1702st", 28668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 6250, 28768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 28868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 28968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 29068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 29168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 0, 29268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 0, 29368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1802, 294a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 295a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 29668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1702st-da", 29768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 6250, 29868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 29968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 30068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 30168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 30268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 1, 30368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 4, 30468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1802, 305a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 306a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 30768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1702hr", 30868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 20000, 30968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 16, 31068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 31168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 31268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 31368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 0, 31468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 0, 31568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1802, 316a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 317a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 31868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1702hr-da", 31968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 20000, 32068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 16, 32168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 32268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 32368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 32468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 1, 32568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 2, 32668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1802, 327a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 328a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 32968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1701ao", 33068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 6250, 33168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 33268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 33368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 33468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 33568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 2, 33668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 2, 33768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1801, 338a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 339a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 34068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1702ao", 34168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 6250, 34268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 34368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 34468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 34568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 34668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 2, 34768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 2, 34868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1802, 349a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 350a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 35168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1801st", 35268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 3000, 35368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 35468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 35568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 35668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 35768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 0, 35868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 0, 35968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1801, 360a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 361a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 36268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1801st-da", 36368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 3000, 36468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 36568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 36668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 36768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 36868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 0, 36968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 4, 37068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1801, 371a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 372a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 37368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1802st", 37468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 3000, 37568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 37668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 37768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 37868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 37968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 0, 38068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 0, 38168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1802, 382a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 383a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 38468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1802st-da", 38568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 3000, 38668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 38768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 38868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 38968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 39068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 1, 39168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 4, 39268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1802, 393a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 394a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 39568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1802hr", 39668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 10000, 39768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 16, 39868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 39968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 40068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 40168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 0, 40268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 0, 40368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1802, 404a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 405a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 40668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1802hr-da", 40768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 10000, 40868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 16, 40968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 41068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 41168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 41268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 1, 41368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 2, 41468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1802, 415a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 416a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 41768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1801hc", 41868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 3000, 41968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 42068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 64, 42168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 0, 42268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 8, 42368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 1, 42468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 2, 42568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1801, 426a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 427a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 42868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1802hc", 42968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 3000, 43068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 43168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 64, 43268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 0, 43368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 8, 43468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 1, 43568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 2, 43668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1802, 437a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 438a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 43968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1801ao", 44068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 3000, 44168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 44268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 44368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 44468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 44568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 2, 44668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 2, 44768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1801, 448a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 449a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 45068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "das-1802ao", 45168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ai_speed = 3000, 45268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .resolution = 12, 45368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .qram_len = 256, 45468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .common = 1, 45568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .do_n_chan = 4, 45668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_ability = 2, 45768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .ao_n_chan = 2, 45868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .range_ai = &range_ai_das1802, 459a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess }, 460a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 461a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 462a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* 463a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * Useful for shorthand access to the particular board structure 464a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 465ce422cf3569444116d7d826b274bd59cc34d3b28Bill Pemberton#define thisboard ((const struct das1800_board *)dev->board_ptr) 466a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 4670c5a144d730a68967dfb3f8163260a142e3282e3Bill Pembertonstruct das1800_private { 468a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess volatile unsigned int count; /* number of data points left to be taken */ 469a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */ 470a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */ 471a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int do_bits; /* digital output bits */ 472a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int irq_dma_bits; /* bits for control register b */ 473a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* dma bits for control register b, stored so that dma can be 474a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * turned on and off */ 475a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int dma_bits; 476a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma0; /* dma channels used */ 477a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma1; 478a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess volatile unsigned int dma_current; /* dma channel currently in use */ 479a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess uint16_t *ai_buf0; /* pointers to dma buffers */ 480a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess uint16_t *ai_buf1; 481a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */ 482a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */ 483a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */ 484a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess short ao_update_bits; /* remembers the last write to the 'update' dac */ 4850c5a144d730a68967dfb3f8163260a142e3282e3Bill Pemberton}; 486a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 4870c5a144d730a68967dfb3f8163260a142e3282e3Bill Pemberton#define devpriv ((struct das1800_private *)dev->private) 488a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 489a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* analog out range for boards with basic analog out */ 4909ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_ao_1 = { 491a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1, 492a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 493a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-10, 10), 494a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 495a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 496a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 497a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* analog out range for 'ao' boards */ 498a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* 4999ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_ao_2 = { 500a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 2, 501a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 502a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-10, 10), 503a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-5, 5), 504a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 505a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 506a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess*/ 507a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 508139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_das1800 = { 50968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "das1800", 51068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 51168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = das1800_attach, 51268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = das1800_detach, 5138629efa4cbf6f89a54a85af4b8bc31762af01800Bill Pemberton .num_names = ARRAY_SIZE(das1800_boards), 51468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .board_name = &das1800_boards[0].name, 51568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .offset = sizeof(struct das1800_board), 516a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 517a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 518a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* 519a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * A convenient macro that defines init_module() and cleanup_module(), 520a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * as necessary. 521a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 522a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori HessCOMEDI_INITCLEANUP(driver_das1800); 523a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 524da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, 525a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma1) 526a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 527a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long flags; 528a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 529a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* need an irq to do dma */ 530a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->irq && dma0) { 531a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* encode dma0 and dma1 into 2 digit hexadecimal for switch */ 532a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch ((dma0 & 0x7) | (dma1 << 4)) { 533a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case 0x5: /* dma0 == 5 */ 534a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH5; 535a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 536a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case 0x6: /* dma0 == 6 */ 537a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH6; 538a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 539a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case 0x7: /* dma0 == 7 */ 540a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH7; 541a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 542a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case 0x65: /* dma0 == 5, dma1 == 6 */ 543a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH5_CH6; 544a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 545a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case 0x76: /* dma0 == 6, dma1 == 7 */ 546a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH6_CH7; 547a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 548a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case 0x57: /* dma0 == 7, dma1 == 5 */ 549a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH7_CH5; 550a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 551a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 552a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" only supports dma channels 5 through 7\n" 553a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess " Dual dma only allows the following combinations:\n" 554a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess " dma 5,6 / 6,7 / or 7,5\n"); 555a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 556a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 557a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 558a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (request_dma(dma0, driver_das1800.driver_name)) { 559a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" failed to allocate dma channel %i\n", dma0); 560a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 561a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 562a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma0 = dma0; 563a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = dma0; 564a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma1) { 565a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (request_dma(dma1, driver_das1800.driver_name)) { 566a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" failed to allocate dma channel %i\n", 567a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dma1); 568a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 569a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 570a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma1 = dma1; 571a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 572a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 573a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf0 == NULL) 574a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 575a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf0; 576a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma1) { 577a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->ai_buf1 = 578a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 579a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf1 == NULL) 580a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 581a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 582a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess flags = claim_dma_lock(); 583a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma0); 584a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_mode(devpriv->dma0, DMA_MODE_READ); 585a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma1) { 586a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma1); 587a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_mode(devpriv->dma1, DMA_MODE_READ); 588a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 589a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_dma_lock(flags); 590a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 591a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 592a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 593a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 594da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_attach(struct comedi_device *dev, struct comedi_devconfig *it) 595a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 59634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 597a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long iobase = it->options[0]; 598a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int irq = it->options[1]; 599a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma0 = it->options[2]; 600a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma1 = it->options[3]; 601a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long iobase2; 602a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int board; 603a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int retval; 604a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 605a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* allocate and initialize dev->private */ 6060c5a144d730a68967dfb3f8163260a142e3282e3Bill Pemberton if (alloc_private(dev, sizeof(struct das1800_private)) < 0) 607a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 608a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 609a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name, 610a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess iobase); 611a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (irq) { 612a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(", irq %u", irq); 613a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma0) { 614a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(", dma %u", dma0); 615a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma1) 616a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" and %u", dma1); 617a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 618a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 619a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk("\n"); 620a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 621a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (iobase == 0) { 622a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" io base address required\n"); 623a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 624a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 625a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 626a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* check if io addresses are available */ 627a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name)) { 628a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase, iobase + DAS1800_SIZE - 1); 629a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EIO; 630a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 631a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->iobase = iobase; 632a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 633a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess board = das1800_probe(dev); 634a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board < 0) { 635a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" unable to determine board type\n"); 636a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENODEV; 637a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 638a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 639a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->board_ptr = das1800_boards + board; 640a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->board_name = thisboard->name; 641a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 642a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* if it is an 'ao' board with fancy analog out then we need extra io ports */ 643a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (thisboard->ao_ability == 2) { 644a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess iobase2 = iobase + IOBASE2; 645a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!request_region(iobase2, DAS1800_SIZE, 646a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess driver_das1800.driver_name)) { 647a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase2, iobase2 + DAS1800_SIZE - 1); 648a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EIO; 649a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 650a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->iobase2 = iobase2; 651a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 652a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 653a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* grab our IRQ */ 654a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (irq) { 6555f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman if (request_irq(irq, das1800_interrupt, 0, 656a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess driver_das1800.driver_name, dev)) { 657a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" unable to allocate irq %u\n", irq); 658a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 659a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 660a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 661a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->irq = irq; 662a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 663a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* set bits that tell card which irq to use */ 664a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (irq) { 665a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0: 666a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 667a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 3: 668a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x8; 669a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 670a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 5: 671a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x10; 672a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 673a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 7: 674a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x18; 675a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 676a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 10: 677a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x28; 678a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 679a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 11: 680a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x30; 681a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 682a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 15: 683a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x38; 684a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 685a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 686a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" irq out of range\n"); 687a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 688a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 689a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 690a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 691a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess retval = das1800_init_dma(dev, dma0, dma1); 692a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (retval < 0) 693a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return retval; 694a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 695a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf0 == NULL) { 696a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->ai_buf0 = 697a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL); 698a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf0 == NULL) 699a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 700a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 701a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 702a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (alloc_subdevices(dev, 4) < 0) 703a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 704a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 705a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* analog input subdevice */ 706a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s = dev->subdevices + 0; 707a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->read_subdev = s; 708a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_AI; 709a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ; 710a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (thisboard->common) 711a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags |= SDF_COMMON; 712a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->n_chan = thisboard->qram_len; 713a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->len_chanlist = thisboard->qram_len; 714a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->maxdata = (1 << thisboard->resolution) - 1; 715a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->range_table = thisboard->range_ai; 716a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->do_cmd = das1800_ai_do_cmd; 717a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->do_cmdtest = das1800_ai_do_cmdtest; 718a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->insn_read = das1800_ai_rinsn; 719a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->poll = das1800_ai_poll; 720a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->cancel = das1800_cancel; 721a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 722a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* analog out */ 723a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s = dev->subdevices + 1; 724a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (thisboard->ao_ability == 1) { 725a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_AO; 726a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags = SDF_WRITABLE; 727a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->n_chan = thisboard->ao_n_chan; 728a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->maxdata = (1 << thisboard->resolution) - 1; 729a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->range_table = &range_ao_1; 730a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->insn_write = das1800_ao_winsn; 731a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 732a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_UNUSED; 733a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 734a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 735a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* di */ 736a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s = dev->subdevices + 2; 737a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_DI; 738a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags = SDF_READABLE; 739a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->n_chan = 4; 740a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->maxdata = 1; 741a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->range_table = &range_digital; 742a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->insn_bits = das1800_di_rbits; 743a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 744a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* do */ 745a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s = dev->subdevices + 3; 746a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_DO; 747a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags = SDF_WRITABLE | SDF_READABLE; 748a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->n_chan = thisboard->do_n_chan; 749a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->maxdata = 1; 750a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->range_table = &range_digital; 751a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->insn_bits = das1800_do_wbits; 752a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 753a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, dev->read_subdev); 754a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 755a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* initialize digital out channels */ 756a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL); 757a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 758a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* initialize analog out channels */ 759a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (thisboard->ao_ability == 1) { 760a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* select 'update' dac channel for baseAddress + 0x0 */ 761a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(DAC(thisboard->ao_n_chan - 1), 762a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->iobase + DAS1800_SELECT); 763a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 764a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 765a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 766a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 767a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 768a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 769da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_detach(struct comedi_device *dev) 770a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 771a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* only free stuff if it has been allocated by _attach */ 772a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->iobase) 773a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_region(dev->iobase, DAS1800_SIZE); 774a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->irq) 7755f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 776a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->private) { 777a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->iobase2) 778a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_region(devpriv->iobase2, DAS1800_SIZE); 779a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma0) 780a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess free_dma(devpriv->dma0); 781a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma1) 782a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess free_dma(devpriv->dma1); 783a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf0) 784a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess kfree(devpriv->ai_buf0); 785a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf1) 786a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess kfree(devpriv->ai_buf1); 787a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 788a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 789a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk("comedi%d: %s: remove\n", dev->minor, 790a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess driver_das1800.driver_name); 791a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 792a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 793a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 794a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 795a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* probes and checks das-1800 series board type 796a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 797da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_probe(struct comedi_device *dev) 798a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 799a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int id; 800a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int board; 801a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 802a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */ 803ce422cf3569444116d7d826b274bd59cc34d3b28Bill Pemberton board = ((struct das1800_board *) dev->board_ptr) - das1800_boards; 804a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 805a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (id) { 806a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x3: 807a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1801st_da || board == das1802st_da || 808a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess board == das1701st_da || board == das1702st_da) { 809a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 810a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_boards[board].name); 811a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 812a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 813a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model (probed, not recommended): das-1800st-da series\n"); 814a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1801st; 815a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 816a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x4: 817a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1802hr_da || board == das1702hr_da) { 818a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 819a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_boards[board].name); 820a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 821a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 822a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model (probed, not recommended): das-1802hr-da\n"); 823a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1802hr; 824a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 825a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x5: 826a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1801ao || board == das1802ao || 827a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess board == das1701ao || board == das1702ao) { 828a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 829a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_boards[board].name); 830a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 831a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 832a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model (probed, not recommended): das-1800ao series\n"); 833a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1801ao; 834a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 835a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x6: 836a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1802hr || board == das1702hr) { 837a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 838a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_boards[board].name); 839a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 840a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 841a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model (probed, not recommended): das-1802hr\n"); 842a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1802hr; 843a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 844a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x7: 845a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1801st || board == das1802st || 846a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess board == das1701st || board == das1702st) { 847a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 848a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_boards[board].name); 849a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 850a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 851a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model (probed, not recommended): das-1800st series\n"); 852a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1801st; 853a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 854a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x8: 855a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1801hc || board == das1802hc) { 856a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 857a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_boards[board].name); 858a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 859a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 860a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model (probed, not recommended): das-1800hc series\n"); 861a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1801hc; 862a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 863a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 864a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: probe returned 0x%x (unknown, please report)\n", id); 865a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 866a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 867a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 868a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 869a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 870a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 871da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) 872a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 873a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long flags; 874a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 875a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* prevent race with interrupt handler */ 8765f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 877a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_ai_handler(dev); 8785f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 879a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 880a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return s->async->buf_write_count - s->async->buf_read_count; 881a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 882a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 88370265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t das1800_interrupt(int irq, void *d) 884a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 88571b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton struct comedi_device *dev = d; 886a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int status; 887a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 888a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->attached == 0) { 889a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, "premature interrupt"); 890a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return IRQ_HANDLED; 891a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 892a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 893a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* Prevent race with das1800_ai_poll() on multi processor systems. 894a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * Also protects indirect addressing in das1800_ai_handler */ 895a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess spin_lock(&dev->spinlock); 896a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess status = inb(dev->iobase + DAS1800_STATUS); 897a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 898a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if interrupt was not caused by das-1800 */ 899a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!(status & INT)) { 900a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess spin_unlock(&dev->spinlock); 901a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return IRQ_NONE; 902a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 903a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* clear the interrupt status bit INT */ 904a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS); 905a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* handle interrupt */ 906a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_ai_handler(dev); 907a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 908a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess spin_unlock(&dev->spinlock); 909a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return IRQ_HANDLED; 910a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 911a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 912a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* the guts of the interrupt handler, that is shared with das1800_ai_poll */ 913da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void das1800_ai_handler(struct comedi_device *dev) 914a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 91534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */ 916d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 917ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &async->cmd; 918a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int status = inb(dev->iobase + DAS1800_STATUS); 919a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 920a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events = 0; 921a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* select adc for base address + 0 */ 922a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(ADC, dev->iobase + DAS1800_SELECT); 923a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* dma buffer full */ 924a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->irq_dma_bits & DMA_ENABLED) { 925a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* look for data from dma transfer even if dma terminal count hasn't happened yet */ 926a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_dma(dev, s, status); 927a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton } else if (status & FHF) { /* if fifo half full */ 928a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_fifo_half_full(dev, s); 929a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton } else if (status & FNE) { /* if fifo not empty */ 930a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_fifo_not_empty(dev, s); 931a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 932a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 933a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events |= COMEDI_CB_BLOCK; 934a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if the card's fifo has overflowed */ 935a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (status & OVF) { 936a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* clear OVF interrupt bit */ 937a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS); 938a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, "DAS1800 FIFO overflow"); 939a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, s); 940a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 941a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_event(dev, s); 942a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 943a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 944a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* stop taking data if appropriate */ 945a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* stop_src TRIG_EXT */ 946a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (status & CT0TC) { 947a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* clear CT0TC interrupt bit */ 948a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS); 949a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* make sure we get all remaining data from board before quitting */ 950a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->irq_dma_bits & DMA_ENABLED) 951a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_flush_dma(dev, s); 952a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess else 953a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_fifo_not_empty(dev, s); 954a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, s); /* disable hardware conversions */ 955a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events |= COMEDI_CB_EOA; 956a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */ 957a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, s); /* disable hardware conversions */ 958a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events |= COMEDI_CB_EOA; 959a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 960a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 961a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_event(dev, s); 962a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 963a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 964a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 965a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 966da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void das1800_handle_dma(struct comedi_device *dev, struct comedi_subdevice *s, 967a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int status) 968a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 969a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long flags; 970a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 971a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 972a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess flags = claim_dma_lock(); 973a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_flush_dma_channel(dev, s, devpriv->dma_current, 974a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf); 975a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* re-enable dma channel */ 976a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_addr(devpriv->dma_current, 977a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess virt_to_bus(devpriv->dma_current_buf)); 978a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size); 979a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess enable_dma(devpriv->dma_current); 980a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_dma_lock(flags); 981a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 982a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (status & DMATC) { 983a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* clear DMATC interrupt bit */ 984a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS); 985a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* switch dma channels for next time, if appropriate */ 986a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dual_dma) { 987a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* read data from the other channel next time */ 988a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma_current == devpriv->dma0) { 989a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma1; 990a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf1; 991a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 992a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma0; 993a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf0; 994a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 995a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 996a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 997a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 998a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 999a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1000a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1001da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic inline uint16_t munge_bipolar_sample(const struct comedi_device *dev, 1002a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess uint16_t sample) 1003a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1004a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess sample += 1 << (thisboard->resolution - 1); 1005a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return sample; 1006a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1007a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1008da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void munge_data(struct comedi_device *dev, uint16_t *array, 1009a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int num_elements) 1010a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1011a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int i; 1012a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int unipolar; 1013a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1014a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* see if card is using a unipolar or bipolar range so we can munge data correctly */ 1015a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 1016a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1017a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* convert to unsigned type if we are in a bipolar mode */ 1018a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!unipolar) { 1019a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (i = 0; i < num_elements; i++) { 1020a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess array[i] = munge_bipolar_sample(dev, array[i]); 1021a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1022a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1023a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1024a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1025a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* Utility function used by das1800_flush_dma() and das1800_handle_dma(). 1026a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * Assumes dma lock is held */ 1027da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void das1800_flush_dma_channel(struct comedi_device *dev, struct comedi_subdevice *s, 1028da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton unsigned int channel, uint16_t *buffer) 1029a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1030a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int num_bytes, num_samples; 1031ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 1032a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1033a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(channel); 1034a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1035a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* clear flip-flop to make sure 2-byte registers 1036a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * get set correctly */ 1037a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess clear_dma_ff(channel); 1038a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1039a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* figure out how many points to read */ 1040a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel); 1041790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton num_samples = num_bytes / sizeof(short); 1042a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1043a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if we only need some of the points */ 1044a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples) 1045a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess num_samples = devpriv->count; 1046a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1047a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess munge_data(dev, buffer, num_samples); 1048a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cfc_write_array_to_buffer(s, buffer, num_bytes); 1049a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (s->async->cmd.stop_src == TRIG_COUNT) 1050a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->count -= num_samples; 1051a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1052a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1053a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1054a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1055a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* flushes remaining data from board when external trigger has stopped aquisition 1056a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * and we are using dma transfers */ 1057da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void das1800_flush_dma(struct comedi_device *dev, struct comedi_subdevice *s) 1058a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1059a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long flags; 1060a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1061a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1062a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess flags = claim_dma_lock(); 1063a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_flush_dma_channel(dev, s, devpriv->dma_current, 1064a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf); 1065a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1066a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dual_dma) { 1067a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* switch to other channel and flush it */ 1068a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma_current == devpriv->dma0) { 1069a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma1; 1070a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf1; 1071a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 1072a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma0; 1073a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf0; 1074a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1075a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_flush_dma_channel(dev, s, devpriv->dma_current, 1076a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf); 1077a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1078a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1079a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_dma_lock(flags); 1080a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1081a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* get any remaining samples in fifo */ 1082a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_fifo_not_empty(dev, s); 1083a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1084a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1085a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1086a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1087da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void das1800_handle_fifo_half_full(struct comedi_device *dev, 1088da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_subdevice *s) 1089a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1090a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int numPoints = 0; /* number of points to read */ 1091ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 1092a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1093a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess numPoints = FIFO_SIZE / 2; 1094a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if we only need some of the points */ 1095a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints) 1096a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess numPoints = devpriv->count; 1097a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints); 1098a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess munge_data(dev, devpriv->ai_buf0, numPoints); 1099a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cfc_write_array_to_buffer(s, devpriv->ai_buf0, 1100a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess numPoints * sizeof(devpriv->ai_buf0[0])); 1101a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT) 1102a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->count -= numPoints; 1103a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1104a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1105a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1106da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void das1800_handle_fifo_not_empty(struct comedi_device *dev, 1107da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_subdevice *s) 1108a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1109790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short dpnt; 1110a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int unipolar; 1111ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 1112a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1113a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 1114a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1115a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess while (inb(dev->iobase + DAS1800_STATUS) & FNE) { 1116a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) 1117a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1118a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dpnt = inw(dev->iobase + DAS1800_FIFO); 1119a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* convert to unsigned type if we are in a bipolar mode */ 1120a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!unipolar) ; 1121a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dpnt = munge_bipolar_sample(dev, dpnt); 1122a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cfc_write_to_buffer(s, dpnt); 1123a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT) 1124a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->count--; 1125a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1126a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1127a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1128a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1129a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1130da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 1131a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1132a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ 1133a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ 1134a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ 1135a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma0) 1136a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma0); 1137a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma1) 1138a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma1); 1139a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1140a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1141a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1142a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* test analog input cmd */ 1143da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, 1144da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_cmd *cmd) 1145a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1146a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int err = 0; 1147a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int tmp; 1148a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int tmp_arg; 1149a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int i; 1150a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int unipolar; 1151a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1152a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* step 1: make sure trigger sources are trivially valid */ 1153a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1154a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->start_src; 1155a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->start_src &= TRIG_NOW | TRIG_EXT; 1156a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->start_src || tmp != cmd->start_src) 1157a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1158a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1159a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->scan_begin_src; 1160a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; 1161a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 1162a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1163a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1164a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->convert_src; 1165a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->convert_src &= TRIG_TIMER | TRIG_EXT; 1166a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->convert_src || tmp != cmd->convert_src) 1167a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1168a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1169a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->scan_end_src; 1170a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_end_src &= TRIG_COUNT; 1171a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 1172a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1173a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1174a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->stop_src; 1175a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE; 1176a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->stop_src || tmp != cmd->stop_src) 1177a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1178a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1179a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1180a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 1; 1181a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1182a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* step 2: make sure trigger sources are unique and mutually compatible */ 1183a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1184a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* uniqueness check */ 1185a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) 1186a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1187a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_begin_src != TRIG_FOLLOW && 1188a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_begin_src != TRIG_TIMER && 1189a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_begin_src != TRIG_EXT) 1190a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1191a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) 1192a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1193a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src != TRIG_COUNT && 1194a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT) 1195a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1196a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* compatibility check */ 1197a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_begin_src != TRIG_FOLLOW && 1198a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->convert_src != TRIG_TIMER) 1199a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1200a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1201a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1202a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 2; 1203a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1204a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* step 3: make sure arguments are trivially compatible */ 1205a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1206a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->start_arg != 0) { 1207a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->start_arg = 0; 1208a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1209a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1210a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_src == TRIG_TIMER) { 1211a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_arg < thisboard->ai_speed) { 1212a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->convert_arg = thisboard->ai_speed; 1213a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1214a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1215a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1216a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->chanlist_len) { 1217a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->chanlist_len = 1; 1218a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1219a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1220a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_end_arg != cmd->chanlist_len) { 1221a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_end_arg = cmd->chanlist_len; 1222a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1223a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1224a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1225a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd->stop_src) { 1226a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_COUNT: 1227a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->stop_arg) { 1228a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->stop_arg = 1; 1229a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1230a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1231a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1232a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_NONE: 1233a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_arg != 0) { 1234a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->stop_arg = 0; 1235a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1236a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1237a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1238a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1239a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1240a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1241a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1242a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1243a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 3; 1244a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1245a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* step 4: fix up any arguments */ 1246a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1247a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_src == TRIG_TIMER) { 1248a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* if we are not in burst mode */ 1249a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_begin_src == TRIG_FOLLOW) { 1250a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp_arg = cmd->convert_arg; 1251a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* calculate counter values that give desired timing */ 1252a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1253a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(devpriv->divisor1), &(devpriv->divisor2), 1254a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(cmd->convert_arg), 1255a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->flags & TRIG_ROUND_MASK); 1256a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (tmp_arg != cmd->convert_arg) 1257a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1258a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1259a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* if we are in burst mode */ 1260a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess else { 1261a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* check that convert_arg is compatible */ 1262a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp_arg = cmd->convert_arg; 1263a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->convert_arg = 1264a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess burst_convert_arg(cmd->convert_arg, 1265a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->flags & TRIG_ROUND_MASK); 1266a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (tmp_arg != cmd->convert_arg) 1267a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1268a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1269a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_begin_src == TRIG_TIMER) { 1270a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* if scans are timed faster than conversion rate allows */ 1271a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_arg * cmd->chanlist_len > 1272a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_begin_arg) { 1273a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_begin_arg = 1274a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->convert_arg * 1275a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->chanlist_len; 1276a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1277a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1278a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp_arg = cmd->scan_begin_arg; 1279a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* calculate counter values that give desired timing */ 1280a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1281a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(devpriv->divisor1), 1282a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(devpriv->divisor2), 1283a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(cmd->scan_begin_arg), 1284a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->flags & TRIG_ROUND_MASK); 1285a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (tmp_arg != cmd->scan_begin_arg) 1286a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1287a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1288a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1289a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1290a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1291a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1292a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 4; 1293a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1294a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* make sure user is not trying to mix unipolar and bipolar ranges */ 1295a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->chanlist) { 1296a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR; 1297a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (i = 1; i < cmd->chanlist_len; i++) { 1298a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) { 1299a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, 1300a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess "unipolar and bipolar ranges cannot be mixed in the chanlist"); 1301a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1302a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1303a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1304a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1305a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1306a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1307a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1308a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 5; 1309a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1310a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1311a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1312a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1313a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* analog input cmd interface */ 1314a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1315a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* first, some utility functions used in the main ai_do_cmd() */ 1316a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1317a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* returns appropriate bits for control register a, depending on command */ 1318ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pembertonstatic int control_a_bits(struct comedi_cmd cmd) 1319a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1320a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int control_a; 1321a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1322a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton control_a = FFEN; /* enable fifo */ 1323a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.stop_src == TRIG_EXT) { 1324a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_a |= ATEN; 1325a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1326a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd.start_src) { 1327a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_EXT: 1328a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_a |= TGEN | CGSL; 1329a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1330a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_NOW: 1331a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_a |= CGEN; 1332a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1333a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1334a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1335a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1336a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1337a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return control_a; 1338a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1339a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1340a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* returns appropriate bits for control register c, depending on command */ 1341ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pembertonstatic int control_c_bits(struct comedi_cmd cmd) 1342a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1343a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int control_c; 1344a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int aref; 1345a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1346a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* set clock source to internal or external, select analog reference, 1347a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * select unipolar / bipolar 1348a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 1349a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess aref = CR_AREF(cmd.chanlist[0]); 1350a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton control_c = UQEN; /* enable upper qram addresses */ 1351a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (aref != AREF_DIFF) 1352a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= SD; 1353a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (aref == AREF_COMMON) 1354a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= CMEN; 1355a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if a unipolar range was selected */ 1356a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR) 1357a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= UB; 1358a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd.scan_begin_src) { 1359a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case TRIG_FOLLOW: /* not in burst mode */ 1360a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd.convert_src) { 1361a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_TIMER: 1362a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* trig on cascaded counters */ 1363a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= IPCLK; 1364a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1365a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_EXT: 1366a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* trig on falling edge of external trigger */ 1367a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= XPCLK; 1368a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1369a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1370a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1371a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1372a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1373a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_TIMER: 1374a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* burst mode with internal pacer clock */ 1375a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= BMDE | IPCLK; 1376a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1377a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_EXT: 1378a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* burst mode with external trigger */ 1379a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= BMDE | XPCLK; 1380a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1381a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1382a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1383a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1384a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1385a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return control_c; 1386a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1387a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1388a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* sets up counters */ 1389da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd) 1390a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1391a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* setup cascaded counters for conversion/scan frequency */ 1392a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd.scan_begin_src) { 1393a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case TRIG_FOLLOW: /* not in burst mode */ 1394a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.convert_src == TRIG_TIMER) { 1395a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* set conversion frequency */ 1396a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1397a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(devpriv->divisor1), &(devpriv->divisor2), 1398a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(cmd.convert_arg), 1399a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd.flags & TRIG_ROUND_MASK); 1400a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (das1800_set_frequency(dev) < 0) { 1401a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 1402a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1403a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1404a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1405a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case TRIG_TIMER: /* in burst mode */ 1406a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* set scan frequency */ 1407a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), 1408a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess &(devpriv->divisor2), &(cmd.scan_begin_arg), 1409a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd.flags & TRIG_ROUND_MASK); 1410a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (das1800_set_frequency(dev) < 0) { 1411a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 1412a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1413a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1414a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1415a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1416a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1417a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1418a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* setup counter 0 for 'about triggering' */ 1419a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.stop_src == TRIG_EXT) { 1420a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* load counter 0 in mode 0 */ 1421a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0); 1422a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1423a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1424a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1425a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1426a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1427a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* sets up dma */ 1428da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd) 1429a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1430a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long lock_flags; 1431a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1432a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1433a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0) 1434a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1435a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1436a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* determine a reasonable dma transfer size */ 1437a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_transfer_size = suggest_transfer_size(&cmd); 1438a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess lock_flags = claim_dma_lock(); 1439a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma0); 1440a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* clear flip-flop to make sure 2-byte registers for 1441a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * count and address get set correctly */ 1442a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess clear_dma_ff(devpriv->dma0); 1443a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0)); 1444a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* set appropriate size of transfer */ 1445a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_count(devpriv->dma0, devpriv->dma_transfer_size); 1446a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma0; 1447a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf0; 1448a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess enable_dma(devpriv->dma0); 1449a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* set up dual dma if appropriate */ 1450a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dual_dma) { 1451a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma1); 1452a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* clear flip-flop to make sure 2-byte registers for 1453a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * count and address get set correctly */ 1454a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess clear_dma_ff(devpriv->dma1); 1455a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1)); 1456a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* set appropriate size of transfer */ 1457a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_count(devpriv->dma1, devpriv->dma_transfer_size); 1458a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess enable_dma(devpriv->dma1); 1459a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1460a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_dma_lock(lock_flags); 1461a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1462a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1463a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1464a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1465a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* programs channel/gain list into card */ 1466da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd) 1467a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1468a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int i, n, chan_range; 1469a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long irq_flags; 1470a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */ 1471a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const int range_bitshift = 8; 1472a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1473a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess n = cmd.chanlist_len; 1474a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* spinlock protects indirect addressing */ 14755f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, irq_flags); 1476a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1477a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */ 1478a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* make channel / gain list */ 1479a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (i = 0; i < n; i++) { 1480a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess chan_range = 1481a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess CR_CHAN(cmd.chanlist[i]) | ((CR_RANGE(cmd. 1482a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess chanlist[i]) & range_mask) << 1483a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range_bitshift); 1484a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(chan_range, dev->iobase + DAS1800_QRAM); 1485a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1486a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 14875f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1488a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1489a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1490a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1491a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1492a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* analog input do_cmd */ 1493da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 1494a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1495a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int ret; 1496a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int control_a, control_c; 1497d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1498ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd cmd = async->cmd; 1499a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1500a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!dev->irq) { 1501a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, 1502a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess "no irq assigned for das-1800, cannot do hardware conversions"); 1503a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 1504a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1505a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1506a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* disable dma on TRIG_WAKE_EOS, or TRIG_RT 1507a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * (because dma in handler is unsafe at hard real-time priority) */ 1508a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) { 1509a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits &= ~DMA_ENABLED; 1510a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 1511a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= devpriv->dma_bits; 1512a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1513a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* interrupt on end of conversion for TRIG_WAKE_EOS */ 1514a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.flags & TRIG_WAKE_EOS) { 1515a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* interrupt fifo not empty */ 1516a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits &= ~FIMD; 1517a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 1518a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* interrupt fifo half full */ 1519a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= FIMD; 1520a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1521a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* determine how many conversions we need */ 1522a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.stop_src == TRIG_COUNT) { 1523a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->count = cmd.stop_arg * cmd.chanlist_len; 1524a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1525a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1526a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, s); 1527a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1528a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* determine proper bits for control registers */ 1529a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_a = control_a_bits(cmd); 1530a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c = control_c_bits(cmd); 1531a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1532a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* setup card and start */ 1533a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess program_chanlist(dev, cmd); 1534a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ret = setup_counters(dev, cmd); 1535a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (ret < 0) { 1536a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, "Error setting up counters"); 1537a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return ret; 1538a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1539a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess setup_dma(dev, cmd); 1540a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(control_c, dev->iobase + DAS1800_CONTROL_C); 1541a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* set conversion rate and length for burst mode */ 1542a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (control_c & BMDE) { 1543a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* program conversion period with number of microseconds minus 1 */ 1544a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(cmd.convert_arg / 1000 - 1, 1545a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->iobase + DAS1800_BURST_RATE); 1546a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH); 1547a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1548a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */ 1549a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */ 1550a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1551a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1552a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1553a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1554a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1555a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* read analog input */ 1556da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, 1557da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 1558a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1559a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int i, n; 1560a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int chan, range, aref, chan_range; 1561a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int timeout = 1000; 1562a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess short dpnt; 1563a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int conv_flags = 0; 1564a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long irq_flags; 1565a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1566a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* set up analog reference and unipolar / bipolar mode */ 1567a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess aref = CR_AREF(insn->chanspec); 1568a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess conv_flags |= UQEN; 1569a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (aref != AREF_DIFF) 1570a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess conv_flags |= SD; 1571a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (aref == AREF_COMMON) 1572a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess conv_flags |= CMEN; 1573a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if a unipolar range was selected */ 1574a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (CR_RANGE(insn->chanspec) & UNIPOLAR) 1575a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess conv_flags |= UB; 1576a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1577a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */ 1578a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1579a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */ 1580a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(FFEN, dev->iobase + DAS1800_CONTROL_A); 1581a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1582a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess chan = CR_CHAN(insn->chanspec); 1583a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* mask of unipolar/bipolar bit from range */ 1584a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range = CR_RANGE(insn->chanspec) & 0x3; 1585a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess chan_range = chan | (range << 8); 15865f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, irq_flags); 1587a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1588a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */ 1589a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(chan_range, dev->iobase + DAS1800_QRAM); 1590a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1591a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */ 1592a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1593a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (n = 0; n < insn->n; n++) { 1594a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* trigger conversion */ 1595a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0, dev->iobase + DAS1800_FIFO); 1596a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (i = 0; i < timeout; i++) { 1597a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (inb(dev->iobase + DAS1800_STATUS) & FNE) 1598a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1599a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1600a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (i == timeout) { 1601a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, "timeout"); 1602a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ETIME; 1603a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1604a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dpnt = inw(dev->iobase + DAS1800_FIFO); 1605a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* shift data to offset binary for bipolar ranges */ 1606a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if ((conv_flags & UB) == 0) 1607a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dpnt += 1 << (thisboard->resolution - 1); 1608a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[n] = dpnt; 1609a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 16105f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1611a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1612a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return n; 1613a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1614a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1615a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* writes to an analog output channel */ 1616da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, 1617da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 1618a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1619a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int chan = CR_CHAN(insn->chanspec); 1620a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* int range = CR_RANGE(insn->chanspec); */ 1621a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int update_chan = thisboard->ao_n_chan - 1; 1622a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess short output; 1623a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long irq_flags; 1624a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1625a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* card expects two's complement data */ 1626a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess output = data[0] - (1 << (thisboard->resolution - 1)); 1627a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* if the write is to the 'update' channel, we need to remember its value */ 1628a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (chan == update_chan) 1629a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->ao_update_bits = output; 1630a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* write to channel */ 16315f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, irq_flags); 1632a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */ 1633a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(output, dev->iobase + DAS1800_DAC); 1634a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* now we need to write to 'update' channel to update all dac channels */ 1635a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (chan != update_chan) { 1636a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */ 1637a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 1638a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 16395f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1640a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1641a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 1; 1642a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1643a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1644a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* reads from digital input channels */ 1645da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, 1646da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 1647a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1648a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1649a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf; 1650a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[0] = 0; 1651a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1652a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 2; 1653a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1654a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1655a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* writes to digital output channels */ 1656da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, 1657da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 1658a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1659790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int wbits; 1660a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1661a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* only set bits that have been masked */ 1662a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[0] &= (1 << s->n_chan) - 1; 1663a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess wbits = devpriv->do_bits; 1664a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess wbits &= ~data[0]; 1665a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess wbits |= data[0] & data[1]; 1666a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->do_bits = wbits; 1667a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1668a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL); 1669a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1670a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[1] = devpriv->do_bits; 1671a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1672a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 2; 1673a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1674a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1675a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* loads counters with divisor1, divisor2 from private structure */ 1676da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_set_frequency(struct comedi_device *dev) 1677a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1678a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int err = 0; 1679a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1680a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* counter 1, mode 2 */ 1681a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1, 1682a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 2)) 1683a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1684a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* counter 2, mode 2 */ 1685a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2, 1686a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 2)) 1687a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1688a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1689a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 1690a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1691a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1692a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1693a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1694a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* converts requested conversion timing to timing compatible with 1695a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * hardware, used only when card is in 'burst mode' 1696a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 1697a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessstatic unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode) 1698a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1699a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int micro_sec; 1700a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1701a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* in burst mode, the maximum conversion time is 64 microseconds */ 1702a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (convert_arg > 64000) 1703a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess convert_arg = 64000; 1704a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1705a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* the conversion time must be an integral number of microseconds */ 1706a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (round_mode) { 1707a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_ROUND_NEAREST: 1708a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1709a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess micro_sec = (convert_arg + 500) / 1000; 1710a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1711a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_ROUND_DOWN: 1712a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess micro_sec = convert_arg / 1000; 1713a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1714a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_ROUND_UP: 1715a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess micro_sec = (convert_arg - 1) / 1000 + 1; 1716a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1717a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1718a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1719a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* return number of nanoseconds */ 1720a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return micro_sec * 1000; 1721a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1722a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1723a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* utility function that suggests a dma transfer size based on the conversion period 'ns' */ 1724da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic unsigned int suggest_transfer_size(struct comedi_cmd *cmd) 1725a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1726a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int size = DMA_BUF_SIZE; 1727a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton static const int sample_size = 2; /* size in bytes of one sample from board */ 1728a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */ 1729a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton unsigned int max_size; /* maximum size we will allow for a transfer */ 1730a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1731a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* make dma buffer fill in 0.3 seconds for timed modes */ 1732a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd->scan_begin_src) { 1733a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case TRIG_FOLLOW: /* not in burst mode */ 1734a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_src == TRIG_TIMER) 1735a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = (fill_time / cmd->convert_arg) * sample_size; 1736a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1737a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_TIMER: 1738a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) * 1739a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess sample_size; 1740a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1741a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1742a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = DMA_BUF_SIZE; 1743a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1744a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1745a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1746a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* set a minimum and maximum size allowed */ 1747a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess max_size = DMA_BUF_SIZE; 1748a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* if we are taking limited number of conversions, limit transfer size to that */ 1749a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT && 1750a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->stop_arg * cmd->chanlist_len * sample_size < max_size) 1751a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess max_size = cmd->stop_arg * cmd->chanlist_len * sample_size; 1752a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1753a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (size > max_size) 1754a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = max_size; 1755a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (size < sample_size) 1756a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = sample_size; 1757a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1758a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return size; 1759a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1760