15c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten/*
25c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten * addi_apci_3xxx.c
35c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
45c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten * Project manager: S. Weber
55c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten *
65c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten *	ADDI-DATA GmbH
75c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten *	Dieselstrasse 3
85c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten *	D-77833 Ottersweier
95c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten *	Tel: +19(0)7223/9493-0
105c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten *	Fax: +49(0)7223/9493-92
115c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten *	http://www.addi-data.com
125c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten *	info@addi-data.com
135c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten *
145c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten * This program is free software; you can redistribute it and/or modify it
155c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten * under the terms of the GNU General Public License as published by the
165c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten * Free Software Foundation; either version 2 of the License, or (at your
175c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten * option) any later version.
185c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten *
195c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten * This program is distributed in the hope that it will be useful, but WITHOUT
205c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
215c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
225c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten * more details.
235c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten */
245c70cbfb3a8ebfaac5f3588840fcbf71c3cc02a1H Hartley Sweeten
25ce157f8032bbd46d9427034c335b0afd751da25dH Hartley Sweeten#include <linux/module.h>
2633782dd5edf8db3cdb7c81a3523bf743dd0209b7H Hartley Sweeten#include <linux/pci.h>
271867add98e44d4bec01572b4cfd4becd11297e5dH Hartley Sweeten#include <linux/interrupt.h>
2833782dd5edf8db3cdb7c81a3523bf743dd0209b7H Hartley Sweeten
293d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten#include "../comedidev.h"
303d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten
31f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten#include "comedi_fc.h"
32f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
33a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten#define CONV_UNIT_NS		(1 << 0)
34a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten#define CONV_UNIT_US		(1 << 1)
35a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten#define CONV_UNIT_MS		(1 << 2)
36a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten
3798a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweetenstatic const struct comedi_lrange apci3xxx_ai_range = {
3898a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten	8, {
3998a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		BIP_RANGE(10),
4098a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		BIP_RANGE(5),
4198a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		BIP_RANGE(2),
4298a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		BIP_RANGE(1),
4398a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		UNI_RANGE(10),
4498a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		UNI_RANGE(5),
4598a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		UNI_RANGE(2),
4698a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		UNI_RANGE(1)
4798a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten	}
4898a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten};
4998a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten
5098a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweetenstatic const struct comedi_lrange apci3xxx_ao_range = {
5198a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten	2, {
5298a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		BIP_RANGE(10),
5398a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		UNI_RANGE(10)
5498a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten	}
5598a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten};
5698a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten
57dbae4575661da840353f12dd76499ad587c92519H Hartley Sweetenenum apci3xxx_boardid {
58dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3000_16,
59dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3000_8,
60dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3000_4,
61dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3006_16,
62dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3006_8,
63dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3006_4,
64dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3010_16,
65dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3010_8,
66dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3010_4,
67dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3016_16,
68dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3016_8,
69dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3016_4,
70dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3100_16_4,
71dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3100_8_4,
72dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3106_16_4,
73dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3106_8_4,
74dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3110_16_4,
75dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3110_8_4,
76dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3116_16_4,
77dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3116_8_4,
78dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3003,
79dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3002_16,
80dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3002_8,
81dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3002_4,
82dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3500,
83dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten};
84dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten
85e053b2419f5f0cff8ced6a8e39a93d113d9cd86aH Hartley Sweetenstruct apci3xxx_boardinfo {
866abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten	const char *name;
878a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten	int ai_subdev_flags;
8847bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten	int ai_n_chan;
895469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten	unsigned int ai_maxdata;
90a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten	unsigned char ai_conv_units;
918edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten	unsigned int ai_min_acq_ns;
92fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten	unsigned int has_ao:1;
934aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten	unsigned int has_dig_in:1;
944aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten	unsigned int has_dig_out:1;
950ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten	unsigned int has_ttl_io:1;
96e053b2419f5f0cff8ced6a8e39a93d113d9cd86aH Hartley Sweeten};
97e053b2419f5f0cff8ced6a8e39a93d113d9cd86aH Hartley Sweeten
98e053b2419f5f0cff8ced6a8e39a93d113d9cd86aH Hartley Sweetenstatic const struct apci3xxx_boardinfo apci3xxx_boardtypes[] = {
99dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3000_16] = {
1006abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3000-16",
1018a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
10247bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
1035469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
104a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1058edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
1060ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
107dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
108dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3000_8] = {
1096abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3000-8",
1108a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
11147bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
1125469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
113a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1148edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
1150ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
116dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
117dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3000_4] = {
1186abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3000-4",
1198a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
12047bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 4,
1215469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
122a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1238edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
1240ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
125dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
126dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3006_16] = {
1276abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3006-16",
1288a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
12947bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
1305469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
131a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1328edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
1330ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
134dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
135dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3006_8] = {
1366abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3006-8",
1378a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
13847bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
1395469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
140a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1418edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
1420ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
143dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
144dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3006_4] = {
1456abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3006-4",
1468a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
14747bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 4,
1485469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
149a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1508edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
1510ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
152dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
153dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3010_16] = {
1546abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3010-16",
1558a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
15647bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
1575469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
158a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1598edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
1604aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
1614aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
1620ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
163dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
164dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3010_8] = {
1656abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3010-8",
1668a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
16747bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
1685469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
169a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1708edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
1714aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
1724aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
1730ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
174dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
175dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3010_4] = {
1766abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3010-4",
1778a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
17847bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 4,
1795469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
180a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1818edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
1824aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
1834aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
1840ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
185dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
186dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3016_16] = {
1876abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3016-16",
1888a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
18947bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
1905469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
191a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1928edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
1934aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
1944aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
1950ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
196dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
197dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3016_8] = {
1986abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3016-8",
1998a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
20047bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
2015469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
202a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2038edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
2044aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
2054aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
2060ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
207dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
208dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3016_4] = {
2096abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3016-4",
2108a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
21147bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 4,
2125469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
213a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2148edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
2154aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
2164aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
2170ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
218dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
219dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3100_16_4] = {
2206abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3100-16-4",
2218a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
22247bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
2235469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
224a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2258edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
226fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2270ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
228dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
229dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3100_8_4] = {
2306abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3100-8-4",
2318a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
23247bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
2335469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
234a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2358edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
236fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2370ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
238dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
239dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3106_16_4] = {
2406abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3106-16-4",
2418a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
24247bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
2435469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
244a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2458edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
246fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2470ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
248dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
249dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3106_8_4] = {
2506abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3106-8-4",
2518a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
25247bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
2535469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
254a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2558edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
256fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2570ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
258dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
259dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3110_16_4] = {
2606abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3110-16-4",
2618a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
26247bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
2635469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
264a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2658edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
266fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2674aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
2684aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
2690ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
270dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
271dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3110_8_4] = {
2726abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3110-8-4",
2738a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
27447bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
2755469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
276a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2778edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
278fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2794aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
2804aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
2810ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
282dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
283dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3116_16_4] = {
2846abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3116-16-4",
2858a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
28647bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
2875469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
288a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2898edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
290fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2914aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
2924aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
2930ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
294dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
295dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3116_8_4] = {
2966abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3116-8-4",
2978a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
29847bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
2995469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
300a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
3018edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
302fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
3034aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
3044aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
3050ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
306dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
307dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3003] = {
3086abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3003",
3098a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_DIFF,
3108d4729066cde58c730573d6aad2ea29f8048fcb3H Hartley Sweeten		.ai_n_chan		= 4,
3115469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
312a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US |
313a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten					  CONV_UNIT_NS,
3148edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 2500,
3154aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
3164aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
317dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
318dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3002_16] = {
3196abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3002-16",
3208a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_DIFF,
3218d4729066cde58c730573d6aad2ea29f8048fcb3H Hartley Sweeten		.ai_n_chan		= 16,
3225469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
323a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
3248edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
3254aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
3264aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
327dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
328dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3002_8] = {
3296abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3002-8",
3308a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_DIFF,
3318d4729066cde58c730573d6aad2ea29f8048fcb3H Hartley Sweeten		.ai_n_chan		= 8,
3325469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
333a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
3348edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
3354aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
3364aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
337dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
338dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3002_4] = {
3396abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3002-4",
3408a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_DIFF,
3418d4729066cde58c730573d6aad2ea29f8048fcb3H Hartley Sweeten		.ai_n_chan		= 4,
3425469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
343a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
3448edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
3454aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
3464aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
347dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
348dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3500] = {
3496abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3500",
350fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
3510ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
352c0a053b8b24d72413a82a16a41f635e6040ccf34H Hartley Sweeten	},
353c0a053b8b24d72413a82a16a41f635e6040ccf34H Hartley Sweeten};
354c0a053b8b24d72413a82a16a41f635e6040ccf34H Hartley Sweeten
3551867add98e44d4bec01572b4cfd4becd11297e5dH Hartley Sweetenstruct apci3xxx_private {
356f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int ai_timer;
357f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned char ai_time_base;
3581867add98e44d4bec01572b4cfd4becd11297e5dH Hartley Sweeten};
3591867add98e44d4bec01572b4cfd4becd11297e5dH Hartley Sweeten
3606c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweetenstatic irqreturn_t apci3xxx_irq_handler(int irq, void *d)
3616c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten{
3626c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten	struct comedi_device *dev = d;
363f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	struct comedi_subdevice *s = dev->read_subdev;
3646c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten	unsigned int status;
365f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int val;
3666c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten
3676c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten	/* Test if interrupt occur */
36824a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	status = readl(dev->mmio + 16);
3696c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten	if ((status & 0x2) == 0x2) {
3706c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten		/* Reset the interrupt */
37124a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten		writel(status, dev->mmio + 16);
3726c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten
37324a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten		val = readl(dev->mmio + 28);
3743672effdeae5395d661a2103f69082146ef949fcIan Abbott		comedi_buf_put(s, val);
375f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
376f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		s->async->events |= COMEDI_CB_EOA;
377f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		comedi_event(dev, s);
378f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
379f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return IRQ_HANDLED;
380f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	}
381f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	return IRQ_NONE;
382f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten}
383f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
384f32376e993a7657198974e713577152ac67833dbH Hartley Sweetenstatic int apci3xxx_ai_started(struct comedi_device *dev)
385f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten{
38624a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	if ((readl(dev->mmio + 8) & 0x80000) == 0x80000)
387f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return 1;
388f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
3899ed221faae72ab1ad16e5f51d9f290e77af2c795H Hartley Sweeten	return 0;
390f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten}
391f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
392f32376e993a7657198974e713577152ac67833dbH Hartley Sweetenstatic int apci3xxx_ai_setup(struct comedi_device *dev, unsigned int chanspec)
393f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten{
394f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int chan = CR_CHAN(chanspec);
395f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int range = CR_RANGE(chanspec);
396f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int aref = CR_AREF(chanspec);
397f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int delay_mode;
398f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int val;
399f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
400f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (apci3xxx_ai_started(dev))
401f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return -EBUSY;
402f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
403f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Clear the FIFO */
40424a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	writel(0x10000, dev->mmio + 12);
405f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
406f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Get and save the delay mode */
40724a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	delay_mode = readl(dev->mmio + 4);
408f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	delay_mode &= 0xfffffef0;
409f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
410f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Channel configuration selection */
41124a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	writel(delay_mode, dev->mmio + 4);
412f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
413f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Make the configuration */
414f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	val = (range & 3) | ((range >> 2) << 6) |
415f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	      ((aref == AREF_DIFF) << 7);
41624a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	writel(val, dev->mmio + 0);
417f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
418f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Channel selection */
41924a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	writel(delay_mode | 0x100, dev->mmio + 4);
42024a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	writel(chan, dev->mmio + 0);
421f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
422f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Restore delay mode */
42324a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	writel(delay_mode, dev->mmio + 4);
424f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
425f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Set the number of sequence to 1 */
42624a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	writel(1, dev->mmio + 48);
427f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
428f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	return 0;
429f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten}
430f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
43167562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweetenstatic int apci3xxx_ai_eoc(struct comedi_device *dev,
43267562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten			   struct comedi_subdevice *s,
43367562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten			   struct comedi_insn *insn,
43467562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten			   unsigned long context)
43567562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten{
43667562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten	unsigned int status;
43767562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten
43824a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	status = readl(dev->mmio + 20);
43967562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten	if (status & 0x1)
44067562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten		return 0;
44167562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten	return -EBUSY;
44267562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten}
44367562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten
444f32376e993a7657198974e713577152ac67833dbH Hartley Sweetenstatic int apci3xxx_ai_insn_read(struct comedi_device *dev,
445f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten				 struct comedi_subdevice *s,
446f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten				 struct comedi_insn *insn,
447f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten				 unsigned int *data)
448f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten{
449f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	int ret;
450f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	int i;
451f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
452f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	ret = apci3xxx_ai_setup(dev, insn->chanspec);
453f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (ret)
454f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return ret;
455f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
456f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	for (i = 0; i < insn->n; i++) {
457f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		/* Start the conversion */
45824a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten		writel(0x80000, dev->mmio + 8);
459f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
460f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		/* Wait the EOS */
46167562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten		ret = comedi_timeout(dev, s, insn, apci3xxx_ai_eoc, 0);
46267562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten		if (ret)
46367562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten			return ret;
464f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
465f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		/* Read the analog value */
46624a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten		data[i] = readl(dev->mmio + 28);
467f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	}
4686c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten
469f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	return insn->n;
470f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten}
471f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
472f32376e993a7657198974e713577152ac67833dbH Hartley Sweetenstatic int apci3xxx_ai_ns_to_timer(struct comedi_device *dev,
473a207c12f62e8b53e1e1600ca384b13a39a9feed2H Hartley Sweeten				   unsigned int *ns, unsigned int flags)
474f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten{
475ef97126fd0f04f55e17d8beb409a6ffc9741f3dcIan Abbott	const struct apci3xxx_boardinfo *board = dev->board_ptr;
476f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	struct apci3xxx_private *devpriv = dev->private;
477f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int base;
478f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int timer;
479f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	int time_base;
480f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
481f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* time_base: 0 = ns, 1 = us, 2 = ms */
482f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	for (time_base = 0; time_base < 3; time_base++) {
483f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		/* skip unsupported time bases */
484f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		if (!(board->ai_conv_units & (1 << time_base)))
485f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			continue;
486f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
487f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		switch (time_base) {
488f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		case 0:
489f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			base = 1;
490f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			break;
491f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		case 1:
492f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			base = 1000;
493f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			break;
494f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		case 2:
495f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			base = 1000000;
496f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			break;
497f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		}
4986c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten
49974eede61acaa6881b9d9a733d904a314768f3eb7Ian Abbott		switch (flags & CMDF_ROUND_MASK) {
50074eede61acaa6881b9d9a733d904a314768f3eb7Ian Abbott		case CMDF_ROUND_NEAREST:
501f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		default:
502f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			timer = (*ns + base / 2) / base;
503f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			break;
50474eede61acaa6881b9d9a733d904a314768f3eb7Ian Abbott		case CMDF_ROUND_DOWN:
505f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			timer = *ns / base;
506f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			break;
50774eede61acaa6881b9d9a733d904a314768f3eb7Ian Abbott		case CMDF_ROUND_UP:
508f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			timer = (*ns + base - 1) / base;
509f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			break;
510f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		}
5116c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten
512f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		if (timer < 0x10000) {
513f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			devpriv->ai_time_base = time_base;
514f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			devpriv->ai_timer = timer;
515f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			*ns = timer * time_base;
516f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			return 0;
5176c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten		}
5186c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten	}
519f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	return -EINVAL;
5206c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten}
5216c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten
52266573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweetenstatic int apci3xxx_ai_cmdtest(struct comedi_device *dev,
52366573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			       struct comedi_subdevice *s,
52466573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			       struct comedi_cmd *cmd)
52566573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten{
526ef97126fd0f04f55e17d8beb409a6ffc9741f3dcIan Abbott	const struct apci3xxx_boardinfo *board = dev->board_ptr;
527f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	int err = 0;
52866e3015f6ec84f7143af0f01ce096b6cd9e1a4b9H Hartley Sweeten	unsigned int arg;
529f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
530f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Step 1 : check if triggers are trivially valid */
531f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
532f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
533f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
534f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
535f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
536f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
537f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
538f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (err)
539f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return 1;
540f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
541f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Step 2a : make sure trigger sources are unique */
542f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
543f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_is_unique(cmd->stop_src);
544f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
545f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Step 2b : and mutually compatible */
546f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
547f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (err)
548f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return 2;
549f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
550f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Step 3: check if arguments are trivially valid */
551f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
552f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
553f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
554f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
555f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten					 board->ai_min_acq_ns);
556f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
557f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
558f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (cmd->stop_src == TRIG_COUNT)
559f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
560f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	else	/* TRIG_NONE */
561f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
562f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
563f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (err)
564f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return 3;
565f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
566f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* step 4: fix up any arguments */
567f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
56866e3015f6ec84f7143af0f01ce096b6cd9e1a4b9H Hartley Sweeten	arg = cmd->convert_arg;
569a207c12f62e8b53e1e1600ca384b13a39a9feed2H Hartley Sweeten	err |= apci3xxx_ai_ns_to_timer(dev, &arg, cmd->flags);
57066e3015f6ec84f7143af0f01ce096b6cd9e1a4b9H Hartley Sweeten	err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
571f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
572f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (err)
573f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return 4;
574f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
57566573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten	return 0;
57666573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten}
57766573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten
57866573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweetenstatic int apci3xxx_ai_cmd(struct comedi_device *dev,
57966573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			   struct comedi_subdevice *s)
58066573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten{
581f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	struct apci3xxx_private *devpriv = dev->private;
582f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	struct comedi_cmd *cmd = &s->async->cmd;
583f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	int ret;
584f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
585f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	ret = apci3xxx_ai_setup(dev, cmd->chanlist[0]);
586f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (ret)
587f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return ret;
588f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
589f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Set the convert timing unit */
59024a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	writel(devpriv->ai_time_base, dev->mmio + 36);
591f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
592f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Set the convert timing */
59324a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	writel(devpriv->ai_timer, dev->mmio + 32);
594f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
595f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Start the conversion */
59624a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	writel(0x180000, dev->mmio + 8);
597f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
59866573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten	return 0;
59966573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten}
60066573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten
60166573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweetenstatic int apci3xxx_ai_cancel(struct comedi_device *dev,
60266573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			      struct comedi_subdevice *s)
60366573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten{
60466573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten	return 0;
60566573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten}
60666573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten
60767562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweetenstatic int apci3xxx_ao_eoc(struct comedi_device *dev,
60867562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten			   struct comedi_subdevice *s,
60967562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten			   struct comedi_insn *insn,
61067562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten			   unsigned long context)
61167562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten{
61267562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten	unsigned int status;
61367562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten
61424a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	status = readl(dev->mmio + 96);
61567562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten	if (status & 0x100)
61667562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten		return 0;
61767562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten	return -EBUSY;
61867562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten}
61967562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten
6200e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweetenstatic int apci3xxx_ao_insn_write(struct comedi_device *dev,
6210e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten				  struct comedi_subdevice *s,
6220e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten				  struct comedi_insn *insn,
6230e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten				  unsigned int *data)
6240e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten{
6250e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	unsigned int chan = CR_CHAN(insn->chanspec);
6260e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	unsigned int range = CR_RANGE(insn->chanspec);
62767562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten	int ret;
6280e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	int i;
6290e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten
6300e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	for (i = 0; i < insn->n; i++) {
631b38d64946f8e78055f742f23678b5ebed674a5b3H Hartley Sweeten		unsigned int val = data[i];
632b38d64946f8e78055f742f23678b5ebed674a5b3H Hartley Sweeten
6330e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		/* Set the range selection */
63424a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten		writel(range, dev->mmio + 96);
6350e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten
6360e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		/* Write the analog value to the selected channel */
637b38d64946f8e78055f742f23678b5ebed674a5b3H Hartley Sweeten		writel((val << 8) | chan, dev->mmio + 100);
6380e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten
6390e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		/* Wait the end of transfer */
64067562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten		ret = comedi_timeout(dev, s, insn, apci3xxx_ao_eoc, 0);
64167562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten		if (ret)
64267562be5054f325324197cfd0f478cdc76ed57e8H Hartley Sweeten			return ret;
643b38d64946f8e78055f742f23678b5ebed674a5b3H Hartley Sweeten
644b38d64946f8e78055f742f23678b5ebed674a5b3H Hartley Sweeten		s->readback[chan] = val;
6450e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	}
6460e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten
6470e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	return insn->n;
6480e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten}
6490e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten
650ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweetenstatic int apci3xxx_di_insn_bits(struct comedi_device *dev,
651ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten				 struct comedi_subdevice *s,
652ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten				 struct comedi_insn *insn,
653ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten				 unsigned int *data)
654ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten{
655dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten	data[1] = inl(dev->iobase + 32) & 0xf;
656ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten
657ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten	return insn->n;
658ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten}
659ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten
660c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweetenstatic int apci3xxx_do_insn_bits(struct comedi_device *dev,
661c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten				 struct comedi_subdevice *s,
662c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten				 struct comedi_insn *insn,
663c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten				 unsigned int *data)
664c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten{
665dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten	s->state = inl(dev->iobase + 48) & 0xf;
666c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten
66797f4289ad08cffe55de06d4ac4f89ac540450aeeH Hartley Sweeten	if (comedi_dio_update_state(s, data))
668dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten		outl(s->state, dev->iobase + 48);
669c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten
670c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten	data[1] = s->state;
671c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten
672c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten	return insn->n;
673c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten}
674c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten
675da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweetenstatic int apci3xxx_dio_insn_config(struct comedi_device *dev,
676da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten				    struct comedi_subdevice *s,
677da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten				    struct comedi_insn *insn,
678da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten				    unsigned int *data)
679da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten{
680da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	unsigned int chan = CR_CHAN(insn->chanspec);
681b0377d4bd438d00310005190a46920cb0279106fChase Southwood	unsigned int mask = 0;
6825dacadcca3176e2b1f8db662e503c080484d71faH Hartley Sweeten	int ret;
683da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
684da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	/*
685da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	 * Port 0 (channels 0-7) are always inputs
686da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	 * Port 1 (channels 8-15) are always outputs
687da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	 * Port 2 (channels 16-23) are programmable i/o
688da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	 */
689b0377d4bd438d00310005190a46920cb0279106fChase Southwood	if (data[0] != INSN_CONFIG_DIO_QUERY) {
690b0377d4bd438d00310005190a46920cb0279106fChase Southwood		/* ignore all other instructions for ports 0 and 1 */
691b0377d4bd438d00310005190a46920cb0279106fChase Southwood		if (chan < 16)
6925dacadcca3176e2b1f8db662e503c080484d71faH Hartley Sweeten			return -EINVAL;
6939ed221faae72ab1ad16e5f51d9f290e77af2c795H Hartley Sweeten
6949ed221faae72ab1ad16e5f51d9f290e77af2c795H Hartley Sweeten		/* changing any channel in port 2 changes the entire port */
6959ed221faae72ab1ad16e5f51d9f290e77af2c795H Hartley Sweeten		mask = 0xff0000;
696da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	}
697da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
6985dacadcca3176e2b1f8db662e503c080484d71faH Hartley Sweeten	ret = comedi_dio_insn_config(dev, s, insn, data, mask);
6995dacadcca3176e2b1f8db662e503c080484d71faH Hartley Sweeten	if (ret)
7005dacadcca3176e2b1f8db662e503c080484d71faH Hartley Sweeten		return ret;
7015dacadcca3176e2b1f8db662e503c080484d71faH Hartley Sweeten
702da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	/* update port 2 configuration */
7035dacadcca3176e2b1f8db662e503c080484d71faH Hartley Sweeten	outl((s->io_bits >> 24) & 0xff, dev->iobase + 224);
704da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
705da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	return insn->n;
706da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten}
707da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
708da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweetenstatic int apci3xxx_dio_insn_bits(struct comedi_device *dev,
709da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten				  struct comedi_subdevice *s,
710da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten				  struct comedi_insn *insn,
711da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten				  unsigned int *data)
712da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten{
713ca5d4a20fb65a2ab2ad3c2797d7639d3dc64c147H Hartley Sweeten	unsigned int mask;
714da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	unsigned int val;
715da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
716ca5d4a20fb65a2ab2ad3c2797d7639d3dc64c147H Hartley Sweeten	mask = comedi_dio_update_state(s, data);
717da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	if (mask) {
718da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		if (mask & 0xff)
719dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten			outl(s->state & 0xff, dev->iobase + 80);
720da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		if (mask & 0xff0000)
721dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten			outl((s->state >> 16) & 0xff, dev->iobase + 112);
722da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	}
723da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
724dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten	val = inl(dev->iobase + 80);
725dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten	val |= (inl(dev->iobase + 64) << 8);
726da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	if (s->io_bits & 0xff0000)
727dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten		val |= (inl(dev->iobase + 112) << 16);
728da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	else
729dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten		val |= (inl(dev->iobase + 96) << 16);
730da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
731da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	data[1] = val;
732da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
733da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	return insn->n;
734da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten}
735da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
7365e72c7a50709e60663217704b30501bf34afa448H Hartley Sweetenstatic int apci3xxx_reset(struct comedi_device *dev)
73798d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten{
7385e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	unsigned int val;
7395e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	int i;
7405e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten
7415e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	/* Disable the interrupt */
7425e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	disable_irq(dev->irq);
7435e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten
7445e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	/* Clear the start command */
74524a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	writel(0, dev->mmio + 8);
7465e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten
7475e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	/* Reset the interrupt flags */
74824a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	val = readl(dev->mmio + 16);
74924a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	writel(val, dev->mmio + 16);
7505e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten
7515e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	/* clear the EOS */
75224a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	readl(dev->mmio + 20);
7535e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten
7545e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	/* Clear the FIFO */
7555e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	for (i = 0; i < 16; i++)
75624a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten		val = readl(dev->mmio + 28);
7575e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten
7585e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	/* Enable the interrupt */
7595e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	enable_irq(dev->irq);
76098d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
76198d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	return 0;
76298d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten}
76398d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
764dbae4575661da840353f12dd76499ad587c92519H Hartley Sweetenstatic int apci3xxx_auto_attach(struct comedi_device *dev,
765dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten				unsigned long context)
766dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten{
76798d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
768e053b2419f5f0cff8ced6a8e39a93d113d9cd86aH Hartley Sweeten	const struct apci3xxx_boardinfo *board = NULL;
7691867add98e44d4bec01572b4cfd4becd11297e5dH Hartley Sweeten	struct apci3xxx_private *devpriv;
77098d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	struct comedi_subdevice *s;
771656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten	int n_subdevices;
772656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten	int subdev;
773656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten	int ret;
774dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten
775dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	if (context < ARRAY_SIZE(apci3xxx_boardtypes))
776dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten		board = &apci3xxx_boardtypes[context];
777dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	if (!board)
778dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten		return -ENODEV;
779dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	dev->board_ptr = board;
7806abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten	dev->board_name = board->name;
78198d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
7820bdab509bf9c6d838dc0a3b1d68bbf841fc20b5aH Hartley Sweeten	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
78398d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	if (!devpriv)
78498d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten		return -ENOMEM;
78598d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
78698d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	ret = comedi_pci_enable(dev);
78798d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	if (ret)
78898d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten		return ret;
78998d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
7902107347327f7bfd47e6af9fe0510a1750f10f884H Hartley Sweeten	dev->iobase = pci_resource_start(pcidev, 2);
79124a446127966eb309dbdb9c5b72c5cd59bd6edf9H Hartley Sweeten	dev->mmio = pci_ioremap_bar(pcidev, 3);
79298d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
79398d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	if (pcidev->irq > 0) {
7946c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten		ret = request_irq(pcidev->irq, apci3xxx_irq_handler,
7956c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten				  IRQF_SHARED, dev->board_name, dev);
79698d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten		if (ret == 0)
79798d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten			dev->irq = pcidev->irq;
79898d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	}
79998d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
800656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten	n_subdevices = (board->ai_n_chan ? 0 : 1) + board->has_ao +
801656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten		       board->has_dig_in + board->has_dig_out +
802656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten		       board->has_ttl_io;
80398d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	ret = comedi_alloc_subdevices(dev, n_subdevices);
80498d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	if (ret)
80598d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten		return ret;
80698d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
807656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten	subdev = 0;
808656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten
809308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten	/* Analog Input subdevice */
8108d4729066cde58c730573d6aad2ea29f8048fcb3H Hartley Sweeten	if (board->ai_n_chan) {
811656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten		s = &dev->subdevices[subdev];
812308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten		s->type		= COMEDI_SUBD_AI;
813308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten		s->subdev_flags	= SDF_READABLE | board->ai_subdev_flags;
814308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten		s->n_chan	= board->ai_n_chan;
815308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten		s->maxdata	= board->ai_maxdata;
816308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten		s->range_table	= &apci3xxx_ai_range;
817308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten		s->insn_read	= apci3xxx_ai_insn_read;
81866573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten		if (dev->irq) {
8197c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			/*
8207c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 * FIXME: The hardware supports multiple scan modes
8217c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 * but the original addi-data driver only supported
8227c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 * reading a single channel with interrupts. Need a
8237c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 * proper datasheet to fix this.
8247c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 *
8257c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 * The following scan modes are supported by the
8267c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 * hardware:
8277c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 *   1) Single software scan
8287c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 *   2) Single hardware triggered scan
8297c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 *   3) Continuous software scan
8307c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 *   4) Continuous software scan with timer delay
8317c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 *   5) Continuous hardware triggered scan
8327c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 *   6) Continuous hardware triggered scan with timer
8337c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 *      delay
8347c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 *
8357c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 * For now, limit the chanlist to a single channel.
8367c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			 */
83766573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			dev->read_subdev = s;
83866573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			s->subdev_flags	|= SDF_CMD_READ;
8397c9fc34ea3ed02d7d8356094ac179e1c63ae443bH Hartley Sweeten			s->len_chanlist	= 1;
84066573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			s->do_cmdtest	= apci3xxx_ai_cmdtest;
84166573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			s->do_cmd	= apci3xxx_ai_cmd;
84266573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			s->cancel	= apci3xxx_ai_cancel;
84366573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten		}
844656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten
845656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten		subdev++;
84698d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	}
84798d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
8480e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	/* Analog Output subdevice */
849fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten	if (board->has_ao) {
850656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten		s = &dev->subdevices[subdev];
8510e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		s->type		= COMEDI_SUBD_AO;
8520e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		s->subdev_flags	= SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
8530e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		s->n_chan	= 4;
8540e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		s->maxdata	= 0x0fff;
8550e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		s->range_table	= &apci3xxx_ao_range;
8560e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		s->insn_write	= apci3xxx_ao_insn_write;
857b38d64946f8e78055f742f23678b5ebed674a5b3H Hartley Sweeten		s->insn_read	= comedi_readback_insn_read;
858b38d64946f8e78055f742f23678b5ebed674a5b3H Hartley Sweeten
859b38d64946f8e78055f742f23678b5ebed674a5b3H Hartley Sweeten		ret = comedi_alloc_subdev_readback(s);
860b38d64946f8e78055f742f23678b5ebed674a5b3H Hartley Sweeten		if (ret)
861b38d64946f8e78055f742f23678b5ebed674a5b3H Hartley Sweeten			return ret;
862656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten
863656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten		subdev++;
86498d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	}
865ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten
866ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten	/* Digital Input subdevice */
8674aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten	if (board->has_dig_in) {
868656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten		s = &dev->subdevices[subdev];
869ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->type		= COMEDI_SUBD_DI;
870ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->subdev_flags	= SDF_READABLE;
871ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->n_chan	= 4;
872ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->maxdata	= 1;
873ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->range_table	= &range_digital;
874ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->insn_bits	= apci3xxx_di_insn_bits;
875656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten
876656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten		subdev++;
87798d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	}
878ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten
879ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten	/* Digital Output subdevice */
8804aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten	if (board->has_dig_out) {
881656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten		s = &dev->subdevices[subdev];
882ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->type		= COMEDI_SUBD_DO;
883ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->subdev_flags	= SDF_WRITEABLE;
884ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->n_chan	= 4;
885ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->maxdata	= 1;
886ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->range_table	= &range_digital;
887ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->insn_bits	= apci3xxx_do_insn_bits;
88898d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
889656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten		subdev++;
890656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten	}
89198d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
892383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten	/* TTL Digital I/O subdevice */
8930ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten	if (board->has_ttl_io) {
894656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten		s = &dev->subdevices[subdev];
895383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten		s->type		= COMEDI_SUBD_DIO;
896383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten		s->subdev_flags	= SDF_READABLE | SDF_WRITEABLE;
897383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten		s->n_chan	= 24;
898383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten		s->maxdata	= 1;
899383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten		s->io_bits	= 0xff;	/* channels 0-7 are always outputs */
900383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten		s->range_table	= &range_digital;
901da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		s->insn_config	= apci3xxx_dio_insn_config;
902da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		s->insn_bits	= apci3xxx_dio_insn_bits;
90398d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
904656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten		subdev++;
905656e39fedcf01b688a2aa1dca78c6c2a571264f1H Hartley Sweeten	}
90698d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
9075e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	apci3xxx_reset(dev);
90898d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	return 0;
90998d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten}
91098d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
91198d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweetenstatic void apci3xxx_detach(struct comedi_device *dev)
91298d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten{
913aac307f9dd5ce1fe651140a036ab4b0a0571b54aH Hartley Sweeten	if (dev->iobase)
914aac307f9dd5ce1fe651140a036ab4b0a0571b54aH Hartley Sweeten		apci3xxx_reset(dev);
915aac307f9dd5ce1fe651140a036ab4b0a0571b54aH Hartley Sweeten	comedi_pci_detach(dev);
916dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten}
917dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten
91820a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct comedi_driver apci3xxx_driver = {
91920a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.driver_name	= "addi_apci_3xxx",
92020a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.module		= THIS_MODULE,
921dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	.auto_attach	= apci3xxx_auto_attach,
92298d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	.detach		= apci3xxx_detach,
92320a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten};
92420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten
925a690b7e535f2f97a3a05ee570715abeb60a8910fBill Pembertonstatic int apci3xxx_pci_probe(struct pci_dev *dev,
926b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten			      const struct pci_device_id *id)
92720a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten{
928b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten	return comedi_pci_auto_config(dev, &apci3xxx_driver, id->driver_data);
92920a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten}
93020a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten
93141e043fcfa2236bb2c4a8335eb09f4c8cee224b3Jingoo Hanstatic const struct pci_device_id apci3xxx_pci_table[] = {
932dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3010), BOARD_APCI3000_16 },
933dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x300f), BOARD_APCI3000_8 },
934dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x300e), BOARD_APCI3000_4 },
935dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3013), BOARD_APCI3006_16 },
936dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3014), BOARD_APCI3006_8 },
937dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3015), BOARD_APCI3006_4 },
938dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3016), BOARD_APCI3010_16 },
939dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3017), BOARD_APCI3010_8 },
940dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3018), BOARD_APCI3010_4 },
941dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3019), BOARD_APCI3016_16 },
942dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x301a), BOARD_APCI3016_8 },
943dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x301b), BOARD_APCI3016_4 },
944dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x301c), BOARD_APCI3100_16_4 },
945dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x301d), BOARD_APCI3100_8_4 },
946dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x301e), BOARD_APCI3106_16_4 },
947dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x301f), BOARD_APCI3106_8_4 },
948dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3020), BOARD_APCI3110_16_4 },
949dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3021), BOARD_APCI3110_8_4 },
950dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3022), BOARD_APCI3116_16_4 },
951dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3023), BOARD_APCI3116_8_4 },
952dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x300B), BOARD_APCI3003 },
953dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3002), BOARD_APCI3002_16 },
954dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3003), BOARD_APCI3002_8 },
955dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3004), BOARD_APCI3002_4 },
956dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3024), BOARD_APCI3500 },
957317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten	{ 0 }
958317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten};
95920a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley SweetenMODULE_DEVICE_TABLE(pci, apci3xxx_pci_table);
960317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten
96120a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct pci_driver apci3xxx_pci_driver = {
96220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.name		= "addi_apci_3xxx",
96320a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.id_table	= apci3xxx_pci_table,
96420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.probe		= apci3xxx_pci_probe,
9659901a4d75d007686e8f6473189cafc4b216b7449Peter Huewe	.remove		= comedi_pci_auto_unconfig,
96620a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten};
96720a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenmodule_comedi_pci_driver(apci3xxx_driver, apci3xxx_pci_driver);
96890f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas
96990f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
97090f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver");
97190f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
972