addi_apci_3xxx.c revision f32376e993a7657198974e713577152ac67833db
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
2533782dd5edf8db3cdb7c81a3523bf743dd0209b7H Hartley Sweeten#include <linux/pci.h>
261867add98e44d4bec01572b4cfd4becd11297e5dH Hartley Sweeten#include <linux/interrupt.h>
2733782dd5edf8db3cdb7c81a3523bf743dd0209b7H Hartley Sweeten
283d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten#include "../comedidev.h"
293d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten
30f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten#include "comedi_fc.h"
31f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
32a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten#define CONV_UNIT_NS		(1 << 0)
33a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten#define CONV_UNIT_US		(1 << 1)
34a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten#define CONV_UNIT_MS		(1 << 2)
35a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten
3698a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweetenstatic const struct comedi_lrange apci3xxx_ai_range = {
3798a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten	8, {
3898a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		BIP_RANGE(10),
3998a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		BIP_RANGE(5),
4098a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		BIP_RANGE(2),
4198a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		BIP_RANGE(1),
4298a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		UNI_RANGE(10),
4398a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		UNI_RANGE(5),
4498a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		UNI_RANGE(2),
4598a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		UNI_RANGE(1)
4698a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten	}
4798a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten};
4898a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten
4998a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweetenstatic const struct comedi_lrange apci3xxx_ao_range = {
5098a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten	2, {
5198a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		BIP_RANGE(10),
5298a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten		UNI_RANGE(10)
5398a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten	}
5498a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten};
5598a856213efb9fec7a45491170d9b589ce55572dH Hartley Sweeten
56dbae4575661da840353f12dd76499ad587c92519H Hartley Sweetenenum apci3xxx_boardid {
57dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3000_16,
58dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3000_8,
59dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3000_4,
60dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3006_16,
61dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3006_8,
62dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3006_4,
63dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3010_16,
64dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3010_8,
65dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3010_4,
66dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3016_16,
67dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3016_8,
68dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3016_4,
69dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3100_16_4,
70dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3100_8_4,
71dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3106_16_4,
72dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3106_8_4,
73dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3110_16_4,
74dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3110_8_4,
75dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3116_16_4,
76dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3116_8_4,
77dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3003,
78dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3002_16,
79dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3002_8,
80dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3002_4,
81dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	BOARD_APCI3500,
82dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten};
83dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten
84e053b2419f5f0cff8ced6a8e39a93d113d9cd86aH Hartley Sweetenstruct apci3xxx_boardinfo {
856abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten	const char *name;
868a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten	int ai_subdev_flags;
8747bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten	int ai_n_chan;
885469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten	unsigned int ai_maxdata;
89a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten	unsigned char ai_conv_units;
908edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten	unsigned int ai_min_acq_ns;
91fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten	unsigned int has_ao:1;
924aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten	unsigned int has_dig_in:1;
934aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten	unsigned int has_dig_out:1;
940ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten	unsigned int has_ttl_io:1;
95e053b2419f5f0cff8ced6a8e39a93d113d9cd86aH Hartley Sweeten};
96e053b2419f5f0cff8ced6a8e39a93d113d9cd86aH Hartley Sweeten
97e053b2419f5f0cff8ced6a8e39a93d113d9cd86aH Hartley Sweetenstatic const struct apci3xxx_boardinfo apci3xxx_boardtypes[] = {
98dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3000_16] = {
996abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3000-16",
1008a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
10147bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
1025469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
103a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1048edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
1050ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
106dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
107dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3000_8] = {
1086abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3000-8",
1098a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
11047bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
1115469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
112a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1138edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
1140ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
115dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
116dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3000_4] = {
1176abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3000-4",
1188a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
11947bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 4,
1205469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
121a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1228edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
1230ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
124dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
125dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3006_16] = {
1266abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3006-16",
1278a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
12847bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
1295469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
130a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1318edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
1320ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
133dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
134dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3006_8] = {
1356abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3006-8",
1368a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
13747bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
1385469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
139a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1408edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
1410ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
142dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
143dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3006_4] = {
1446abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3006-4",
1458a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
14647bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 4,
1475469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
148a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1498edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
1500ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
151dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
152dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3010_16] = {
1536abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3010-16",
1548a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
15547bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
1565469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
157a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1588edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
1594aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
1604aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
1610ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
162dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
163dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3010_8] = {
1646abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3010-8",
1658a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
16647bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
1675469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
168a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1698edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
1704aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
1714aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
1720ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
173dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
174dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3010_4] = {
1756abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3010-4",
1768a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
17747bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 4,
1785469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
179a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1808edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
1814aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
1824aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
1830ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
184dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
185dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3016_16] = {
1866abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3016-16",
1878a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
18847bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
1895469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
190a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
1918edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
1924aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
1934aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
1940ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
195dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
196dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3016_8] = {
1976abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3016-8",
1988a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
19947bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
2005469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
201a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2028edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
2034aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
2044aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
2050ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
206dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
207dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3016_4] = {
2086abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3016-4",
2098a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
21047bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 4,
2115469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
212a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2138edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
2144aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
2154aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
2160ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
217dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
218dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3100_16_4] = {
2196abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3100-16-4",
2208a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
22147bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
2225469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
223a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2248edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
225fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2260ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
227dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
228dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3100_8_4] = {
2296abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3100-8-4",
2308a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
23147bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
2325469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
233a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2348edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
235fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2360ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
237dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
238dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3106_16_4] = {
2396abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3106-16-4",
2408a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
24147bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
2425469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
243a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2448edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
245fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2460ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
247dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
248dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3106_8_4] = {
2496abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3106-8-4",
2508a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
25147bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
2525469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
253a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2548edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 10000,
255fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2560ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
257dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
258dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3110_16_4] = {
2596abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3110-16-4",
2608a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
26147bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
2625469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
263a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2648edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
265fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2664aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
2674aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
2680ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
269dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
270dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3110_8_4] = {
2716abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3110-8-4",
2728a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
27347bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
2745469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0x0fff,
275a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2768edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
277fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2784aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
2794aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
2800ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
281dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
282dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3116_16_4] = {
2836abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3116-16-4",
2848a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
28547bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 16,
2865469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
287a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
2888edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
289fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
2904aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
2914aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
2920ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
293dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
294dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3116_8_4] = {
2956abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3116-8-4",
2968a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
29747bd1ad800470f4786f7d35379798a7a10aff84cH Hartley Sweeten		.ai_n_chan		= 8,
2985469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
299a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
3008edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
301fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
3024aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
3034aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
3040ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
305dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
306dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3003] = {
3076abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3003",
3088a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_DIFF,
3098d4729066cde58c730573d6aad2ea29f8048fcb3H Hartley Sweeten		.ai_n_chan		= 4,
3105469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
311a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US |
312a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten					  CONV_UNIT_NS,
3138edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 2500,
3144aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
3154aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
316dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
317dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3002_16] = {
3186abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3002-16",
3198a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_DIFF,
3208d4729066cde58c730573d6aad2ea29f8048fcb3H Hartley Sweeten		.ai_n_chan		= 16,
3215469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
322a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
3238edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
3244aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
3254aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
326dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
327dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3002_8] = {
3286abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3002-8",
3298a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_DIFF,
3308d4729066cde58c730573d6aad2ea29f8048fcb3H Hartley Sweeten		.ai_n_chan		= 8,
3315469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
332a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
3338edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
3344aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
3354aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
336dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
337dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3002_4] = {
3386abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3002-4",
3398a1ec30d75d844d21c5034152242a087230e40e5H Hartley Sweeten		.ai_subdev_flags	= SDF_DIFF,
3408d4729066cde58c730573d6aad2ea29f8048fcb3H Hartley Sweeten		.ai_n_chan		= 4,
3415469d929087c135b5978b1f5628ec897d5c55d9fH Hartley Sweeten		.ai_maxdata		= 0xffff,
342a67e0cc7aa3f15a4aa3e88945cd1d2476149191fH Hartley Sweeten		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
3438edd44251eb35b92f381b8caf495f6cc8483bc27H Hartley Sweeten		.ai_min_acq_ns		= 5000,
3444aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_in		= 1,
3454aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten		.has_dig_out		= 1,
346dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	},
347dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	[BOARD_APCI3500] = {
3486abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten		.name			= "apci3500",
349fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten		.has_ao			= 1,
3500ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten		.has_ttl_io		= 1,
351c0a053b8b24d72413a82a16a41f635e6040ccf34H Hartley Sweeten	},
352c0a053b8b24d72413a82a16a41f635e6040ccf34H Hartley Sweeten};
353c0a053b8b24d72413a82a16a41f635e6040ccf34H Hartley Sweeten
3541867add98e44d4bec01572b4cfd4becd11297e5dH Hartley Sweetenstruct apci3xxx_private {
355f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten	void __iomem *mmio;
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;
3631867add98e44d4bec01572b4cfd4becd11297e5dH Hartley Sweeten	struct apci3xxx_private *devpriv = dev->private;
364f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	struct comedi_subdevice *s = dev->read_subdev;
3656c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten	unsigned int status;
366f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int val;
3676c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten
3686c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten	/* Test if interrupt occur */
369f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten	status = readl(devpriv->mmio + 16);
3706c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten	if ((status & 0x2) == 0x2) {
3716c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten		/* Reset the interrupt */
372f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten		writel(status, devpriv->mmio + 16);
3736c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten
374f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		val = readl(devpriv->mmio + 28);
375f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		comedi_buf_put(s->async, val);
376f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
377f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		s->async->events |= COMEDI_CB_EOA;
378f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		comedi_event(dev, s);
379f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
380f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return IRQ_HANDLED;
381f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	}
382f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	return IRQ_NONE;
383f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten}
384f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
385f32376e993a7657198974e713577152ac67833dbH Hartley Sweetenstatic int apci3xxx_ai_started(struct comedi_device *dev)
386f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten{
387f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	struct apci3xxx_private *devpriv = dev->private;
388f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
389f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if ((readl(devpriv->mmio + 8) & 0x80000) == 0x80000)
390f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return 1;
391f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	else
392f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return 0;
393f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
394f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten}
395f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
396f32376e993a7657198974e713577152ac67833dbH Hartley Sweetenstatic int apci3xxx_ai_setup(struct comedi_device *dev, unsigned int chanspec)
397f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten{
398f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	struct apci3xxx_private *devpriv = dev->private;
399f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int chan = CR_CHAN(chanspec);
400f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int range = CR_RANGE(chanspec);
401f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int aref = CR_AREF(chanspec);
402f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int delay_mode;
403f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int val;
404f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
405f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (apci3xxx_ai_started(dev))
406f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return -EBUSY;
407f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
408f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Clear the FIFO */
409f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	writel(0x10000, devpriv->mmio + 12);
410f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
411f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Get and save the delay mode */
412f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	delay_mode = readl(devpriv->mmio + 4);
413f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	delay_mode &= 0xfffffef0;
414f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
415f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Channel configuration selection */
416f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	writel(delay_mode, devpriv->mmio + 4);
417f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
418f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Make the configuration */
419f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	val = (range & 3) | ((range >> 2) << 6) |
420f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	      ((aref == AREF_DIFF) << 7);
421f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	writel(val, devpriv->mmio + 0);
422f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
423f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Channel selection */
424f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	writel(delay_mode | 0x100, devpriv->mmio + 4);
425f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	writel(chan, devpriv->mmio + 0);
426f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
427f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Restore delay mode */
428f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	writel(delay_mode, devpriv->mmio + 4);
429f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
430f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Set the number of sequence to 1 */
431f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	writel(1, devpriv->mmio + 48);
432f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
433f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	return 0;
434f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten}
435f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
436f32376e993a7657198974e713577152ac67833dbH Hartley Sweetenstatic int apci3xxx_ai_insn_read(struct comedi_device *dev,
437f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten				 struct comedi_subdevice *s,
438f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten				 struct comedi_insn *insn,
439f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten				 unsigned int *data)
440f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten{
441f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	struct apci3xxx_private *devpriv = dev->private;
442f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int val;
443f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	int ret;
444f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	int i;
445f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
446f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	ret = apci3xxx_ai_setup(dev, insn->chanspec);
447f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (ret)
448f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return ret;
449f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
450f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	for (i = 0; i < insn->n; i++) {
451f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		/* Start the conversion */
452f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		writel(0x80000, devpriv->mmio + 8);
453f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
454f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		/* Wait the EOS */
455f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		do {
456f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			val = readl(devpriv->mmio + 20);
457f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			val &= 0x1;
458f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		} while (!val);
459f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
460f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		/* Read the analog value */
461f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		data[i] = readl(devpriv->mmio + 28);
462f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	}
4636c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten
464f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	return insn->n;
465f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten}
466f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
467f32376e993a7657198974e713577152ac67833dbH Hartley Sweetenstatic int apci3xxx_ai_ns_to_timer(struct comedi_device *dev,
468f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten				   unsigned int *ns, int round_mode)
469f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten{
470f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	const struct apci3xxx_boardinfo *board = comedi_board(dev);
471f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	struct apci3xxx_private *devpriv = dev->private;
472f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int base;
473f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int timer;
474f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	int time_base;
475f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
476f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* time_base: 0 = ns, 1 = us, 2 = ms */
477f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	for (time_base = 0; time_base < 3; time_base++) {
478f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		/* skip unsupported time bases */
479f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		if (!(board->ai_conv_units & (1 << time_base)))
480f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			continue;
481f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
482f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		switch (time_base) {
483f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		case 0:
484f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			base = 1;
485f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			break;
486f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		case 1:
487f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			base = 1000;
488f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			break;
489f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		case 2:
490f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			base = 1000000;
491f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			break;
492f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		}
4936c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten
494f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		switch (round_mode) {
495f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		case TRIG_ROUND_NEAREST:
496f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		default:
497f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			timer = (*ns + base / 2) / base;
498f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			break;
499f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		case TRIG_ROUND_DOWN:
500f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			timer = *ns / base;
501f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			break;
502f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		case TRIG_ROUND_UP:
503f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			timer = (*ns + base - 1) / base;
504f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			break;
505f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		}
5066c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten
507f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		if (timer < 0x10000) {
508f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			devpriv->ai_time_base = time_base;
509f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			devpriv->ai_timer = timer;
510f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			*ns = timer * time_base;
511f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten			return 0;
5126c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten		}
5136c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten	}
514f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	return -EINVAL;
5156c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten}
5166c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten
51766573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweetenstatic int apci3xxx_ai_cmdtest(struct comedi_device *dev,
51866573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			       struct comedi_subdevice *s,
51966573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			       struct comedi_cmd *cmd)
52066573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten{
521f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	const struct apci3xxx_boardinfo *board = comedi_board(dev);
522f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	int err = 0;
523f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	unsigned int tmp;
524f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
525f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Step 1 : check if triggers are trivially valid */
526f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
527f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
528f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
529f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
530f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
531f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
532f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
533f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (err)
534f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return 1;
535f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
536f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Step 2a : make sure trigger sources are unique */
537f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
538f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_is_unique(cmd->stop_src);
539f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
540f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Step 2b : and mutually compatible */
541f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
542f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (err)
543f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return 2;
544f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
545f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Step 3: check if arguments are trivially valid */
546f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
547f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
548f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
549f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
550f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten					 board->ai_min_acq_ns);
551f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
552f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
553f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (cmd->stop_src == TRIG_COUNT)
554f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
555f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	else	/* TRIG_NONE */
556f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
557f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
558f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (err)
559f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return 3;
560f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
561f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* step 4: fix up any arguments */
562f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
563f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/*
564f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 * FIXME: The hardware supports multiple scan modes but the original
565f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 * addi-data driver only supported reading a single channel with
566f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 * interrupts. Need a proper datasheet to fix this.
567f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 *
568f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 * The following scan modes are supported by the hardware:
569f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 * 1) Single software scan
570f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 * 2) Single hardware triggered scan
571f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 * 3) Continuous software scan
572f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 * 4) Continuous software scan with timer delay
573f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 * 5) Continuous hardware triggered scan
574f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 * 6) Continuous hardware triggered scan with timer delay
575f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 *
576f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 * For now, limit the chanlist to a single channel.
577f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	 */
578f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (cmd->chanlist_len > 1) {
579f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		cmd->chanlist_len = 1;
580f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		err |= -EINVAL;
581f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	}
582f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
583f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	tmp = cmd->convert_arg;
584f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	err |= apci3xxx_ai_ns_to_timer(dev, &cmd->convert_arg,
585f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten				       cmd->flags & TRIG_ROUND_MASK);
586f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (tmp != cmd->convert_arg)
587f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		err |= -EINVAL;
588f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
589f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (err)
590f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return 4;
591f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
59266573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten	return 0;
59366573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten}
59466573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten
59566573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweetenstatic int apci3xxx_ai_cmd(struct comedi_device *dev,
59666573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			   struct comedi_subdevice *s)
59766573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten{
598f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	struct apci3xxx_private *devpriv = dev->private;
599f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	struct comedi_cmd *cmd = &s->async->cmd;
600f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	int ret;
601f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
602f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	ret = apci3xxx_ai_setup(dev, cmd->chanlist[0]);
603f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	if (ret)
604f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten		return ret;
605f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
606f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Set the convert timing unit */
607f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	writel(devpriv->ai_time_base, devpriv->mmio + 36);
608f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
609f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Set the convert timing */
610f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	writel(devpriv->ai_timer, devpriv->mmio + 32);
611f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
612f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	/* Start the conversion */
613f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten	writel(0x180000, devpriv->mmio + 8);
614f32376e993a7657198974e713577152ac67833dbH Hartley Sweeten
61566573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten	return 0;
61666573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten}
61766573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten
61866573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweetenstatic int apci3xxx_ai_cancel(struct comedi_device *dev,
61966573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			      struct comedi_subdevice *s)
62066573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten{
62166573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten	return 0;
62266573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten}
62366573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten
6240e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweetenstatic int apci3xxx_ao_insn_write(struct comedi_device *dev,
6250e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten				  struct comedi_subdevice *s,
6260e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten				  struct comedi_insn *insn,
6270e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten				  unsigned int *data)
6280e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten{
6290e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	struct apci3xxx_private *devpriv = dev->private;
6300e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	unsigned int chan = CR_CHAN(insn->chanspec);
6310e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	unsigned int range = CR_RANGE(insn->chanspec);
6320e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	unsigned int status;
6330e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	int i;
6340e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten
6350e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	for (i = 0; i < insn->n; i++) {
6360e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		/* Set the range selection */
637f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten		writel(range, devpriv->mmio + 96);
6380e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten
6390e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		/* Write the analog value to the selected channel */
640f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten		writel((data[i] << 8) | chan, devpriv->mmio + 100);
6410e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten
6420e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		/* Wait the end of transfer */
6430e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		do {
644f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten			status = readl(devpriv->mmio + 96);
6450e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		} while ((status & 0x100) != 0x100);
6460e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	}
6470e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten
6480e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	return insn->n;
6490e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten}
6500e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten
651ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweetenstatic int apci3xxx_di_insn_bits(struct comedi_device *dev,
652ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten				 struct comedi_subdevice *s,
653ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten				 struct comedi_insn *insn,
654ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten				 unsigned int *data)
655ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten{
656dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten	data[1] = inl(dev->iobase + 32) & 0xf;
657ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten
658ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten	return insn->n;
659ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten}
660ae57b69639bcbd653821f7a4a14b87f6fa6743c0H Hartley Sweeten
661c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweetenstatic int apci3xxx_do_insn_bits(struct comedi_device *dev,
662c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten				 struct comedi_subdevice *s,
663c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten				 struct comedi_insn *insn,
664c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten				 unsigned int *data)
665c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten{
666c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten	unsigned int mask = data[0];
667c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten	unsigned int bits = data[1];
668c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten
669dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten	s->state = inl(dev->iobase + 48) & 0xf;
670c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten	if (mask) {
671c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten		s->state &= ~mask;
672c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten		s->state |= (bits & mask);
673c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten
674dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten		outl(s->state, dev->iobase + 48);
675c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten	}
676c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten
677c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten	data[1] = s->state;
678c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten
679c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten	return insn->n;
680c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten}
681c3d8605fca03adb70f712512b3df0e0311ac9b61H Hartley Sweeten
682da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweetenstatic int apci3xxx_dio_insn_config(struct comedi_device *dev,
683da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten				    struct comedi_subdevice *s,
684da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten				    struct comedi_insn *insn,
685da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten				    unsigned int *data)
686da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten{
687da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	unsigned int chan = CR_CHAN(insn->chanspec);
688da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	unsigned int mask = 1 << chan;
689da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	unsigned int bits;
690da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
691da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	/*
692da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	 * Port 0 (channels 0-7) are always inputs
693da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	 * Port 1 (channels 8-15) are always outputs
694da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	 * Port 2 (channels 16-23) are programmable i/o
695da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	 *
696da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	 * Changing any channel in port 2 changes the entire port.
697da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	 */
698da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	if (mask & 0xff0000)
699da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		bits = 0xff0000;
700da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	else
701da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		bits = 0;
702da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
703da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	switch (data[0]) {
704da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	case INSN_CONFIG_DIO_INPUT:
705da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		s->io_bits &= ~bits;
706da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		break;
707da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	case INSN_CONFIG_DIO_OUTPUT:
708da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		s->io_bits |= bits;
709da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		break;
710da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	case INSN_CONFIG_DIO_QUERY:
711da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
712da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		return insn->n;
713da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	default:
714da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		return -EINVAL;
715da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	}
716da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
717da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	/* update port 2 configuration */
718da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	if (bits)
719dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten		outl((s->io_bits >> 24) & 0xff, dev->iobase + 224);
720da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
721da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	return insn->n;
722da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten}
723da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
724da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweetenstatic int apci3xxx_dio_insn_bits(struct comedi_device *dev,
725da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten				  struct comedi_subdevice *s,
726da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten				  struct comedi_insn *insn,
727da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten				  unsigned int *data)
728da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten{
729da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	unsigned int mask = data[0];
730da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	unsigned int bits = data[1];
731da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	unsigned int val;
732da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
733da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	/* only update output channels */
734da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	mask &= s->io_bits;
735da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	if (mask) {
736da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		s->state &= ~mask;
737da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		s->state |= (bits & mask);
738da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
739da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		if (mask & 0xff)
740dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten			outl(s->state & 0xff, dev->iobase + 80);
741da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		if (mask & 0xff0000)
742dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten			outl((s->state >> 16) & 0xff, dev->iobase + 112);
743da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	}
744da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
745dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten	val = inl(dev->iobase + 80);
746dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten	val |= (inl(dev->iobase + 64) << 8);
747da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	if (s->io_bits & 0xff0000)
748dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten		val |= (inl(dev->iobase + 112) << 16);
749da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	else
750dc63364691322014e313d1eb740df1ade2a3b13dH Hartley Sweeten		val |= (inl(dev->iobase + 96) << 16);
751da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
752da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	data[1] = val;
753da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
754da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten	return insn->n;
755da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten}
756da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten
7575e72c7a50709e60663217704b30501bf34afa448H Hartley Sweetenstatic int apci3xxx_reset(struct comedi_device *dev)
75898d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten{
7591867add98e44d4bec01572b4cfd4becd11297e5dH Hartley Sweeten	struct apci3xxx_private *devpriv = dev->private;
7605e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	unsigned int val;
7615e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	int i;
7625e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten
7635e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	/* Disable the interrupt */
7645e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	disable_irq(dev->irq);
7655e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten
7665e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	/* Clear the start command */
767f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten	writel(0, devpriv->mmio + 8);
7685e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten
7695e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	/* Reset the interrupt flags */
770f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten	val = readl(devpriv->mmio + 16);
771f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten	writel(val, devpriv->mmio + 16);
7725e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten
7735e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	/* clear the EOS */
774f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten	readl(devpriv->mmio + 20);
7755e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten
7765e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	/* Clear the FIFO */
7775e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	for (i = 0; i < 16; i++)
778f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten		val = readl(devpriv->mmio + 28);
7795e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten
7805e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	/* Enable the interrupt */
7815e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	enable_irq(dev->irq);
78298d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
78398d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	return 0;
78498d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten}
78598d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
786dbae4575661da840353f12dd76499ad587c92519H Hartley Sweetenstatic int apci3xxx_auto_attach(struct comedi_device *dev,
787dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten				unsigned long context)
788dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten{
78998d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
790e053b2419f5f0cff8ced6a8e39a93d113d9cd86aH Hartley Sweeten	const struct apci3xxx_boardinfo *board = NULL;
7911867add98e44d4bec01572b4cfd4becd11297e5dH Hartley Sweeten	struct apci3xxx_private *devpriv;
79298d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	struct comedi_subdevice *s;
79398d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	int ret, n_subdevices;
794dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten
795dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	if (context < ARRAY_SIZE(apci3xxx_boardtypes))
796dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten		board = &apci3xxx_boardtypes[context];
797dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	if (!board)
798dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten		return -ENODEV;
799dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	dev->board_ptr = board;
8006abeba097bb32e82a8b9e0a748224574b588d3a3H Hartley Sweeten	dev->board_name = board->name;
80198d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
80298d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
80398d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	if (!devpriv)
80498d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten		return -ENOMEM;
80598d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	dev->private = devpriv;
80698d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
80798d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	ret = comedi_pci_enable(dev);
80898d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	if (ret)
80998d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten		return ret;
81098d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
8112107347327f7bfd47e6af9fe0510a1750f10f884H Hartley Sweeten	dev->iobase = pci_resource_start(pcidev, 2);
812f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten	devpriv->mmio = pci_ioremap_bar(pcidev, 3);
81398d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
81498d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	if (pcidev->irq > 0) {
8156c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten		ret = request_irq(pcidev->irq, apci3xxx_irq_handler,
8166c5b0fff8eb76913f0d38e72f4e68e19ea91de04H Hartley Sweeten				  IRQF_SHARED, dev->board_name, dev);
81798d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten		if (ret == 0)
81898d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten			dev->irq = pcidev->irq;
81998d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	}
82098d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
82198d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	n_subdevices = 7;
82298d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	ret = comedi_alloc_subdevices(dev, n_subdevices);
82398d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	if (ret)
82498d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten		return ret;
82598d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
826308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten	/* Analog Input subdevice */
82798d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	s = &dev->subdevices[0];
8288d4729066cde58c730573d6aad2ea29f8048fcb3H Hartley Sweeten	if (board->ai_n_chan) {
829308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten		s->type		= COMEDI_SUBD_AI;
830308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten		s->subdev_flags	= SDF_READABLE | board->ai_subdev_flags;
831308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten		s->n_chan	= board->ai_n_chan;
832308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten		s->maxdata	= board->ai_maxdata;
833308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten		s->len_chanlist	= s->n_chan;
834308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten		s->range_table	= &apci3xxx_ai_range;
835308380e69625c347f88ba23da9dc0e9a58918838H Hartley Sweeten		s->insn_read	= apci3xxx_ai_insn_read;
83666573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten		if (dev->irq) {
83766573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			dev->read_subdev = s;
83866573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			s->subdev_flags	|= SDF_CMD_READ;
83966573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			s->do_cmdtest	= apci3xxx_ai_cmdtest;
84066573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			s->do_cmd	= apci3xxx_ai_cmd;
84166573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten			s->cancel	= apci3xxx_ai_cancel;
84266573991c47f3e826f294b6ab4aa1cf967d5f426H Hartley Sweeten		}
84398d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	} else {
84498d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten		s->type = COMEDI_SUBD_UNUSED;
84598d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	}
84698d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
8470e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten	/* Analog Output subdevice */
84898d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	s = &dev->subdevices[1];
849fa81e2f186fb95dac1641e1e8d6740ed559e5204H Hartley Sweeten	if (board->has_ao) {
8500e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		s->type		= COMEDI_SUBD_AO;
8510e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		s->subdev_flags	= SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
8520e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		s->n_chan	= 4;
8530e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		s->maxdata	= 0x0fff;
8540e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		s->range_table	= &apci3xxx_ao_range;
8550e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		s->insn_write	= apci3xxx_ao_insn_write;
85698d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	} else {
8570e771e49fc2174054bbb4927f9afe8db4e16ae0bH Hartley Sweeten		s->type		= COMEDI_SUBD_UNUSED;
85898d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	}
859ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten
860ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten	/* Digital Input subdevice */
86198d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	s = &dev->subdevices[2];
8624aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten	if (board->has_dig_in) {
863ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->type		= COMEDI_SUBD_DI;
864ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->subdev_flags	= SDF_READABLE;
865ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->n_chan	= 4;
866ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->maxdata	= 1;
867ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->range_table	= &range_digital;
868ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->insn_bits	= apci3xxx_di_insn_bits;
86998d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	} else {
870ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->type		= COMEDI_SUBD_UNUSED;
87198d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	}
872ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten
873ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten	/* Digital Output subdevice */
87498d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	s = &dev->subdevices[3];
8754aab8bfd1db3455c062c332e56790e6f046284c7H Hartley Sweeten	if (board->has_dig_out) {
876ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->type		= COMEDI_SUBD_DO;
877ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->subdev_flags	= SDF_WRITEABLE;
878ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->n_chan	= 4;
879ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->maxdata	= 1;
880ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->range_table	= &range_digital;
881ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->insn_bits	= apci3xxx_do_insn_bits;
88298d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	} else {
883ca1cc85b0ea5d1c9de91ffebf4d5272bb5a61deeH Hartley Sweeten		s->type		= COMEDI_SUBD_UNUSED;
88498d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	}
88598d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
88698d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	/*  Allocate and Initialise Timer Subdevice Structures */
88798d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	s = &dev->subdevices[4];
888178bd8d3a61432ce24399604b13cc756293d1ac8H Hartley Sweeten	s->type = COMEDI_SUBD_UNUSED;
88998d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
890383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten	/* TTL Digital I/O subdevice */
89198d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	s = &dev->subdevices[5];
8920ed9f25fbc94e8cfe6f5929e6cafa98944d51617H Hartley Sweeten	if (board->has_ttl_io) {
893383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten		s->type		= COMEDI_SUBD_DIO;
894383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten		s->subdev_flags	= SDF_READABLE | SDF_WRITEABLE;
895383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten		s->n_chan	= 24;
896383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten		s->maxdata	= 1;
897383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten		s->io_bits	= 0xff;	/* channels 0-7 are always outputs */
898383390cfd4aefad6e00d4738233aa89901211fddH Hartley Sweeten		s->range_table	= &range_digital;
899da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		s->insn_config	= apci3xxx_dio_insn_config;
900da6578abd7c7535e59cae5eb0c54f5cd13902a6dH Hartley Sweeten		s->insn_bits	= apci3xxx_dio_insn_bits;
90198d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	} else {
90298d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten		s->type = COMEDI_SUBD_UNUSED;
90398d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	}
90498d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
90598d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	/* EEPROM */
90698d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	s = &dev->subdevices[6];
90793c0dc284dff2e2fec320662d8ef01b933096e36H Hartley Sweeten	s->type = COMEDI_SUBD_UNUSED;
90898d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
9095e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten	apci3xxx_reset(dev);
91098d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	return 0;
91198d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten}
91298d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten
91398d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweetenstatic void apci3xxx_detach(struct comedi_device *dev)
91498d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten{
9151867add98e44d4bec01572b4cfd4becd11297e5dH Hartley Sweeten	struct apci3xxx_private *devpriv = dev->private;
916dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten
91798d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	if (devpriv) {
91898d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten		if (dev->iobase)
9195e72c7a50709e60663217704b30501bf34afa448H Hartley Sweeten			apci3xxx_reset(dev);
92098d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten		if (dev->irq)
92198d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten			free_irq(dev->irq, dev);
922f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten		if (devpriv->mmio)
923f43abbb4ff4bbe7f92c1293c3aa06c1e43da7695H Hartley Sweeten			iounmap(devpriv->mmio);
92498d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	}
92598d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	comedi_pci_disable(dev);
926dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten}
927dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten
92820a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct comedi_driver apci3xxx_driver = {
92920a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.driver_name	= "addi_apci_3xxx",
93020a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.module		= THIS_MODULE,
931dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	.auto_attach	= apci3xxx_auto_attach,
93298d3385dd68381dd2738a825f8513366c44018b2H Hartley Sweeten	.detach		= apci3xxx_detach,
93320a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten};
93420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten
935a690b7e535f2f97a3a05ee570715abeb60a8910fBill Pembertonstatic int apci3xxx_pci_probe(struct pci_dev *dev,
936b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten			      const struct pci_device_id *id)
93720a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten{
938b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten	return comedi_pci_auto_config(dev, &apci3xxx_driver, id->driver_data);
93920a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten}
94020a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten
94120a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic DEFINE_PCI_DEVICE_TABLE(apci3xxx_pci_table) = {
942dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3010), BOARD_APCI3000_16 },
943dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x300f), BOARD_APCI3000_8 },
944dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x300e), BOARD_APCI3000_4 },
945dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3013), BOARD_APCI3006_16 },
946dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3014), BOARD_APCI3006_8 },
947dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3015), BOARD_APCI3006_4 },
948dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3016), BOARD_APCI3010_16 },
949dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3017), BOARD_APCI3010_8 },
950dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3018), BOARD_APCI3010_4 },
951dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3019), BOARD_APCI3016_16 },
952dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x301a), BOARD_APCI3016_8 },
953dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x301b), BOARD_APCI3016_4 },
954dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x301c), BOARD_APCI3100_16_4 },
955dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x301d), BOARD_APCI3100_8_4 },
956dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x301e), BOARD_APCI3106_16_4 },
957dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x301f), BOARD_APCI3106_8_4 },
958dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3020), BOARD_APCI3110_16_4 },
959dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3021), BOARD_APCI3110_8_4 },
960dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3022), BOARD_APCI3116_16_4 },
961dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3023), BOARD_APCI3116_8_4 },
962dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x300B), BOARD_APCI3003 },
963dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3002), BOARD_APCI3002_16 },
964dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3003), BOARD_APCI3002_8 },
965dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3004), BOARD_APCI3002_4 },
966dbae4575661da840353f12dd76499ad587c92519H Hartley Sweeten	{ PCI_VDEVICE(ADDIDATA, 0x3024), BOARD_APCI3500 },
967317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten	{ 0 }
968317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten};
96920a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley SweetenMODULE_DEVICE_TABLE(pci, apci3xxx_pci_table);
970317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten
97120a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct pci_driver apci3xxx_pci_driver = {
97220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.name		= "addi_apci_3xxx",
97320a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.id_table	= apci3xxx_pci_table,
97420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.probe		= apci3xxx_pci_probe,
9759901a4d75d007686e8f6473189cafc4b216b7449Peter Huewe	.remove		= comedi_pci_auto_unconfig,
97620a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten};
97720a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenmodule_comedi_pci_driver(apci3xxx_driver, apci3xxx_pci_driver);
97890f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas
97990f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
98090f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver");
98190f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
982