das1800.c revision 7114a28011f9d5f3d981731ad341177c21f9d948
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> 1045a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 105a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include "../comedidev.h" 106a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 107a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include <linux/ioport.h> 108a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include <asm/dma.h> 109a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 110a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include "8253.h" 111a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#include "comedi_fc.h" 112a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 113a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* misc. defines */ 114a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define DAS1800_SIZE 16 /* uses 16 io addresses */ 115a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define FIFO_SIZE 1024 /* 1024 sample fifo */ 116a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define TIMER_BASE 200 /* 5 Mhz master clock */ 117a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define UNIPOLAR 0x4 /* bit that determines whether input range is uni/bipolar */ 118a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define DMA_BUF_SIZE 0x1ff00 /* size in bytes of dma buffers */ 119a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 120a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* Registers for the das1800 */ 121a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_FIFO 0x0 122a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_QRAM 0x0 123a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_DAC 0x0 124a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_SELECT 0x2 125a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define ADC 0x0 126a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define QRAM 0x1 127a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAC(a) (0x2 + a) 128a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_DIGITAL 0x3 129a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_CONTROL_A 0x4 130a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define FFEN 0x1 131a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CGEN 0x4 132a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CGSL 0x8 133a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define TGEN 0x10 134a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define TGSL 0x20 135a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define ATEN 0x80 136a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_CONTROL_B 0x5 137a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH5 0x1 138a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH6 0x2 139a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH7 0x3 140a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH5_CH6 0x5 141a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH6_CH7 0x6 142a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_CH7_CH5 0x7 143a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define DMA_ENABLED 0x3 /* mask used to determine if dma is enabled */ 144a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMA_DUAL 0x4 145a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ3 0x8 146a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ5 0x10 147a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ7 0x18 148a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ10 0x28 149a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ11 0x30 150a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IRQ15 0x38 151a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define FIMD 0x40 152a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_CONTROL_C 0X6 153a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define IPCLK 0x1 154a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define XPCLK 0x3 155a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define BMDE 0x4 156a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CMEN 0x8 157a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define UQEN 0x10 158a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define SD 0x40 159a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define UB 0x80 160a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_STATUS 0x7 161a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* bits that prevent interrupt status bits (and CVEN) from being cleared on write */ 162a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CLEAR_INTR_MASK (CVEN_MASK | 0x1f) 163a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define INT 0x1 164a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DMATC 0x2 165a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CT0TC 0x8 166a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define OVF 0x10 167a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define FHF 0x20 168a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define FNE 0x40 169a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define CVEN_MASK 0x40 /* masks CVEN on write */ 170a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define CVEN 0x80 171a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_BURST_LENGTH 0x8 172a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_BURST_RATE 0x9 173a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_QRAM_ADDRESS 0xa 174a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess#define DAS1800_COUNTER 0xc 175a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 176a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton#define IOBASE2 0x400 /* offset of additional ioports used on 'ao' cards */ 177a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 178a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessenum { 179a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1701st, das1701st_da, das1702st, das1702st_da, das1702hr, 180a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1702hr_da, 181a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da, 182a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao 183a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 184a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_attach(struct comedi_device *dev, 1860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 187814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_detach(struct comedi_device *dev); 188814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_probe(struct comedi_device *dev); 1890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_cancel(struct comedi_device *dev, 1900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 19170265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t das1800_interrupt(int irq, void *d); 1920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_ai_poll(struct comedi_device *dev, 1930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 194814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void das1800_ai_handler(struct comedi_device *dev); 1950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void das1800_handle_dma(struct comedi_device *dev, 1960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, unsigned int status); 1970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void das1800_flush_dma(struct comedi_device *dev, 1980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 1990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void das1800_flush_dma_channel(struct comedi_device *dev, 2000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 2010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int channel, uint16_t * buffer); 202814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void das1800_handle_fifo_half_full(struct comedi_device *dev, 2030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 204814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void das1800_handle_fifo_not_empty(struct comedi_device *dev, 2050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 2060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_ai_do_cmdtest(struct comedi_device *dev, 2070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 2080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd); 2090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_ai_do_cmd(struct comedi_device *dev, 2100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 2110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_ai_rinsn(struct comedi_device *dev, 2120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 2130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 2140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_ao_winsn(struct comedi_device *dev, 2150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 2160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 2170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_di_rbits(struct comedi_device *dev, 2180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 2190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 2200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_do_wbits(struct comedi_device *dev, 2210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 2220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 223814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton 224814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int das1800_set_frequency(struct comedi_device *dev); 225a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessstatic unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode); 226814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic unsigned int suggest_transfer_size(struct comedi_cmd *cmd); 227a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 228a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* analog input ranges */ 2299ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_ai_das1801 = { 230a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 8, 231a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 2320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-5, 5), 2330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-1, 1), 2340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-0.1, 0.1), 2350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-0.02, 0.02), 2360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(0, 5), 2370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(0, 1), 2380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(0, 0.1), 2390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(0, 0.02), 2400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 241a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 242a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 2439ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_ai_das1802 = { 244a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 8, 245a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 2460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-10, 10), 2470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-5, 5), 2480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-2.5, 2.5), 2490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-1.25, 1.25), 2500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(0, 10), 2510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(0, 5), 2520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(0, 2.5), 2530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(0, 1.25), 2540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 255a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 256a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 257ce422cf3569444116d7d826b274bd59cc34d3b28Bill Pembertonstruct das1800_board { 258a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const char *name; 259a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int ai_speed; /* max conversion period in nanoseconds */ 260a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int resolution; /* bits of ai resolution */ 261a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int qram_len; /* length of card's channel / gain queue */ 262a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int common; /* supports AREF_COMMON flag */ 263a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int do_n_chan; /* number of digital output channels */ 264a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */ 265a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int ao_n_chan; /* number of analog out channels */ 2669ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pemberton const struct comedi_lrange *range_ai; /* available input ranges */ 267ce422cf3569444116d7d826b274bd59cc34d3b28Bill Pemberton}; 268a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 269a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* Warning: the maximum conversion speeds listed below are 270a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * not always achievable depending on board setup (see 271a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * user manual.) 272a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 273ce422cf3569444116d7d826b274bd59cc34d3b28Bill Pembertonstatic const struct das1800_board das1800_boards[] = { 274a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 2750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1701st", 2760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 6250, 2770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 2780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 2790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 2800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 2810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 0, 2820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 0, 2830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1801, 2840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 285a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 2860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1701st-da", 2870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 6250, 2880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 2890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 2900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 2910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 2920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 1, 2930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 4, 2940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1801, 2950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 296a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 2970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1702st", 2980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 6250, 2990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 3000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 3010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 3020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 3030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 0, 3040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 0, 3050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1802, 3060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 307a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 3080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1702st-da", 3090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 6250, 3100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 3110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 3120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 3130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 3140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 1, 3150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 4, 3160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1802, 3170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 318a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 3190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1702hr", 3200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 20000, 3210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 16, 3220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 3230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 3240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 3250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 0, 3260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 0, 3270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1802, 3280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 329a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 3300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1702hr-da", 3310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 20000, 3320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 16, 3330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 3340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 3350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 3360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 1, 3370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 2, 3380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1802, 3390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 340a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 3410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1701ao", 3420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 6250, 3430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 3440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 3450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 3460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 3470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 2, 3480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 2, 3490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1801, 3500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 351a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 3520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1702ao", 3530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 6250, 3540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 3550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 3560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 3570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 3580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 2, 3590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 2, 3600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1802, 3610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 362a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 3630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1801st", 3640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3000, 3650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 3660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 3670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 3680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 3690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 0, 3700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 0, 3710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1801, 3720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 373a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 3740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1801st-da", 3750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3000, 3760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 3770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 3780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 3790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 3800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 0, 3810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 4, 3820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1801, 3830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 384a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 3850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1802st", 3860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3000, 3870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 3880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 3890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 3900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 3910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 0, 3920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 0, 3930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1802, 3940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 395a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 3960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1802st-da", 3970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3000, 3980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 3990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 4000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 4010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 4020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 1, 4030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 4, 4040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1802, 4050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 406a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 4070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1802hr", 4080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 10000, 4090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 16, 4100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 4110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 4120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 4130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 0, 4140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 0, 4150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1802, 4160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 417a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 4180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1802hr-da", 4190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 10000, 4200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 16, 4210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 4220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 4230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 4240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 1, 4250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 2, 4260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1802, 4270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 428a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 4290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1801hc", 4300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3000, 4310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 4320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 64, 4330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 0, 4340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 8, 4350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 1, 4360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 2, 4370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1801, 4380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 439a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 4400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1802hc", 4410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3000, 4420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 4430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 64, 4440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 0, 4450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 8, 4460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 1, 4470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 2, 4480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1802, 4490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 450a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 4510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1801ao", 4520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3000, 4530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 4540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 4550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 4560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 4570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 2, 4580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 2, 4590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1801, 4600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 461a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 4620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "das-1802ao", 4630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_speed = 3000, 4640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .resolution = 12, 4650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .qram_len = 256, 4660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .common = 1, 4670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .do_n_chan = 4, 4680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_ability = 2, 4690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_n_chan = 2, 4700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .range_ai = &range_ai_das1802, 4710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 472a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 473a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 474a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* 475a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * Useful for shorthand access to the particular board structure 476a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 477ce422cf3569444116d7d826b274bd59cc34d3b28Bill Pemberton#define thisboard ((const struct das1800_board *)dev->board_ptr) 478a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 4790c5a144d730a68967dfb3f8163260a142e3282e3Bill Pembertonstruct das1800_private { 480a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess volatile unsigned int count; /* number of data points left to be taken */ 481a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */ 482a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */ 483a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int do_bits; /* digital output bits */ 484a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int irq_dma_bits; /* bits for control register b */ 485a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* dma bits for control register b, stored so that dma can be 486a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * turned on and off */ 487a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int dma_bits; 488a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma0; /* dma channels used */ 489a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma1; 490a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess volatile unsigned int dma_current; /* dma channel currently in use */ 491a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess uint16_t *ai_buf0; /* pointers to dma buffers */ 492a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess uint16_t *ai_buf1; 493a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */ 494a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */ 495a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */ 496a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess short ao_update_bits; /* remembers the last write to the 'update' dac */ 4970c5a144d730a68967dfb3f8163260a142e3282e3Bill Pemberton}; 498a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 4990c5a144d730a68967dfb3f8163260a142e3282e3Bill Pemberton#define devpriv ((struct das1800_private *)dev->private) 500a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 501a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* analog out range for boards with basic analog out */ 5029ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_ao_1 = { 503a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1, 504a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 5050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-10, 10), 5060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 507a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 508a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 509a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* analog out range for 'ao' boards */ 510a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* 5119ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_ao_2 = { 512a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 2, 513a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess { 514a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-10, 10), 515a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess RANGE(-5, 5), 516a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 517a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 518a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess*/ 519a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 520139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_das1800 = { 52168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "das1800", 52268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 52368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = das1800_attach, 52468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = das1800_detach, 5258629efa4cbf6f89a54a85af4b8bc31762af01800Bill Pemberton .num_names = ARRAY_SIZE(das1800_boards), 52668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .board_name = &das1800_boards[0].name, 52768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .offset = sizeof(struct das1800_board), 528a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 529a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 530a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* 531a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * A convenient macro that defines init_module() and cleanup_module(), 532a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * as necessary. 533a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 5347114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic int __init driver_das1800_init_module(void) 5357114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{ 5367114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas return comedi_driver_register(&driver_das1800); 5377114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas} 5387114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas 5397114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic void __exit driver_das1800_cleanup_module(void) 5407114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{ 5417114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas comedi_driver_unregister(&driver_das1800); 5427114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas} 5437114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas 5447114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_init(driver_das1800_init_module); 5457114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_exit(driver_das1800_cleanup_module); 546a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 547da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, 5480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int dma1) 549a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 550a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long flags; 551a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 552a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* need an irq to do dma */ 553a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->irq && dma0) { 554a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* encode dma0 and dma1 into 2 digit hexadecimal for switch */ 555a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch ((dma0 & 0x7) | (dma1 << 4)) { 556a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case 0x5: /* dma0 == 5 */ 557a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH5; 558a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 559a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case 0x6: /* dma0 == 6 */ 560a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH6; 561a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 562a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case 0x7: /* dma0 == 7 */ 563a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH7; 564a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 565a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case 0x65: /* dma0 == 5, dma1 == 6 */ 566a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH5_CH6; 567a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 568a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case 0x76: /* dma0 == 6, dma1 == 7 */ 569a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH6_CH7; 570a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 571a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case 0x57: /* dma0 == 7, dma1 == 5 */ 572a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_bits |= DMA_CH7_CH5; 573a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 574a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 575a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" only supports dma channels 5 through 7\n" 5760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral " Dual dma only allows the following combinations:\n" 5770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral " dma 5,6 / 6,7 / or 7,5\n"); 578a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 579a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 580a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 581a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (request_dma(dma0, driver_das1800.driver_name)) { 582a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" failed to allocate dma channel %i\n", dma0); 583a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 584a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 585a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma0 = dma0; 586a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = dma0; 587a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma1) { 588a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (request_dma(dma1, driver_das1800.driver_name)) { 589a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" failed to allocate dma channel %i\n", 5900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dma1); 591a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 592a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 593a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma1 = dma1; 594a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 595a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 596a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf0 == NULL) 597a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 598a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf0; 599a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma1) { 600a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->ai_buf1 = 6010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 602a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf1 == NULL) 603a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 604a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 605a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess flags = claim_dma_lock(); 606a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma0); 607a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_mode(devpriv->dma0, DMA_MODE_READ); 608a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma1) { 609a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma1); 610a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_mode(devpriv->dma1, DMA_MODE_READ); 611a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 612a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_dma_lock(flags); 613a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 614a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 615a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 616a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 6170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_attach(struct comedi_device *dev, 6180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it) 619a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 62034c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 621a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long iobase = it->options[0]; 622a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int irq = it->options[1]; 623a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma0 = it->options[2]; 624a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int dma1 = it->options[3]; 625a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long iobase2; 626a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int board; 627a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int retval; 628a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 629a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* allocate and initialize dev->private */ 6300c5a144d730a68967dfb3f8163260a142e3282e3Bill Pemberton if (alloc_private(dev, sizeof(struct das1800_private)) < 0) 631a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 632a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 633a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name, 6340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral iobase); 635a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (irq) { 636a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(", irq %u", irq); 637a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma0) { 638a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(", dma %u", dma0); 639a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dma1) 640a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" and %u", dma1); 641a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 642a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 643a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk("\n"); 644a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 645a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (iobase == 0) { 646a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" io base address required\n"); 647a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 648a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 649a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 650a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* check if io addresses are available */ 651a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name)) { 6520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 6530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", 6540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral iobase, iobase + DAS1800_SIZE - 1); 655a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EIO; 656a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 657a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->iobase = iobase; 658a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 659a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess board = das1800_probe(dev); 660a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board < 0) { 661a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" unable to determine board type\n"); 662a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENODEV; 663a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 664a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 665a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->board_ptr = das1800_boards + board; 666a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->board_name = thisboard->name; 667a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 668a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* if it is an 'ao' board with fancy analog out then we need extra io ports */ 669a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (thisboard->ao_ability == 2) { 670a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess iobase2 = iobase + IOBASE2; 671a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!request_region(iobase2, DAS1800_SIZE, 6720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral driver_das1800.driver_name)) { 6730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 6740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", 6750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral iobase2, iobase2 + DAS1800_SIZE - 1); 676a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EIO; 677a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 678a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->iobase2 = iobase2; 679a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 680a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 681a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* grab our IRQ */ 682a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (irq) { 6835f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman if (request_irq(irq, das1800_interrupt, 0, 684a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess driver_das1800.driver_name, dev)) { 685a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" unable to allocate irq %u\n", irq); 686a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 687a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 688a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 689a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->irq = irq; 690a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 691a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* set bits that tell card which irq to use */ 692a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (irq) { 693a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0: 694a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 695a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 3: 696a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x8; 697a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 698a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 5: 699a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x10; 700a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 701a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 7: 702a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x18; 703a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 704a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 10: 705a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x28; 706a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 707a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 11: 708a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x30; 709a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 710a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 15: 711a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= 0x38; 712a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 713a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 714a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" irq out of range\n"); 715a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -EINVAL; 716a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 717a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 718a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 719a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess retval = das1800_init_dma(dev, dma0, dma1); 720a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (retval < 0) 721a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return retval; 722a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 723a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf0 == NULL) { 724a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->ai_buf0 = 7250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL); 726a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->ai_buf0 == NULL) 727a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 728a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 729a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 730a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (alloc_subdevices(dev, 4) < 0) 731a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -ENOMEM; 732a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 733a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* analog input subdevice */ 734a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s = dev->subdevices + 0; 735a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dev->read_subdev = s; 736a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_AI; 737a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ; 738a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (thisboard->common) 739a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags |= SDF_COMMON; 740a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->n_chan = thisboard->qram_len; 741a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->len_chanlist = thisboard->qram_len; 742a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->maxdata = (1 << thisboard->resolution) - 1; 743a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->range_table = thisboard->range_ai; 744a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->do_cmd = das1800_ai_do_cmd; 745a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->do_cmdtest = das1800_ai_do_cmdtest; 746a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->insn_read = das1800_ai_rinsn; 747a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->poll = das1800_ai_poll; 748a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->cancel = das1800_cancel; 749a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 750a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* analog out */ 751a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s = dev->subdevices + 1; 752a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (thisboard->ao_ability == 1) { 753a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_AO; 754a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags = SDF_WRITABLE; 755a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->n_chan = thisboard->ao_n_chan; 756a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->maxdata = (1 << thisboard->resolution) - 1; 757a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->range_table = &range_ao_1; 758a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->insn_write = das1800_ao_winsn; 759a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 760a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_UNUSED; 761a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 762a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 763a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* di */ 764a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s = dev->subdevices + 2; 765a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_DI; 766a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags = SDF_READABLE; 767a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->n_chan = 4; 768a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->maxdata = 1; 769a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->range_table = &range_digital; 770a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->insn_bits = das1800_di_rbits; 771a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 772a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* do */ 773a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s = dev->subdevices + 3; 774a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->type = COMEDI_SUBD_DO; 775a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->subdev_flags = SDF_WRITABLE | SDF_READABLE; 776a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->n_chan = thisboard->do_n_chan; 777a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->maxdata = 1; 778a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->range_table = &range_digital; 779a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess s->insn_bits = das1800_do_wbits; 780a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 781a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, dev->read_subdev); 782a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 783a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* initialize digital out channels */ 784a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL); 785a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 786a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* initialize analog out channels */ 787a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (thisboard->ao_ability == 1) { 788a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* select 'update' dac channel for baseAddress + 0x0 */ 789a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(DAC(thisboard->ao_n_chan - 1), 7900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->iobase + DAS1800_SELECT); 791a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 792a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 793a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 794a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 795a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 796a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 797da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_detach(struct comedi_device *dev) 798a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 799a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* only free stuff if it has been allocated by _attach */ 800a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->iobase) 801a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_region(dev->iobase, DAS1800_SIZE); 802a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->irq) 8035f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 804a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->private) { 805a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->iobase2) 806a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_region(devpriv->iobase2, DAS1800_SIZE); 807a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma0) 808a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess free_dma(devpriv->dma0); 809a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma1) 810a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess free_dma(devpriv->dma1); 8111bf2ee4ea19d3ebeb8fe35c03dd44cb1d851e19fDavid Binderman kfree(devpriv->ai_buf0); 8121bf2ee4ea19d3ebeb8fe35c03dd44cb1d851e19fDavid Binderman kfree(devpriv->ai_buf1); 813a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 814a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 815a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk("comedi%d: %s: remove\n", dev->minor, 8160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral driver_das1800.driver_name); 817a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 818a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 819a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess}; 820a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 821a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* probes and checks das-1800 series board type 822a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 823da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_probe(struct comedi_device *dev) 824a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 825a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int id; 826a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int board; 827a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 828a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */ 8290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral board = ((struct das1800_board *)dev->board_ptr) - das1800_boards; 830a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 831a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (id) { 832a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x3: 833a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1801st_da || board == das1802st_da || 8340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral board == das1701st_da || board == das1702st_da) { 835a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 8360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral das1800_boards[board].name); 837a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 838a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 8390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 8400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (" Board model (probed, not recommended): das-1800st-da series\n"); 841a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1801st; 842a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 843a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x4: 844a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1802hr_da || board == das1702hr_da) { 845a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 8460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral das1800_boards[board].name); 847a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 848a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 8490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 8500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (" Board model (probed, not recommended): das-1802hr-da\n"); 851a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1802hr; 852a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 853a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x5: 854a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1801ao || board == das1802ao || 8550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral board == das1701ao || board == das1702ao) { 856a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 8570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral das1800_boards[board].name); 858a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 859a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 8600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 8610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (" Board model (probed, not recommended): das-1800ao series\n"); 862a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1801ao; 863a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 864a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x6: 865a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1802hr || board == das1702hr) { 866a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 8670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral das1800_boards[board].name); 868a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 869a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 870a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model (probed, not recommended): das-1802hr\n"); 871a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1802hr; 872a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 873a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x7: 874a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1801st || board == das1802st || 8750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral board == das1701st || board == das1702st) { 876a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 8770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral das1800_boards[board].name); 878a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 879a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 8800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 8810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (" Board model (probed, not recommended): das-1800st series\n"); 882a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1801st; 883a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 884a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case 0x8: 885a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (board == das1801hc || board == das1802hc) { 886a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess printk(" Board model: %s\n", 8870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral das1800_boards[board].name); 888a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 889a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 8900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 8910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (" Board model (probed, not recommended): das-1800hc series\n"); 892a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return das1801hc; 893a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 894a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 8950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 8960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (" Board model: probe returned 0x%x (unknown, please report)\n", 8970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral id); 898a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return board; 899a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 900a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 901a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 902a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 903a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 9040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_ai_poll(struct comedi_device *dev, 9050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 906a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 907a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long flags; 908a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 909a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* prevent race with interrupt handler */ 9105f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 911a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_ai_handler(dev); 9125f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 913a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 914a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return s->async->buf_write_count - s->async->buf_read_count; 915a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 916a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 91770265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t das1800_interrupt(int irq, void *d) 918a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 91971b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton struct comedi_device *dev = d; 920a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int status; 921a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 922a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dev->attached == 0) { 923a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, "premature interrupt"); 924a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return IRQ_HANDLED; 925a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 926a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 927a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* Prevent race with das1800_ai_poll() on multi processor systems. 928a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * Also protects indirect addressing in das1800_ai_handler */ 929a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess spin_lock(&dev->spinlock); 930a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess status = inb(dev->iobase + DAS1800_STATUS); 931a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 932a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if interrupt was not caused by das-1800 */ 933a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!(status & INT)) { 934a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess spin_unlock(&dev->spinlock); 935a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return IRQ_NONE; 936a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 937a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* clear the interrupt status bit INT */ 938a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS); 939a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* handle interrupt */ 940a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_ai_handler(dev); 941a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 942a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess spin_unlock(&dev->spinlock); 943a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return IRQ_HANDLED; 944a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 945a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 946a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* the guts of the interrupt handler, that is shared with das1800_ai_poll */ 947da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void das1800_ai_handler(struct comedi_device *dev) 948a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 94934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */ 950d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 951ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &async->cmd; 952a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int status = inb(dev->iobase + DAS1800_STATUS); 953a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 954a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events = 0; 955a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* select adc for base address + 0 */ 956a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(ADC, dev->iobase + DAS1800_SELECT); 957a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* dma buffer full */ 958a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->irq_dma_bits & DMA_ENABLED) { 959a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* look for data from dma transfer even if dma terminal count hasn't happened yet */ 960a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_dma(dev, s, status); 961a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton } else if (status & FHF) { /* if fifo half full */ 962a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_fifo_half_full(dev, s); 963a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton } else if (status & FNE) { /* if fifo not empty */ 964a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_fifo_not_empty(dev, s); 965a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 966a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 967a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events |= COMEDI_CB_BLOCK; 968a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if the card's fifo has overflowed */ 969a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (status & OVF) { 970a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* clear OVF interrupt bit */ 971a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS); 972a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, "DAS1800 FIFO overflow"); 973a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, s); 974a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 975a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_event(dev, s); 976a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 977a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 978a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* stop taking data if appropriate */ 979a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* stop_src TRIG_EXT */ 980a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (status & CT0TC) { 981a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* clear CT0TC interrupt bit */ 982a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS); 983a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* make sure we get all remaining data from board before quitting */ 984a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->irq_dma_bits & DMA_ENABLED) 985a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_flush_dma(dev, s); 986a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess else 987a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_fifo_not_empty(dev, s); 988a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, s); /* disable hardware conversions */ 989a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events |= COMEDI_CB_EOA; 990a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */ 991a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, s); /* disable hardware conversions */ 992a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess async->events |= COMEDI_CB_EOA; 993a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 994a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 995a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_event(dev, s); 996a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 997a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 998a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 999a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 10000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void das1800_handle_dma(struct comedi_device *dev, 10010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, unsigned int status) 1002a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1003a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long flags; 1004a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1005a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1006a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess flags = claim_dma_lock(); 1007a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_flush_dma_channel(dev, s, devpriv->dma_current, 10080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->dma_current_buf); 1009a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* re-enable dma channel */ 1010a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_addr(devpriv->dma_current, 10110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral virt_to_bus(devpriv->dma_current_buf)); 1012a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size); 1013a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess enable_dma(devpriv->dma_current); 1014a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_dma_lock(flags); 1015a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1016a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (status & DMATC) { 1017a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* clear DMATC interrupt bit */ 1018a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS); 1019a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* switch dma channels for next time, if appropriate */ 1020a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dual_dma) { 1021a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* read data from the other channel next time */ 1022a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma_current == devpriv->dma0) { 1023a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma1; 1024a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf1; 1025a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 1026a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma0; 1027a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf0; 1028a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1029a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1030a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1031a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1032a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1033a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1034a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1035da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic inline uint16_t munge_bipolar_sample(const struct comedi_device *dev, 10360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral uint16_t sample) 1037a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1038a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess sample += 1 << (thisboard->resolution - 1); 1039a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return sample; 1040a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1041a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 10420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void munge_data(struct comedi_device *dev, uint16_t * array, 10430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int num_elements) 1044a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1045a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int i; 1046a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int unipolar; 1047a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1048a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* see if card is using a unipolar or bipolar range so we can munge data correctly */ 1049a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 1050a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1051a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* convert to unsigned type if we are in a bipolar mode */ 1052a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!unipolar) { 1053a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (i = 0; i < num_elements; i++) { 1054a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess array[i] = munge_bipolar_sample(dev, array[i]); 1055a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1056a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1057a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1058a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1059a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* Utility function used by das1800_flush_dma() and das1800_handle_dma(). 1060a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * Assumes dma lock is held */ 10610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void das1800_flush_dma_channel(struct comedi_device *dev, 10620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 10630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int channel, uint16_t * buffer) 1064a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1065a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int num_bytes, num_samples; 1066ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 1067a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1068a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(channel); 1069a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1070a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* clear flip-flop to make sure 2-byte registers 1071a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * get set correctly */ 1072a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess clear_dma_ff(channel); 1073a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1074a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* figure out how many points to read */ 1075a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel); 1076790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton num_samples = num_bytes / sizeof(short); 1077a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1078a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if we only need some of the points */ 1079a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples) 1080a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess num_samples = devpriv->count; 1081a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1082a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess munge_data(dev, buffer, num_samples); 1083a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cfc_write_array_to_buffer(s, buffer, num_bytes); 1084a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (s->async->cmd.stop_src == TRIG_COUNT) 1085a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->count -= num_samples; 1086a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1087a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1088a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1089a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1090a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* flushes remaining data from board when external trigger has stopped aquisition 1091a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * and we are using dma transfers */ 10920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void das1800_flush_dma(struct comedi_device *dev, 10930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 1094a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1095a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long flags; 1096a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1097a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1098a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess flags = claim_dma_lock(); 1099a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_flush_dma_channel(dev, s, devpriv->dma_current, 11000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->dma_current_buf); 1101a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1102a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dual_dma) { 1103a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* switch to other channel and flush it */ 1104a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma_current == devpriv->dma0) { 1105a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma1; 1106a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf1; 1107a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 1108a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma0; 1109a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf0; 1110a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1111a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_flush_dma_channel(dev, s, devpriv->dma_current, 11120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->dma_current_buf); 1113a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1114a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1115a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_dma_lock(flags); 1116a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1117a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* get any remaining samples in fifo */ 1118a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_handle_fifo_not_empty(dev, s); 1119a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1120a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1121a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1122a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1123da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void das1800_handle_fifo_half_full(struct comedi_device *dev, 11240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 1125a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1126a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int numPoints = 0; /* number of points to read */ 1127ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 1128a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1129a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess numPoints = FIFO_SIZE / 2; 1130a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if we only need some of the points */ 1131a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints) 1132a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess numPoints = devpriv->count; 1133a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints); 1134a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess munge_data(dev, devpriv->ai_buf0, numPoints); 1135a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cfc_write_array_to_buffer(s, devpriv->ai_buf0, 11360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral numPoints * sizeof(devpriv->ai_buf0[0])); 1137a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT) 1138a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->count -= numPoints; 1139a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1140a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1141a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1142da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void das1800_handle_fifo_not_empty(struct comedi_device *dev, 11430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 1144a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1145790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short dpnt; 1146a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int unipolar; 1147ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 1148a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1149a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 1150a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1151a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess while (inb(dev->iobase + DAS1800_STATUS) & FNE) { 1152a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) 1153a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1154a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dpnt = inw(dev->iobase + DAS1800_FIFO); 1155a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* convert to unsigned type if we are in a bipolar mode */ 1156a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!unipolar) ; 1157a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dpnt = munge_bipolar_sample(dev, dpnt); 1158a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cfc_write_to_buffer(s, dpnt); 1159a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT) 1160a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->count--; 1161a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1162a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1163a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1164a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1165a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1166da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 1167a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1168a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ 1169a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ 1170a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ 1171a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma0) 1172a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma0); 1173a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (devpriv->dma1) 1174a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma1); 1175a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1176a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1177a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1178a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* test analog input cmd */ 11790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_ai_do_cmdtest(struct comedi_device *dev, 11800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 11810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd) 1182a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1183a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int err = 0; 1184a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int tmp; 1185a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int tmp_arg; 1186a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int i; 1187a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int unipolar; 1188a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1189a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* step 1: make sure trigger sources are trivially valid */ 1190a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1191a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->start_src; 1192a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->start_src &= TRIG_NOW | TRIG_EXT; 1193a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->start_src || tmp != cmd->start_src) 1194a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1195a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1196a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->scan_begin_src; 1197a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; 1198a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 1199a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1200a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1201a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->convert_src; 1202a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->convert_src &= TRIG_TIMER | TRIG_EXT; 1203a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->convert_src || tmp != cmd->convert_src) 1204a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1205a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1206a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->scan_end_src; 1207a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_end_src &= TRIG_COUNT; 1208a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 1209a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1210a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1211a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp = cmd->stop_src; 1212a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE; 1213a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->stop_src || tmp != cmd->stop_src) 1214a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1215a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1216a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1217a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 1; 1218a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1219a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* step 2: make sure trigger sources are unique and mutually compatible */ 1220a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1221a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* uniqueness check */ 1222a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) 1223a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1224a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_begin_src != TRIG_FOLLOW && 12250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_src != TRIG_TIMER && 12260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_src != TRIG_EXT) 1227a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1228a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) 1229a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1230a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src != TRIG_COUNT && 12310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT) 1232a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1233a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* compatibility check */ 1234a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_begin_src != TRIG_FOLLOW && 12350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->convert_src != TRIG_TIMER) 1236a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1237a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1238a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1239a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 2; 1240a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1241a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* step 3: make sure arguments are trivially compatible */ 1242a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1243a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->start_arg != 0) { 1244a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->start_arg = 0; 1245a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1246a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1247a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_src == TRIG_TIMER) { 1248a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_arg < thisboard->ai_speed) { 1249a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->convert_arg = thisboard->ai_speed; 1250a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1251a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1252a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1253a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->chanlist_len) { 1254a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->chanlist_len = 1; 1255a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1256a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1257a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_end_arg != cmd->chanlist_len) { 1258a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_end_arg = cmd->chanlist_len; 1259a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1260a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1261a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1262a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd->stop_src) { 1263a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_COUNT: 1264a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!cmd->stop_arg) { 1265a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->stop_arg = 1; 1266a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1267a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1268a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1269a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_NONE: 1270a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_arg != 0) { 1271a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->stop_arg = 0; 1272a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1273a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1274a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1275a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1276a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1277a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1278a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1279a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1280a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 3; 1281a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1282a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* step 4: fix up any arguments */ 1283a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1284a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_src == TRIG_TIMER) { 1285a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* if we are not in burst mode */ 1286a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_begin_src == TRIG_FOLLOW) { 1287a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp_arg = cmd->convert_arg; 1288a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* calculate counter values that give desired timing */ 1289a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8253_cascade_ns_to_timer_2div(TIMER_BASE, 12900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor1), 12910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor2), 12920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd->convert_arg), 12930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd-> 12940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral flags & TRIG_ROUND_MASK); 1295a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (tmp_arg != cmd->convert_arg) 1296a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1297a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1298a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* if we are in burst mode */ 1299a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess else { 1300a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* check that convert_arg is compatible */ 1301a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp_arg = cmd->convert_arg; 1302a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->convert_arg = 13030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral burst_convert_arg(cmd->convert_arg, 13040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 1305a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (tmp_arg != cmd->convert_arg) 1306a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1307a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1308a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->scan_begin_src == TRIG_TIMER) { 1309a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* if scans are timed faster than conversion rate allows */ 1310a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_arg * cmd->chanlist_len > 13110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_arg) { 1312a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess cmd->scan_begin_arg = 13130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->convert_arg * 13140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->chanlist_len; 1315a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1316a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1317a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess tmp_arg = cmd->scan_begin_arg; 1318a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* calculate counter values that give desired timing */ 1319a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8253_cascade_ns_to_timer_2div(TIMER_BASE, 13200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv-> 13210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral divisor1), 13220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv-> 13230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral divisor2), 13240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd-> 13250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral scan_begin_arg), 13260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd-> 13270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral flags & 13280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral TRIG_ROUND_MASK); 1329a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (tmp_arg != cmd->scan_begin_arg) 1330a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1331a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1332a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1333a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1334a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1335a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1336a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 4; 1337a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1338a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* make sure user is not trying to mix unipolar and bipolar ranges */ 1339a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->chanlist) { 1340a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR; 1341a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (i = 1; i < cmd->chanlist_len; i++) { 1342a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) { 1343a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, 13440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "unipolar and bipolar ranges cannot be mixed in the chanlist"); 1345a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1346a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1347a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1348a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1349a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1350a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1351a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1352a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 5; 1353a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1354a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1355a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1356a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1357a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* analog input cmd interface */ 1358a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1359a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* first, some utility functions used in the main ai_do_cmd() */ 1360a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1361a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* returns appropriate bits for control register a, depending on command */ 1362ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pembertonstatic int control_a_bits(struct comedi_cmd cmd) 1363a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1364a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int control_a; 1365a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1366a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton control_a = FFEN; /* enable fifo */ 1367a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.stop_src == TRIG_EXT) { 1368a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_a |= ATEN; 1369a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1370a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd.start_src) { 1371a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_EXT: 1372a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_a |= TGEN | CGSL; 1373a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1374a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_NOW: 1375a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_a |= CGEN; 1376a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1377a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1378a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1379a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1380a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1381a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return control_a; 1382a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1383a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1384a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* returns appropriate bits for control register c, depending on command */ 1385ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pembertonstatic int control_c_bits(struct comedi_cmd cmd) 1386a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1387a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int control_c; 1388a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int aref; 1389a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1390a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* set clock source to internal or external, select analog reference, 1391a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * select unipolar / bipolar 1392a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 1393a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess aref = CR_AREF(cmd.chanlist[0]); 1394a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton control_c = UQEN; /* enable upper qram addresses */ 1395a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (aref != AREF_DIFF) 1396a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= SD; 1397a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (aref == AREF_COMMON) 1398a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= CMEN; 1399a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if a unipolar range was selected */ 1400a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR) 1401a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= UB; 1402a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd.scan_begin_src) { 1403a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case TRIG_FOLLOW: /* not in burst mode */ 1404a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd.convert_src) { 1405a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_TIMER: 1406a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* trig on cascaded counters */ 1407a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= IPCLK; 1408a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1409a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_EXT: 1410a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* trig on falling edge of external trigger */ 1411a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= XPCLK; 1412a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1413a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1414a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1415a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1416a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1417a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_TIMER: 1418a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* burst mode with internal pacer clock */ 1419a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= BMDE | IPCLK; 1420a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1421a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_EXT: 1422a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* burst mode with external trigger */ 1423a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c |= BMDE | XPCLK; 1424a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1425a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1426a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1427a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1428a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1429a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return control_c; 1430a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1431a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1432a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* sets up counters */ 1433da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd) 1434a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1435a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* setup cascaded counters for conversion/scan frequency */ 1436a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd.scan_begin_src) { 1437a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case TRIG_FOLLOW: /* not in burst mode */ 1438a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.convert_src == TRIG_TIMER) { 1439a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* set conversion frequency */ 1440a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8253_cascade_ns_to_timer_2div(TIMER_BASE, 14410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor1), 14420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor2), 14430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd.convert_arg), 14440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd. 14450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral flags & TRIG_ROUND_MASK); 1446a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (das1800_set_frequency(dev) < 0) { 1447a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 1448a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1449a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1450a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1451a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case TRIG_TIMER: /* in burst mode */ 1452a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* set scan frequency */ 1453a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), 14540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(devpriv->divisor2), 14550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd.scan_begin_arg), 14560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd.flags & TRIG_ROUND_MASK); 1457a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (das1800_set_frequency(dev) < 0) { 1458a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 1459a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1460a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1461a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1462a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1463a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1464a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1465a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* setup counter 0 for 'about triggering' */ 1466a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.stop_src == TRIG_EXT) { 1467a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* load counter 0 in mode 0 */ 1468a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0); 1469a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1470a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1471a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1472a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1473a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1474a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* sets up dma */ 1475da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd) 1476a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1477a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long lock_flags; 1478a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1479a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1480a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0) 1481a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1482a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1483a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* determine a reasonable dma transfer size */ 1484a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_transfer_size = suggest_transfer_size(&cmd); 1485a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess lock_flags = claim_dma_lock(); 1486a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma0); 1487a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* clear flip-flop to make sure 2-byte registers for 1488a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * count and address get set correctly */ 1489a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess clear_dma_ff(devpriv->dma0); 1490a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0)); 1491a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* set appropriate size of transfer */ 1492a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_count(devpriv->dma0, devpriv->dma_transfer_size); 1493a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current = devpriv->dma0; 1494a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->dma_current_buf = devpriv->ai_buf0; 1495a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess enable_dma(devpriv->dma0); 1496a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* set up dual dma if appropriate */ 1497a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (dual_dma) { 1498a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess disable_dma(devpriv->dma1); 1499a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* clear flip-flop to make sure 2-byte registers for 1500a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * count and address get set correctly */ 1501a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess clear_dma_ff(devpriv->dma1); 1502a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1)); 1503a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* set appropriate size of transfer */ 1504a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess set_dma_count(devpriv->dma1, devpriv->dma_transfer_size); 1505a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess enable_dma(devpriv->dma1); 1506a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1507a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess release_dma_lock(lock_flags); 1508a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1509a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1510a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1511a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1512a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* programs channel/gain list into card */ 1513da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd) 1514a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1515a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int i, n, chan_range; 1516a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long irq_flags; 1517a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */ 1518a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess const int range_bitshift = 8; 1519a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1520a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess n = cmd.chanlist_len; 1521a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* spinlock protects indirect addressing */ 15225f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, irq_flags); 1523a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1524a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */ 1525a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* make channel / gain list */ 1526a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (i = 0; i < n; i++) { 1527a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess chan_range = 15280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_CHAN(cmd. 15290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral chanlist[i]) | ((CR_RANGE(cmd.chanlist[i]) & 15300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral range_mask) << range_bitshift); 1531a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(chan_range, dev->iobase + DAS1800_QRAM); 1532a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1533a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 15345f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1535a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1536a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return; 1537a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1538a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1539a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* analog input do_cmd */ 15400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_ai_do_cmd(struct comedi_device *dev, 15410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 1542a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1543a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int ret; 1544a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int control_a, control_c; 1545d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async = s->async; 1546ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd cmd = async->cmd; 1547a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1548a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (!dev->irq) { 1549a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, 15500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "no irq assigned for das-1800, cannot do hardware conversions"); 1551a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 1552a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1553a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1554a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* disable dma on TRIG_WAKE_EOS, or TRIG_RT 1555a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * (because dma in handler is unsafe at hard real-time priority) */ 1556a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) { 1557a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits &= ~DMA_ENABLED; 1558a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 1559a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= devpriv->dma_bits; 1560a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1561a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* interrupt on end of conversion for TRIG_WAKE_EOS */ 1562a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.flags & TRIG_WAKE_EOS) { 1563a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* interrupt fifo not empty */ 1564a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits &= ~FIMD; 1565a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } else { 1566a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* interrupt fifo half full */ 1567a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->irq_dma_bits |= FIMD; 1568a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1569a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* determine how many conversions we need */ 1570a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd.stop_src == TRIG_COUNT) { 1571a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->count = cmd.stop_arg * cmd.chanlist_len; 1572a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1573a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1574a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess das1800_cancel(dev, s); 1575a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1576a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* determine proper bits for control registers */ 1577a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_a = control_a_bits(cmd); 1578a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess control_c = control_c_bits(cmd); 1579a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1580a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* setup card and start */ 1581a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess program_chanlist(dev, cmd); 1582a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess ret = setup_counters(dev, cmd); 1583a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (ret < 0) { 1584a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, "Error setting up counters"); 1585a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return ret; 1586a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1587a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess setup_dma(dev, cmd); 1588a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(control_c, dev->iobase + DAS1800_CONTROL_C); 1589a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* set conversion rate and length for burst mode */ 1590a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (control_c & BMDE) { 1591a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* program conversion period with number of microseconds minus 1 */ 1592a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(cmd.convert_arg / 1000 - 1, 15930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->iobase + DAS1800_BURST_RATE); 1594a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH); 1595a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1596a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */ 1597a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */ 1598a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1599a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1600a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1601a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1602a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1603a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* read analog input */ 16040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_ai_rinsn(struct comedi_device *dev, 16050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 16060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 1607a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1608a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int i, n; 1609a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int chan, range, aref, chan_range; 1610a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int timeout = 1000; 1611a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess short dpnt; 1612a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int conv_flags = 0; 1613a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long irq_flags; 1614a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1615a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* set up analog reference and unipolar / bipolar mode */ 1616a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess aref = CR_AREF(insn->chanspec); 1617a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess conv_flags |= UQEN; 1618a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (aref != AREF_DIFF) 1619a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess conv_flags |= SD; 1620a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (aref == AREF_COMMON) 1621a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess conv_flags |= CMEN; 1622a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* if a unipolar range was selected */ 1623a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (CR_RANGE(insn->chanspec) & UNIPOLAR) 1624a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess conv_flags |= UB; 1625a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1626a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */ 1627a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1628a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */ 1629a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(FFEN, dev->iobase + DAS1800_CONTROL_A); 1630a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1631a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess chan = CR_CHAN(insn->chanspec); 1632a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* mask of unipolar/bipolar bit from range */ 1633a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess range = CR_RANGE(insn->chanspec) & 0x3; 1634a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess chan_range = chan | (range << 8); 16355f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, irq_flags); 1636a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1637a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */ 1638a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(chan_range, dev->iobase + DAS1800_QRAM); 1639a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1640a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */ 1641a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1642a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (n = 0; n < insn->n; n++) { 1643a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* trigger conversion */ 1644a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(0, dev->iobase + DAS1800_FIFO); 1645a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess for (i = 0; i < timeout; i++) { 1646a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (inb(dev->iobase + DAS1800_STATUS) & FNE) 1647a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1648a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1649a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (i == timeout) { 1650a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess comedi_error(dev, "timeout"); 1651d18c5906d0914d911a13d342ff61a6bca6aff597Greg Kroah-Hartman n = -ETIME; 1652d18c5906d0914d911a13d342ff61a6bca6aff597Greg Kroah-Hartman goto exit; 1653a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1654a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dpnt = inw(dev->iobase + DAS1800_FIFO); 1655a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess /* shift data to offset binary for bipolar ranges */ 1656a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if ((conv_flags & UB) == 0) 1657a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess dpnt += 1 << (thisboard->resolution - 1); 1658a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[n] = dpnt; 1659a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1660d18c5906d0914d911a13d342ff61a6bca6aff597Greg Kroah-Hartmanexit: 16615f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1662a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1663a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return n; 1664a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1665a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1666a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* writes to an analog output channel */ 16670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_ao_winsn(struct comedi_device *dev, 16680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 16690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 1670a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1671a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int chan = CR_CHAN(insn->chanspec); 1672a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* int range = CR_RANGE(insn->chanspec); */ 1673a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int update_chan = thisboard->ao_n_chan - 1; 1674a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess short output; 1675a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned long irq_flags; 1676a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1677a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* card expects two's complement data */ 1678a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess output = data[0] - (1 << (thisboard->resolution - 1)); 1679a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* if the write is to the 'update' channel, we need to remember its value */ 1680a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (chan == update_chan) 1681a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->ao_update_bits = output; 1682a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* write to channel */ 16835f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, irq_flags); 1684a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */ 1685a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(output, dev->iobase + DAS1800_DAC); 1686a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* now we need to write to 'update' channel to update all dac channels */ 1687a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (chan != update_chan) { 1688a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */ 1689a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 1690a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 16915f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1692a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1693a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 1; 1694a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1695a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1696a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* reads from digital input channels */ 16970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_di_rbits(struct comedi_device *dev, 16980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 16990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 1700a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1701a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1702a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf; 1703a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[0] = 0; 1704a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1705a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 2; 1706a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1707a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1708a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* writes to digital output channels */ 17090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das1800_do_wbits(struct comedi_device *dev, 17100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 17110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 1712a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1713790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int wbits; 1714a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1715a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* only set bits that have been masked */ 1716a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[0] &= (1 << s->n_chan) - 1; 1717a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess wbits = devpriv->do_bits; 1718a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess wbits &= ~data[0]; 1719a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess wbits |= data[0] & data[1]; 1720a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess devpriv->do_bits = wbits; 1721a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1722a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL); 1723a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1724a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess data[1] = devpriv->do_bits; 1725a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1726a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 2; 1727a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1728a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1729a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* loads counters with divisor1, divisor2 from private structure */ 1730da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das1800_set_frequency(struct comedi_device *dev) 1731a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1732a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess int err = 0; 1733a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1734a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* counter 1, mode 2 */ 1735a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1, 17360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral 2)) 1737a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1738a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* counter 2, mode 2 */ 1739a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2, 17400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral 2)) 1741a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess err++; 1742a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (err) 1743a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return -1; 1744a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1745a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return 0; 1746a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1747a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1748a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess/* converts requested conversion timing to timing compatible with 1749a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess * hardware, used only when card is in 'burst mode' 1750a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess */ 1751a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hessstatic unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode) 1752a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1753a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int micro_sec; 1754a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1755a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* in burst mode, the maximum conversion time is 64 microseconds */ 1756a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (convert_arg > 64000) 1757a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess convert_arg = 64000; 1758a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1759a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* the conversion time must be an integral number of microseconds */ 1760a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (round_mode) { 1761a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_ROUND_NEAREST: 1762a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1763a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess micro_sec = (convert_arg + 500) / 1000; 1764a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1765a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_ROUND_DOWN: 1766a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess micro_sec = convert_arg / 1000; 1767a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1768a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_ROUND_UP: 1769a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess micro_sec = (convert_arg - 1) / 1000 + 1; 1770a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1771a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1772a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1773a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* return number of nanoseconds */ 1774a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return micro_sec * 1000; 1775a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 1776a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1777a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton/* utility function that suggests a dma transfer size based on the conversion period 'ns' */ 1778da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic unsigned int suggest_transfer_size(struct comedi_cmd *cmd) 1779a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess{ 1780a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess unsigned int size = DMA_BUF_SIZE; 1781a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton static const int sample_size = 2; /* size in bytes of one sample from board */ 1782a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */ 1783a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton unsigned int max_size; /* maximum size we will allow for a transfer */ 1784a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1785a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* make dma buffer fill in 0.3 seconds for timed modes */ 1786a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess switch (cmd->scan_begin_src) { 1787a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton case TRIG_FOLLOW: /* not in burst mode */ 1788a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->convert_src == TRIG_TIMER) 1789a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = (fill_time / cmd->convert_arg) * sample_size; 1790a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1791a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess case TRIG_TIMER: 1792a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) * 17930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral sample_size; 1794a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1795a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess default: 1796a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = DMA_BUF_SIZE; 1797a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess break; 1798a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess } 1799a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1800a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* set a minimum and maximum size allowed */ 1801a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess max_size = DMA_BUF_SIZE; 1802a351ecf3081f94796cf915dba820f9f5e62c43cfBill Pemberton /* if we are taking limited number of conversions, limit transfer size to that */ 1803a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (cmd->stop_src == TRIG_COUNT && 18040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->stop_arg * cmd->chanlist_len * sample_size < max_size) 1805a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess max_size = cmd->stop_arg * cmd->chanlist_len * sample_size; 1806a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1807a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (size > max_size) 1808a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = max_size; 1809a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess if (size < sample_size) 1810a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess size = sample_size; 1811a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess 1812a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess return size; 1813a69cc3a9fae82f3620d7242fe5bfaedd24b65df5Frank Mori Hess} 181490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 181590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 181690f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 181790f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 1818