[go: nahoru, domu]

13c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef/*
23c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   comedi/drivers/dt2811.c
33c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   Hardware driver for Data Translation DT2811
43c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
53c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   COMEDI - Linux Control and Measurement Device Interface
63c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   History:
73c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   Base Version  - David A. Schleef <ds@schleef.org>
83c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   December 1998 - Updated to work.  David does not have a DT2811
93c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   board any longer so this was suffering from bitrot.
103c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   Updated performed by ...
113c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
123c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   This program is free software; you can redistribute it and/or modify
133c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   it under the terms of the GNU General Public License as published by
143c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   the Free Software Foundation; either version 2 of the License, or
153c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   (at your option) any later version.
163c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
173c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   This program is distributed in the hope that it will be useful,
183c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   but WITHOUT ANY WARRANTY; without even the implied warranty of
193c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
203c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   GNU General Public License for more details.
213c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef */
223c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef/*
233c443716217c9bd10ae0ce2f0ea3238f28bb5c31David SchleefDriver: dt2811
243c443716217c9bd10ae0ce2f0ea3238f28bb5c31David SchleefDescription: Data Translation DT2811
253c443716217c9bd10ae0ce2f0ea3238f28bb5c31David SchleefAuthor: ds
263c443716217c9bd10ae0ce2f0ea3238f28bb5c31David SchleefDevices: [Data Translation] DT2811-PGL (dt2811-pgl), DT2811-PGH (dt2811-pgh)
273c443716217c9bd10ae0ce2f0ea3238f28bb5c31David SchleefStatus: works
283c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
293c443716217c9bd10ae0ce2f0ea3238f28bb5c31David SchleefConfiguration options:
303c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef  [0] - I/O port base address
313c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef  [1] - IRQ, although this is currently unused
323c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef  [2] - A/D reference
333b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	  0 = signle-ended
343b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	  1 = differential
353c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	  2 = pseudo-differential (common reference)
363c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef  [3] - A/D range
373b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	  0 = [-5, 5]
383b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	  1 = [-2.5, 2.5]
393b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	  2 = [0, 5]
403c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef  [4] - D/A 0 range (same choices)
413c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef  [4] - D/A 1 range (same choices)
423c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef*/
433c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
44ce157f8032bbd46d9427034c335b0afd751da25dH Hartley Sweeten#include <linux/module.h>
453c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#include "../comedidev.h"
463c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
473b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcherstatic const struct comedi_lrange range_dt2811_pgh_ai_5_unipolar = {
483b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	4, {
493cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		UNI_RANGE(5),
503cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		UNI_RANGE(2.5),
513cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		UNI_RANGE(1.25),
523cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		UNI_RANGE(0.625)
533b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	}
543c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef};
550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral
563b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcherstatic const struct comedi_lrange range_dt2811_pgh_ai_2_5_bipolar = {
573b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	4, {
583cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(2.5),
593cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(1.25),
603cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(0.625),
613cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(0.3125)
623b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	}
633c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef};
640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral
653b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcherstatic const struct comedi_lrange range_dt2811_pgh_ai_5_bipolar = {
663b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	4, {
673cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(5),
683cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(2.5),
693cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(1.25),
703cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(0.625)
713b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	}
723c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef};
730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral
743b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcherstatic const struct comedi_lrange range_dt2811_pgl_ai_5_unipolar = {
753b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	4, {
763cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		UNI_RANGE(5),
773cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		UNI_RANGE(0.5),
783cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		UNI_RANGE(0.05),
793cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		UNI_RANGE(0.01)
803b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	}
813c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef};
820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral
833b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcherstatic const struct comedi_lrange range_dt2811_pgl_ai_2_5_bipolar = {
843b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	4, {
853cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(2.5),
863cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(0.25),
873cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(0.025),
883cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(0.005)
893b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	}
903c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef};
910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral
923b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcherstatic const struct comedi_lrange range_dt2811_pgl_ai_5_bipolar = {
933b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	4, {
943cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(5),
953cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(0.5),
963cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(0.05),
973cdabd5d3048bfb988f964ae52e9eef6a452ee93H Hartley Sweeten		BIP_RANGE(0.01)
983b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher	}
993c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef};
1003c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
1013c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef/*
1023c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
1033c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   0x00    ADCSR R/W  A/D Control/Status Register
1043c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   bit 7 - (R) 1 indicates A/D conversion done
1053c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   reading ADDAT clears bit
1063c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   (W) ignored
1073c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   bit 6 - (R) 1 indicates A/D error
1083c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   (W) ignored
1093c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   bit 5 - (R) 1 indicates A/D busy, cleared at end
1103c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   of conversion
1113c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   (W) ignored
1123c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   bit 4 - (R) 0
1133c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   (W)
1143c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   bit 3 - (R) 0
1153c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   bit 2 - (R/W) 1 indicates interrupts enabled
1163c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   bits 1,0 - (R/W) mode bits
1173c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   00  single conversion on ADGCR load
1183c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   01  continuous conversion, internal clock,
1193c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   (clock enabled on ADGCR load)
1203c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   10  continuous conversion, internal clock,
1213c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   external trigger
1223c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   11  continuous conversion, external clock,
1233c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   external trigger
1243c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
1253c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   0x01    ADGCR R/W A/D Gain/Channel Register
1263c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   bit 6,7 - (R/W) gain select
1273c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   00  gain=1, both PGH, PGL models
1283c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   01  gain=2 PGH, 10 PGL
1293c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   10  gain=4 PGH, 100 PGL
1303c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   11  gain=8 PGH, 500 PGL
1313c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   bit 4,5 - reserved
1323c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   bit 3-0 - (R/W) channel select
1333c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   channel number from 0-15
1343c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
1353c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   0x02,0x03 (R) ADDAT A/D Data Register
1363c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   (W) DADAT0 D/A Data Register 0
1373c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   0x02 low byte
1383c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   0x03 high byte
1393c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
1403c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   0x04,0x05 (W) DADAT0 D/A Data Register 1
1413c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
1423c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   0x06 (R) DIO0 Digital Input Port 0
1433c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   (W) DIO1 Digital Output Port 1
1443c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
1453c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   0x07 TMRCTR (R/W) Timer/Counter Register
1463c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   bits 6,7 - reserved
1473c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   bits 5-3 - Timer frequency control (mantissa)
1483c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   543  divisor  freqency (kHz)
1493c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   000  1        600
1503c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   001  10       60
1513c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   010  2        300
1523c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   011  3        200
1533c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   100  4        150
1543c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   101  5        120
1553c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   110  6        100
1563c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   111  12       50
1573c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   bits 2-0 - Timer frequency control (exponent)
1583c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   210  multiply divisor/divide frequency by
1593c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   000  1
1603c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   001  10
1613c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   010  100
1623c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   011  1000
1633c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   100  10000
1643c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   101  100000
1653c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   110  1000000
1663c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef   111  10000000
1673c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
1683c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef */
1693c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
1703c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define TIMEOUT 10000
1713c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
1723c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_ADCSR 0
1733c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_ADGCR 1
1743c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_ADDATLO 2
1753c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_ADDATHI 3
1763c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_DADAT0LO 2
1773c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_DADAT0HI 3
1783c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_DADAT1LO 4
1793c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_DADAT1HI 5
1803c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_DIO 6
1813c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_TMRCTR 7
1823c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
1833c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef/*
1843c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef * flags
1853c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef */
1863c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
1873c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef/* ADCSR */
1883c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
1893c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_ADDONE   0x80
1903c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_ADERROR  0x40
1913c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_ADBUSY   0x20
1923c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_CLRERROR 0x10
1933c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_INTENB   0x04
1943c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#define DT2811_ADMODE   0x03
1953c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
19642f1884d0683d0d0d4b0895aaed02dbed5d8b921Bill Pembertonstruct dt2811_board {
19742f1884d0683d0d0d4b0895aaed02dbed5d8b921Bill Pemberton
1983c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	const char *name;
1999ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pemberton	const struct comedi_lrange *bip_5;
2009ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pemberton	const struct comedi_lrange *bip_2_5;
2019ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pemberton	const struct comedi_lrange *unip_5;
20242f1884d0683d0d0d4b0895aaed02dbed5d8b921Bill Pemberton};
20342f1884d0683d0d0d4b0895aaed02dbed5d8b921Bill Pemberton
2043c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleefenum { card_2811_pgh, card_2811_pgl };
205d89da61754236aee5ab8faf0cab7f5449a2fdd34Bill Pemberton
206d89da61754236aee5ab8faf0cab7f5449a2fdd34Bill Pembertonstruct dt2811_private {
2073c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	int ntrig;
2083c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	int curadchan;
2093c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	enum {
2103c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		adc_singleended, adc_diff, adc_pseudo_diff
2113c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	} adc_mux;
2123c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	enum {
2133c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		dac_bipolar_5, dac_bipolar_2_5, dac_unipolar_5
2143c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	} dac_range[2];
2159ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pemberton	const struct comedi_lrange *range_type_list[2];
216d89da61754236aee5ab8faf0cab7f5449a2fdd34Bill Pemberton};
2173c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
2189ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange *dac_range_types[] = {
2193c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	&range_bipolar5,
2203c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	&range_bipolar2_5,
2213c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	&range_unipolar5
2223c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef};
2233c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
2247c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweetenstatic int dt2811_ai_eoc(struct comedi_device *dev,
2257c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten			 struct comedi_subdevice *s,
2267c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten			 struct comedi_insn *insn,
2277c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten			 unsigned long context)
2287c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten{
2297c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten	unsigned int status;
2307c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten
2317c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten	status = inb(dev->iobase + DT2811_ADCSR);
2327c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten	if ((status & DT2811_ADBUSY) == 0)
2337c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten		return 0;
2347c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten	return -EBUSY;
2357c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten}
2363c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
2375675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweetenstatic int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
2385675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten			  struct comedi_insn *insn, unsigned int *data)
2395675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten{
2405675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	int chan = CR_CHAN(insn->chanspec);
2417c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten	int ret;
2425675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	int i;
2435675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten
2445675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	for (i = 0; i < insn->n; i++) {
2455675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten		outb(chan, dev->iobase + DT2811_ADGCR);
2465675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten
2477c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten		ret = comedi_timeout(dev, s, insn, dt2811_ai_eoc, 0);
2487c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten		if (ret)
2497c4ede3a6baa640393c7e98f9271c6c282a02f1eH Hartley Sweeten			return ret;
2505675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten
2515675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten		data[i] = inb(dev->iobase + DT2811_ADDATLO);
2525675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten		data[i] |= inb(dev->iobase + DT2811_ADDATHI) << 8;
2535675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten		data[i] &= 0xfff;
2545675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	}
2555675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten
2565675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	return i;
2575675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten}
2585675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten
259b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweetenstatic int dt2811_ao_insn_write(struct comedi_device *dev,
260b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten				struct comedi_subdevice *s,
261b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten				struct comedi_insn *insn,
262b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten				unsigned int *data)
2635675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten{
264b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten	unsigned int chan = CR_CHAN(insn->chanspec);
265b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten	unsigned int val = s->readback[chan];
2665675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	int i;
2675675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten
2685675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	for (i = 0; i < insn->n; i++) {
269b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten		val = data[i];
270b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten		outb(val & 0xff, dev->iobase + DT2811_DADAT0LO + 2 * chan);
271b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten		outb((val >> 8) & 0xff,
2725675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten		     dev->iobase + DT2811_DADAT0HI + 2 * chan);
2735675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	}
274b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten	s->readback[chan] = val;
2755675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten
276b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten	return insn->n;
2775675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten}
2785675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten
2795675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweetenstatic int dt2811_di_insn_bits(struct comedi_device *dev,
2805675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten			       struct comedi_subdevice *s,
2815675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten			       struct comedi_insn *insn, unsigned int *data)
2825675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten{
2835675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	data[1] = inb(dev->iobase + DT2811_DIO);
2845675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten
285a2714e3e42e746d6c8525c35fdcc58fb60c2830dH Hartley Sweeten	return insn->n;
2865675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten}
2875675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten
2885675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweetenstatic int dt2811_do_insn_bits(struct comedi_device *dev,
2895675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten			       struct comedi_subdevice *s,
29097f4289ad08cffe55de06d4ac4f89ac540450aeeH Hartley Sweeten			       struct comedi_insn *insn,
29197f4289ad08cffe55de06d4ac4f89ac540450aeeH Hartley Sweeten			       unsigned int *data)
2925675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten{
29397f4289ad08cffe55de06d4ac4f89ac540450aeeH Hartley Sweeten	if (comedi_dio_update_state(s, data))
29497f4289ad08cffe55de06d4ac4f89ac540450aeeH Hartley Sweeten		outb(s->state, dev->iobase + DT2811_DIO);
2955675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten
2965675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	data[1] = s->state;
2975675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten
298a2714e3e42e746d6c8525c35fdcc58fb60c2830dH Hartley Sweeten	return insn->n;
2995675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten}
3005675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten
3013c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef/*
3023c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef  options[0]   Board base address
3033c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef  options[1]   IRQ
3043c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef  options[2]   Input configuration
3053b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher		 0 == single-ended
3063b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher		 1 == differential
3073b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher		 2 == pseudo-differential
3083c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef  options[3]   Analog input range configuration
3093b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher		 0 == bipolar 5  (-5V -- +5V)
3103b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher		 1 == bipolar 2.5V  (-2.5V -- +2.5V)
3113b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher		 2 == unipolar 5V  (0V -- +5V)
3123c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef  options[4]   Analog output 0 range configuration
3133b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher		 0 == bipolar 5  (-5V -- +5V)
3143b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher		 1 == bipolar 2.5V  (-2.5V -- +2.5V)
3153b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher		 2 == unipolar 5V  (0V -- +5V)
3163c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef  options[5]   Analog output 1 range configuration
3173b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher		 0 == bipolar 5  (-5V -- +5V)
3183b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher		 1 == bipolar 2.5V  (-2.5V -- +2.5V)
3193b9fdcd5e85104e622c0ec5f626c81b831ddfae2Iain Churcher		 2 == unipolar 5V  (0V -- +5V)
3203c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef*/
321da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
3223c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef{
323d7bfe8e845ad03a48bc0e988cddedb536e296144H Hartley Sweeten	/* int i; */
324a5a74074d3401028fa09dfeaee12d38e2dae0075Ian Abbott	const struct dt2811_board *board = dev->board_ptr;
3259a1a6cf8ae5ca58171e117335b9983e3cfa2185cH Hartley Sweeten	struct dt2811_private *devpriv;
3263c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	int ret;
32734c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s;
3283c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
329862755ec07572036b0c69d738b88f89b6beede99H Hartley Sweeten	ret = comedi_request_region(dev, it->options[0], 0x8);
3306ca3f28b8529d9401a7be7641a8951c12443e05dH Hartley Sweeten	if (ret)
3316ca3f28b8529d9401a7be7641a8951c12443e05dH Hartley Sweeten		return ret;
3323c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
3333c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#if 0
3343c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	outb(0, dev->iobase + DT2811_ADCSR);
3355f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	udelay(100);
3363c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	i = inb(dev->iobase + DT2811_ADDATLO);
3373c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	i = inb(dev->iobase + DT2811_ADDATHI);
3383c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef#endif
3393c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
3402f0b9d082e5d0056a3aca4be038483a564849196H Hartley Sweeten	ret = comedi_alloc_subdevices(dev, 4);
3418b6c56949ffa83dbc2a6e8fa3f98b10a19372207H Hartley Sweeten	if (ret)
3423c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		return ret;
343c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton
3440bdab509bf9c6d838dc0a3b1d68bbf841fc20b5aH Hartley Sweeten	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
345c34fa261b0ac3a862ccd3f71ee55a16b920dfc83H Hartley Sweeten	if (!devpriv)
346c34fa261b0ac3a862ccd3f71ee55a16b920dfc83H Hartley Sweeten		return -ENOMEM;
347c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton
3483c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	switch (it->options[2]) {
3493c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	case 0:
3503c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		devpriv->adc_mux = adc_singleended;
3513c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
3523c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	case 1:
3533c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		devpriv->adc_mux = adc_diff;
3543c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
3553c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	case 2:
3563c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		devpriv->adc_mux = adc_pseudo_diff;
3573c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
3583c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	default:
3593c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		devpriv->adc_mux = adc_singleended;
3603c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
3613c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	}
3623c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	switch (it->options[4]) {
3633c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	case 0:
3643c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		devpriv->dac_range[0] = dac_bipolar_5;
3653c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
3663c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	case 1:
3673c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		devpriv->dac_range[0] = dac_bipolar_2_5;
3683c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
3693c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	case 2:
3703c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		devpriv->dac_range[0] = dac_unipolar_5;
3713c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
3723c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	default:
3733c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		devpriv->dac_range[0] = dac_bipolar_5;
3743c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
3753c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	}
3763c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	switch (it->options[5]) {
3773c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	case 0:
3783c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		devpriv->dac_range[1] = dac_bipolar_5;
3793c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
3803c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	case 1:
3813c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		devpriv->dac_range[1] = dac_bipolar_2_5;
3823c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
3833c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	case 2:
3843c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		devpriv->dac_range[1] = dac_unipolar_5;
3853c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
3863c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	default:
3873c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		devpriv->dac_range[1] = dac_bipolar_5;
3883c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
3893c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	}
3903c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
3914ea498964a9168a17bc61183c400308f11eaee8aH Hartley Sweeten	s = &dev->subdevices[0];
3923c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	/* initialize the ADC subdevice */
3933c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->type = COMEDI_SUBD_AI;
3943c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->subdev_flags = SDF_READABLE | SDF_GROUND;
3953c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->n_chan = devpriv->adc_mux == adc_diff ? 8 : 16;
3963c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->insn_read = dt2811_ai_insn;
3973c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->maxdata = 0xfff;
3983c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	switch (it->options[3]) {
3993c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	case 0:
4003c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	default:
4015a011d61ed5ca531470493acf19756fc4e894675H Hartley Sweeten		s->range_table = board->bip_5;
4023c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
4033c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	case 1:
4045a011d61ed5ca531470493acf19756fc4e894675H Hartley Sweeten		s->range_table = board->bip_2_5;
4053c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
4063c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	case 2:
4075a011d61ed5ca531470493acf19756fc4e894675H Hartley Sweeten		s->range_table = board->unip_5;
4083c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef		break;
4093c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	}
4103c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
4114ea498964a9168a17bc61183c400308f11eaee8aH Hartley Sweeten	s = &dev->subdevices[1];
4123c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	/* ao subdevice */
4133c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->type = COMEDI_SUBD_AO;
4143c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->subdev_flags = SDF_WRITABLE;
4153c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->n_chan = 2;
4163c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->maxdata = 0xfff;
4173c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->range_table_list = devpriv->range_type_list;
4183c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	devpriv->range_type_list[0] = dac_range_types[devpriv->dac_range[0]];
4193c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	devpriv->range_type_list[1] = dac_range_types[devpriv->dac_range[1]];
420b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten	s->insn_write = dt2811_ao_insn_write;
421b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten	s->insn_read = comedi_readback_insn_read;
422b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten
423b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten	ret = comedi_alloc_subdev_readback(s);
424b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten	if (ret)
425b33bad98afe06cb8bb2751a02bdae2f2531bd4f4H Hartley Sweeten		return ret;
4263c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
4274ea498964a9168a17bc61183c400308f11eaee8aH Hartley Sweeten	s = &dev->subdevices[2];
4283c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	/* di subdevice */
4293c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->type = COMEDI_SUBD_DI;
4303c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->subdev_flags = SDF_READABLE;
4313c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->n_chan = 8;
4323c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->insn_bits = dt2811_di_insn_bits;
4333c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->maxdata = 1;
4343c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->range_table = &range_digital;
4353c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
4364ea498964a9168a17bc61183c400308f11eaee8aH Hartley Sweeten	s = &dev->subdevices[3];
4373c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	/* do subdevice */
4383c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->type = COMEDI_SUBD_DO;
4393c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->subdev_flags = SDF_WRITABLE;
4403c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->n_chan = 8;
4413c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->insn_bits = dt2811_do_insn_bits;
4423c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->maxdata = 1;
4433c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->state = 0;
4443c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	s->range_table = &range_digital;
4453c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
4463c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef	return 0;
4473c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef}
4483c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
4495675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweetenstatic const struct dt2811_board boardtypes[] = {
4505675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	{
4515675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten		.name		= "dt2811-pgh",
4525675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten		.bip_5		= &range_dt2811_pgh_ai_5_bipolar,
4535675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten		.bip_2_5	= &range_dt2811_pgh_ai_2_5_bipolar,
4545675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten		.unip_5		= &range_dt2811_pgh_ai_5_unipolar,
4555675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	}, {
4565675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten		.name		= "dt2811-pgl",
4575675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten		.bip_5		= &range_dt2811_pgl_ai_5_bipolar,
4585675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten		.bip_2_5	= &range_dt2811_pgl_ai_2_5_bipolar,
4595675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten		.unip_5		= &range_dt2811_pgl_ai_5_unipolar,
4605675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	},
4615675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten};
4623c443716217c9bd10ae0ce2f0ea3238f28bb5c31David Schleef
4635675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweetenstatic struct comedi_driver dt2811_driver = {
4645675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	.driver_name	= "dt2811",
4655675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	.module		= THIS_MODULE,
4665675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	.attach		= dt2811_attach,
4673d1fe3f785c80e17f62acf8f92570ae9210bd588H Hartley Sweeten	.detach		= comedi_legacy_detach,
4685675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	.board_name	= &boardtypes[0].name,
4695675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	.num_names	= ARRAY_SIZE(boardtypes),
4705675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten	.offset		= sizeof(struct dt2811_board),
4715675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweeten};
4725675d89927d428f7ea1bb6b0b3df06580bd55dcfH Hartley Sweetenmodule_comedi_driver(dt2811_driver);
47390f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas
47490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
47590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver");
47690f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
477