adl_pci9111.c revision 790c55415aa31f4c732729f94d2c3a54f7d3bfc2
18cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud/*
28cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
38cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud   comedi/drivers/adl_pci9111.c
48cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
58cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud   Hardware driver for PCI9111 ADLink cards:
68cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
78cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud     PCI-9111HR
88cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
98cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud   Copyright (C) 2002-2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    This program is free software; you can redistribute it and/or modify
128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    it under the terms of the GNU General Public License as published by
138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    the Free Software Foundation; either version 2 of the License, or
148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    (at your option) any later version.
158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    This program is distributed in the hope that it will be useful,
178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    but WITHOUT ANY WARRANTY; without even the implied warranty of
188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    GNU General Public License for more details.
208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    You should have received a copy of the GNU General Public License
228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    along with this program; if not, write to the Free Software
238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud*/
258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud/*
278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudDriver: adl_pci9111
288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudDescription: Adlink PCI-9111HR
298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudAuthor: Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudDevices: [ADLink] PCI-9111HR (adl_pci9111)
318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudStatus: experimental
328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudSupports:
348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  - ai_insn read
368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  - ao_insn read/write
378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  - di_insn read
388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  - do_insn read/write
398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  - ai_do_cmd mode with the following sources:
408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    - start_src 		TRIG_NOW
428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    - scan_begin_src 		TRIG_FOLLOW	TRIG_TIMER	TRIG_EXT
438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    - convert_src				TRIG_TIMER	TRIG_EXT
448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    - scan_end_src		TRIG_COUNT
458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    - stop_src			TRIG_COUNT	TRIG_NONE
468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    The scanned channels must be consecutive and start from 0. They must
488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    all have the same range and aref.
498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudConfiguration options:
518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    [0] - PCI bus number (optional)
538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    [1] - PCI slot number (optional)
548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    If bus/slot is not specified, the first available PCI
568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    device will be used.
578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud*/
598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud/*
618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudCHANGELOG:
628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  2005/02/17 Extend AI streaming capabilities. Now, scan_begin_arg can be
648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  a multiple of chanlist_len*convert_arg.
658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  2002/02/19 Fixed the two's complement conversion in pci9111_(hr_)ai_get_data.
668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  2002/02/18 Added external trigger support for analog input.
678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudTODO:
698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  - Really test implemented functionality.
718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  - Add support for the PCI-9111DG with a probe routine to identify the card type
728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    (perhaps with the help of the channel number readback of the A/D Data register).
738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  - Add external multiplexer support.
748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud*/
768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#include "../comedidev.h"
788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#include <linux/delay.h>
808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#include "8253.h"
828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#include "comedi_pci.h"
838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#include "comedi_fc.h"
848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_DRIVER_NAME 	"adl_pci9111"
868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_HR_DEVICE_ID 	0x9111
878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// TODO: Add other pci9111 board id
898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_IO_RANGE 	0x0100
918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_FIFO_HALF_SIZE	512
938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_CHANNEL_NBR			16
958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_RESOLUTION			12
978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_RESOLUTION_MASK		0x0FFF
988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_RESOLUTION_2_CMP_BIT		0x0800
998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_HR_AI_RESOLUTION		16
1018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_HR_AI_RESOLUTION_MASK		0xFFFF
1028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_HR_AI_RESOLUTION_2_CMP_BIT	0x8000
1038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS	10000
1058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AO_CHANNEL_NBR			1
1068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define	PCI9111_AO_RESOLUTION			12
1078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AO_RESOLUTION_MASK		0x0FFF
1088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_DI_CHANNEL_NBR			16
1098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define	PCI9111_DO_CHANNEL_NBR			16
1108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_DO_MASK				0xFFFF
1118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_RANGE_SETTING_DELAY		10
1138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_INSTANT_READ_UDELAY_US	2
1148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_INSTANT_READ_TIMEOUT		100
1158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_CLOCK_PERIOD_NS		500
1178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_COUNTER_0			0x00
1198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_COUNTER_1			0x40
1208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_COUNTER_2			0x80
1218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_COUNTER_LATCH		0x00
1228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_READ_LOAD_LSB_ONLY		0x10
1238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_READ_LOAD_MSB_ONLY		0x20
1248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_READ_LOAD_LSB_MSB		0x30
1258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_MODE_0			0x00
1268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_MODE_1			0x02
1278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_MODE_2			0x04
1288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_MODE_3			0x06
1298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_MODE_4			0x08
1308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_MODE_5			0x0A
1318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_BINARY_COUNTER		0x00
1328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_BCD_COUNTER		0x01
1338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud/* IO address map */
1358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_AD_FIFO_VALUE 			0x00	// AD Data stored in FIFO
1378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_DA_OUTPUT 			0x00
1388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_DIGITAL_IO 			0x02
1398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_EXTENDED_IO_PORTS 		0x04
1408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_AD_CHANNEL_CONTROL 		0x06	// Channel selection
1418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_AD_CHANNEL_READBACK 		0x06
1428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_INPUT_SIGNAL_RANGE 		0x08
1438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_RANGE_STATUS_READBACK 		0x08
1448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_TRIGGER_MODE_CONTROL 		0x0A
1458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK 	0x0A
1468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_SOFTWARE_TRIGGER 		0x0E
1478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_INTERRUPT_CONTROL 		0x0C
1488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_8254_COUNTER_0			0x40
1498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_8254_COUNTER_1			0x42
1508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_8254_COUNTER_2 		0X44
1518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_8254_CONTROL			0x46
1528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_INTERRUPT_CLEAR 		0x48
1538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_TRIGGER_MASK 				0x0F
1558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_PTRG_OFF 				(0 << 3)
1568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_PTRG_ON 				(1 << 3)
1578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_EITS_EXTERNAL				(1 << 2)
1588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_EITS_INTERNAL				(0 << 2)
1598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_TPST_SOFTWARE_TRIGGER			(0 << 1)
1608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_TPST_TIMER_PACER			(1 << 1)
1618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_ASCAN_ON				(1 << 0)
1628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_ASCAN_OFF				(0 << 0)
1638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_ISC0_SET_IRQ_ON_ENDING_OF_AD_CONVERSION (0 << 0)
1658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL		(1 << 0)
1668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_ISC1_SET_IRQ_ON_TIMER_TICK  		(0 << 1)
1678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_ISC1_SET_IRQ_ON_EXT_TRG 		(1 << 1)
1688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_FFEN_SET_FIFO_ENABLE 			(0 << 2)
1698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_FFEN_SET_FIFO_DISABLE			(1 << 2)
1708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_CHANNEL_MASK				0x0F
1728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_RANGE_MASK				0x07
1748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_FIFO_EMPTY_MASK				0x10
1758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_FIFO_HALF_FULL_MASK			0x20
1768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_FIFO_FULL_MASK				0x40
1778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AD_BUSY_MASK				0x80
1788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_IO_BASE dev->iobase
1808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud/*
1828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud * Define inlined function
1838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud */
1848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_trigger_and_autoscan_get() \
1868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK)&0x0F)
1878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_trigger_and_autoscan_set(flags) \
1898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb(flags,PCI9111_IO_BASE+PCI9111_REGISTER_TRIGGER_MODE_CONTROL)
1908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_interrupt_and_fifo_get() \
1928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) >> 4) &0x03)
1938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_interrupt_and_fifo_set(flags) \
1958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb(flags,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
1968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
1978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_interrupt_clear() \
1988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb(0,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CLEAR)
1998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_software_trigger() \
2018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb(0,PCI9111_IO_BASE+PCI9111_REGISTER_SOFTWARE_TRIGGER)
2028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_fifo_reset() \
2048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb(PCI9111_FFEN_SET_FIFO_ENABLE,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
2058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb(PCI9111_FFEN_SET_FIFO_DISABLE,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
2068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb(PCI9111_FFEN_SET_FIFO_ENABLE,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
2078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_is_fifo_full() \
2098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
2108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    PCI9111_FIFO_FULL_MASK)==0)
2118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_is_fifo_half_full() \
2138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
2148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    PCI9111_FIFO_HALF_FULL_MASK)==0)
2158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_is_fifo_empty() \
2178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
2188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud    PCI9111_FIFO_EMPTY_MASK)==0)
2198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_ai_channel_set(channel) \
2218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb((channel)&PCI9111_CHANNEL_MASK,PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_CONTROL)
2228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_ai_channel_get() \
2248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_READBACK)&PCI9111_CHANNEL_MASK
2258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_ai_range_set(range) \
2278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb((range)&PCI9111_RANGE_MASK,PCI9111_IO_BASE+PCI9111_REGISTER_INPUT_SIGNAL_RANGE)
2288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_ai_range_get() \
2308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)&PCI9111_RANGE_MASK
2318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_ai_get_data() \
2338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  ((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)>>4)&PCI9111_AI_RESOLUTION_MASK) \
2348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  ^ PCI9111_AI_RESOLUTION_2_CMP_BIT
2358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_hr_ai_get_data() \
2378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  (inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE) & PCI9111_HR_AI_RESOLUTION_MASK) \
2388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT
2398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_ao_set_data(data) \
2418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outw(data&PCI9111_AO_RESOLUTION_MASK,PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT)
2428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_di_get_bits() \
2448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  inw(PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
2458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_do_set_bits(bits) \
2478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outw(bits,PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
2488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_control_set(flags) \
2508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb(flags,PCI9111_IO_BASE+PCI9111_REGISTER_8254_CONTROL)
2518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_0_set(data) \
2538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \
2548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb( (data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0)
2558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_1_set(data) \
2578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \
2588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb( (data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1)
2598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_2_set(data) \
2618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \
2628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  outb( (data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2)
2638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
2658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// Function prototypes
2668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
2678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int pci9111_attach(comedi_device * dev, comedi_devconfig * it);
2698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int pci9111_detach(comedi_device * dev);
2708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic void pci9111_ai_munge(comedi_device * dev, comedi_subdevice * s,
2718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	void *data, unsigned int num_bytes, unsigned int start_chan_index);
2728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic const comedi_lrange pci9111_hr_ai_range = {
2748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	5,
2758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	{
2768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			BIP_RANGE(10),
2778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			BIP_RANGE(5),
2788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			BIP_RANGE(2.5),
2798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			BIP_RANGE(1.25),
2808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			BIP_RANGE(0.625)
2818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		}
2828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud};
2838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = {
2858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	{PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0,
2868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		0, 0},
2878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//{ PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
2888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	{0}
2898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud};
2908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudMODULE_DEVICE_TABLE(pci, pci9111_pci_table);
2928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
2948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// Board specification structure
2958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
2968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
2978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudtypedef struct {
2988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	const char *name;	// driver name
2998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int device_id;
3008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int ai_channel_nbr;	// num of A/D chans
3018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int ao_channel_nbr;	// num of D/A chans
3028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int ai_resolution;	// resolution of A/D
3038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int ai_resolution_mask;
3048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int ao_resolution;	// resolution of D/A
3058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int ao_resolution_mask;
3068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	const comedi_lrange *ai_range_list;	// rangelist for A/D
3078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	const comedi_lrange *ao_range_list;	// rangelist for D/A
3088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	unsigned int ai_acquisition_period_min_ns;
3098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} pci9111_board_struct;
3108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic const pci9111_board_struct pci9111_boards[] = {
3128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	{
3138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	      name:	"pci9111_hr",
3148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	      device_id:PCI9111_HR_DEVICE_ID,
3158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	      ai_channel_nbr:PCI9111_AI_CHANNEL_NBR,
3168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	      ao_channel_nbr:PCI9111_AO_CHANNEL_NBR,
3178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	      ai_resolution:PCI9111_HR_AI_RESOLUTION,
3188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	      ai_resolution_mask:PCI9111_HR_AI_RESOLUTION_MASK,
3198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	      ao_resolution:PCI9111_AO_RESOLUTION,
3208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	      ao_resolution_mask:PCI9111_AO_RESOLUTION_MASK,
3218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	      ai_range_list:&pci9111_hr_ai_range,
3228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	      ao_range_list:&range_bipolar10,
3238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud      ai_acquisition_period_min_ns:PCI9111_AI_ACQUISITION_PERIOD_MIN_NS}
3248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud};
3258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_board_nbr \
3278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  (sizeof(pci9111_boards)/sizeof(pci9111_board_struct))
3288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic comedi_driver pci9111_driver = {
3308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud      driver_name:PCI9111_DRIVER_NAME,
3318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud      module:THIS_MODULE,
3328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud      attach:pci9111_attach,
3338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud      detach:pci9111_detach,
3348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud};
3358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudCOMEDI_PCI_INITCLEANUP(pci9111_driver, pci9111_pci_table);
3378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
3398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// Private data structure
3408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
3418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudtypedef struct {
3438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	struct pci_dev *pci_device;
3448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	unsigned long io_range;	// PCI6503 io range
3458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	unsigned long lcr_io_base;	// Local configuration register base address
3478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	unsigned long lcr_io_range;
3488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int stop_counter;
3508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int stop_is_none;
3518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	unsigned int scan_delay;
3538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	unsigned int chanlist_len;
3548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	unsigned int chunk_counter;
3558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	unsigned int chunk_num_samples;
3568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int ao_readback;	// Last written analog output data
3588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int timer_divisor_1;	// Divisor values for the 8254 timer pacer
3608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int timer_divisor_2;
3618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int is_valid;		// Is device valid
3638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
364790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
3658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} pci9111_private_data_struct;
3668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define dev_private 	((pci9111_private_data_struct *)dev->private)
3688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
3708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
3718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// PLX9050 SECTION
3728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
3738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
3748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_REGISTER_INTERRUPT_CONTROL 0x4c
3768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_ENABLE		(1 << 0)
3788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_ACTIVE_HIGH	(1 << 1)
3798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_STATUS		(1 << 2)
3808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_ENABLE		(1 << 3)
3818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_ACTIVE_HIGH	(1 << 4)
3828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_STATUS		(1 << 5)
3838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_PCI_INTERRUPT_ENABLE	(1 << 6)
3848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_SOFTWARE_INTERRUPT	(1 << 7)
3858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic void plx9050_interrupt_control(unsigned long io_base,
3878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	bool LINTi1_enable,
3888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	bool LINTi1_active_high,
3898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	bool LINTi2_enable, bool LINTi2_active_high, bool interrupt_enable)
3908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
3918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int flags = 0;
3928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
3938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (LINTi1_enable)
3948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		flags |= PLX9050_LINTI1_ENABLE;
3958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (LINTi1_active_high)
3968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		flags |= PLX9050_LINTI1_ACTIVE_HIGH;
3978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (LINTi2_enable)
3988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		flags |= PLX9050_LINTI2_ENABLE;
3998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (LINTi2_active_high)
4008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		flags |= PLX9050_LINTI2_ACTIVE_HIGH;
4018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (interrupt_enable)
4038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		flags |= PLX9050_PCI_INTERRUPT_ENABLE;
4048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	outb(flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL);
4068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
4078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
4098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
4108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// MISCELLANEOUS SECTION
4118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
4128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
4138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
4158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// 8254 timer
4168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
4178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic void pci9111_timer_set(comedi_device * dev)
4198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
4208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_8254_control_set(PCI9111_8254_COUNTER_0 |
4218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		PCI9111_8254_READ_LOAD_LSB_MSB |
4228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		PCI9111_8254_MODE_0 | PCI9111_8254_BINARY_COUNTER);
4238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_8254_control_set(PCI9111_8254_COUNTER_1 |
4258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		PCI9111_8254_READ_LOAD_LSB_MSB |
4268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		PCI9111_8254_MODE_2 | PCI9111_8254_BINARY_COUNTER);
4278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_8254_control_set(PCI9111_8254_COUNTER_2 |
4298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		PCI9111_8254_READ_LOAD_LSB_MSB |
4308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		PCI9111_8254_MODE_2 | PCI9111_8254_BINARY_COUNTER);
4318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	comedi_udelay(1);
4338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_8254_counter_2_set(dev_private->timer_divisor_2);
4358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_8254_counter_1_set(dev_private->timer_divisor_1);
4368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
4378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudtypedef enum {
4398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	software,
4408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	timer_pacer,
4418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	external
4428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} pci9111_trigger_sources;
4438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic void pci9111_trigger_source_set(comedi_device * dev,
4458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_trigger_sources source)
4468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
4478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int flags;
4488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	flags = pci9111_trigger_and_autoscan_get() & 0x09;
4508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	switch (source) {
4528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	case software:
4538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_SOFTWARE_TRIGGER;
4548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		break;
4558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	case timer_pacer:
4578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_TIMER_PACER;
4588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		break;
4598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	case external:
4618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		flags |= PCI9111_EITS_EXTERNAL;
4628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		break;
4638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
4648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_trigger_and_autoscan_set(flags);
4668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
4678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic void pci9111_pretrigger_set(comedi_device * dev, bool pretrigger)
4698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
4708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int flags;
4718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	flags = pci9111_trigger_and_autoscan_get() & 0x07;
4738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (pretrigger)
4758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		flags |= PCI9111_PTRG_ON;
4768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_trigger_and_autoscan_set(flags);
4788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
4798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic void pci9111_autoscan_set(comedi_device * dev, bool autoscan)
4818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
4828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int flags;
4838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	flags = pci9111_trigger_and_autoscan_get() & 0x0e;
4858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (autoscan)
4878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		flags |= PCI9111_ASCAN_ON;
4888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_trigger_and_autoscan_set(flags);
4908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
4918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudtypedef enum {
4938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	irq_on_eoc,
4948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	irq_on_fifo_half_full
4958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} pci9111_ISC0_sources;
4968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
4978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudtypedef enum {
4988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	irq_on_timer_tick,
4998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	irq_on_external_trigger
5008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} pci9111_ISC1_sources;
5018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic void pci9111_interrupt_source_set(comedi_device * dev,
5038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_ISC0_sources irq_0_source, pci9111_ISC1_sources irq_1_source)
5048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
5058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int flags;
5068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	flags = pci9111_interrupt_and_fifo_get() & 0x04;
5088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (irq_0_source == irq_on_fifo_half_full)
5108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		flags |= PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL;
5118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (irq_1_source == irq_on_external_trigger)
5138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		flags |= PCI9111_ISC1_SET_IRQ_ON_EXT_TRG;
5148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_interrupt_and_fifo_set(flags);
5168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
5178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
5198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
5208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// HARDWARE TRIGGERED ANALOG INPUT SECTION
5218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
5228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
5238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
5258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// Cancel analog input autoscan
5268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
5278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef AI_DO_CMD_DEBUG
5298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int pci9111_ai_cancel(comedi_device * dev, comedi_subdevice * s)
5318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
5328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Disable interrupts
5338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
5358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		true, false);
5368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_trigger_source_set(dev, software);
5388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_autoscan_set(dev, false);
5408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_fifo_reset();
5428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG
5448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk(PCI9111_DRIVER_NAME ": ai_cancel\n");
5458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif
5468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	return 0;
5488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
5498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
5518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// Test analog input command
5528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
5538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_check_trigger_src(src,flags) \
5558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  tmp = src; \
5568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  src &= flags; \
5578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud  if (!src || tmp != src) error++
5588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int
5608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudpci9111_ai_do_cmd_test(comedi_device * dev,
5618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	comedi_subdevice * s, comedi_cmd * cmd)
5628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
5638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int tmp;
5648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int error = 0;
5658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int range, reference;
5668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int i;
5678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_board_struct *board = (pci9111_board_struct *) dev->board_ptr;
5688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Step 1 : check if trigger are trivialy valid
5708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_check_trigger_src(cmd->start_src, TRIG_NOW);
5728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_check_trigger_src(cmd->scan_begin_src,
5738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
5748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_check_trigger_src(cmd->convert_src, TRIG_TIMER | TRIG_EXT);
5758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_check_trigger_src(cmd->scan_end_src, TRIG_COUNT);
5768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_check_trigger_src(cmd->stop_src, TRIG_COUNT | TRIG_NONE);
5778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (error)
5798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return 1;
5808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// step 2 : make sure trigger sources are unique and mutually compatible
5828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (cmd->start_src != TRIG_NOW)
5848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
5858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->scan_begin_src != TRIG_TIMER) &&
5878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		(cmd->scan_begin_src != TRIG_FOLLOW) &&
5888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		(cmd->scan_begin_src != TRIG_EXT))
5898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
5908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
5918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT)) {
5928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
5938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
5948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->convert_src == TRIG_TIMER) &&
5958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		!((cmd->scan_begin_src == TRIG_TIMER) ||
5968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			(cmd->scan_begin_src == TRIG_FOLLOW))) {
5978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
5988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
5998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->convert_src == TRIG_EXT) &&
6008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		!((cmd->scan_begin_src == TRIG_EXT) ||
6018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			(cmd->scan_begin_src == TRIG_FOLLOW))) {
6028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
6048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (cmd->scan_end_src != TRIG_COUNT)
6068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->stop_src != TRIG_COUNT) && (cmd->stop_src != TRIG_NONE))
6088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (error)
6118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return 2;
6128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Step 3 : make sure arguments are trivialy compatible
6148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (cmd->chanlist_len < 1) {
6168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		cmd->chanlist_len = 1;
6178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
6198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (cmd->chanlist_len > board->ai_channel_nbr) {
6218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		cmd->chanlist_len = board->ai_channel_nbr;
6228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
6248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) {
6268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		cmd->start_arg = 0;
6278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
6298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->convert_src == TRIG_TIMER) &&
6318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		(cmd->convert_arg < board->ai_acquisition_period_min_ns)) {
6328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		cmd->convert_arg = board->ai_acquisition_period_min_ns;
6338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
6358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) {
6368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		cmd->convert_arg = 0;
6378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
6398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->scan_begin_src == TRIG_TIMER) &&
6418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		(cmd->scan_begin_arg < board->ai_acquisition_period_min_ns)) {
6428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		cmd->scan_begin_arg = board->ai_acquisition_period_min_ns;
6438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
6458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->scan_begin_src == TRIG_FOLLOW) && (cmd->scan_begin_arg != 0)) {
6468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		cmd->scan_begin_arg = 0;
6478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
6498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->scan_begin_src == TRIG_EXT) && (cmd->scan_begin_arg != 0)) {
6508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		cmd->scan_begin_arg = 0;
6518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
6538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->scan_end_src == TRIG_COUNT) &&
6558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		(cmd->scan_end_arg != cmd->chanlist_len)) {
6568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		cmd->scan_end_arg = cmd->chanlist_len;
6578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
6598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->stop_src == TRIG_COUNT) && (cmd->stop_arg < 1)) {
6618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		cmd->stop_arg = 1;
6628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
6648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((cmd->stop_src == TRIG_NONE) && (cmd->stop_arg != 0)) {
6658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		cmd->stop_arg = 0;
6668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		error++;
6678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
6688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (error)
6708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return 3;
6718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Step 4 : fix up any arguments
6738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (cmd->convert_src == TRIG_TIMER) {
6758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		tmp = cmd->convert_arg;
6768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
6778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			&(dev_private->timer_divisor_1),
6788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			&(dev_private->timer_divisor_2),
6798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			&(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
6808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		if (tmp != cmd->convert_arg)
6818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			error++;
6828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
6838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// There's only one timer on this card, so the scan_begin timer must
6848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// be a multiple of chanlist_len*convert_arg
6858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (cmd->scan_begin_src == TRIG_TIMER) {
6878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		unsigned int scan_begin_min;
6898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		unsigned int scan_begin_arg;
6908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		unsigned int scan_factor;
6918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		scan_begin_min = cmd->chanlist_len * cmd->convert_arg;
6938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
6948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		if (cmd->scan_begin_arg != scan_begin_min) {
6958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			if (scan_begin_min < cmd->scan_begin_arg) {
6968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				scan_factor =
6978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					cmd->scan_begin_arg / scan_begin_min;
6988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				scan_begin_arg = scan_factor * scan_begin_min;
6998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				if (cmd->scan_begin_arg != scan_begin_arg) {
7008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					cmd->scan_begin_arg = scan_begin_arg;
7018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					error++;
7028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				}
7038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			} else {
7048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				cmd->scan_begin_arg = scan_begin_min;
7058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				error++;
7068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			}
7078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		}
7088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
7098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (error)
7118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return 4;
7128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Step 5 : check channel list
7148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (cmd->chanlist) {
7168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		range = CR_RANGE(cmd->chanlist[0]);
7188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		reference = CR_AREF(cmd->chanlist[0]);
7198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		if (cmd->chanlist_len > 1) {
7218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			for (i = 0; i < cmd->chanlist_len; i++) {
7228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				if (CR_CHAN(cmd->chanlist[i]) != i) {
7238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					comedi_error(dev,
7248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						"entries in chanlist must be consecutive "
7258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						"channels,counting upwards from 0\n");
7268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					error++;
7278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				}
7288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				if (CR_RANGE(cmd->chanlist[i]) != range) {
7298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					comedi_error(dev,
7308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						"entries in chanlist must all have the same gain\n");
7318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					error++;
7328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				}
7338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				if (CR_AREF(cmd->chanlist[i]) != reference) {
7348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					comedi_error(dev,
7358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						"entries in chanlist must all have the same reference\n");
7368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					error++;
7378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				}
7388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			}
7398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		} else {
7408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			if ((CR_CHAN(cmd->chanlist[0]) >
7418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					(board->ai_channel_nbr - 1))
7428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				|| (CR_CHAN(cmd->chanlist[0]) < 0)) {
7438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				comedi_error(dev,
7448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					"channel number is out of limits\n");
7458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				error++;
7468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			}
7478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		}
7488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
7498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (error)
7518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return 5;
7528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	return 0;
7548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
7568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
7588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// Analog input command
7598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
7608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int pci9111_ai_do_cmd(comedi_device * dev, comedi_subdevice * subdevice)
7628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
7638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	comedi_cmd *async_cmd = &subdevice->async->cmd;
7648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (!dev->irq) {
7668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		comedi_error(dev,
7678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			"no irq assigned for PCI9111, cannot do hardware conversion");
7688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return -1;
7698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
7708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Set channel scan limit
7718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//
7728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// PCI9111 allows only scanning from channel 0 to channel n
7738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//
7748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// TODO: handle the case of an external multiplexer
7758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//
7768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (async_cmd->chanlist_len > 1) {
7788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_ai_channel_set((async_cmd->chanlist_len) - 1);
7798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_autoscan_set(dev, true);
7808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	} else {
7818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_ai_channel_set(CR_CHAN(async_cmd->chanlist[0]));
7828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_autoscan_set(dev, false);
7838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
7848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Set gain
7868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//
7878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// This is the same gain on every channel
7888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//
7898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_ai_range_set(CR_RANGE(async_cmd->chanlist[0]));
7918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	/* Set counter */
7938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
7948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	switch (async_cmd->stop_src) {
7958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	case TRIG_COUNT:
7968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev_private->stop_counter =
7978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			async_cmd->stop_arg * async_cmd->chanlist_len;
7988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev_private->stop_is_none = 0;
7998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		break;
8008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	case TRIG_NONE:
8028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev_private->stop_counter = 0;
8038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev_private->stop_is_none = 1;
8048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		break;
8058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	default:
8078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		comedi_error(dev, "Invalid stop trigger");
8088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return -1;
8098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
8108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Set timer pacer
8128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev_private->scan_delay = 0;
8148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	switch (async_cmd->convert_src) {
8158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	case TRIG_TIMER:
8168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
8178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			&(dev_private->timer_divisor_1),
8188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			&(dev_private->timer_divisor_2),
8198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			&(async_cmd->convert_arg),
8208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			async_cmd->flags & TRIG_ROUND_MASK);
8218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG
8228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		printk(PCI9111_DRIVER_NAME ": divisors = %d, %d\n",
8238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			dev_private->timer_divisor_1,
8248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			dev_private->timer_divisor_2);
8258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif
8268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_trigger_source_set(dev, software);
8288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_timer_set(dev);
8298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_fifo_reset();
8308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
8318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			irq_on_timer_tick);
8328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_trigger_source_set(dev, timer_pacer);
8338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
8348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			false, true, true);
8358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev_private->scan_delay =
8378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			(async_cmd->scan_begin_arg / (async_cmd->convert_arg *
8388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				async_cmd->chanlist_len)) - 1;
8398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		break;
8418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	case TRIG_EXT:
8438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_trigger_source_set(dev, external);
8458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_fifo_reset();
8468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
8478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			irq_on_timer_tick);
8488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
8498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			false, true, true);
8508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		break;
8528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	default:
8548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		comedi_error(dev, "Invalid convert trigger");
8558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return -1;
8568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
8578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev_private->stop_counter *= (1 + dev_private->scan_delay);
8598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev_private->chanlist_len = async_cmd->chanlist_len;
8608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev_private->chunk_counter = 0;
8618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev_private->chunk_num_samples =
8628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev_private->chanlist_len * (1 + dev_private->scan_delay);
8638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG
8658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk(PCI9111_DRIVER_NAME ": start interruptions!\n");
8668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk(PCI9111_DRIVER_NAME ": trigger source = %2x\n",
8678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_trigger_and_autoscan_get());
8688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk(PCI9111_DRIVER_NAME ": irq source     = %2x\n",
8698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_interrupt_and_fifo_get());
8708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk(PCI9111_DRIVER_NAME ": ai_do_cmd\n");
8718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk(PCI9111_DRIVER_NAME ": stop counter   = %d\n",
8728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev_private->stop_counter);
8738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk(PCI9111_DRIVER_NAME ": scan delay     = %d\n",
8748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev_private->scan_delay);
8758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk(PCI9111_DRIVER_NAME ": chanlist_len   = %d\n",
8768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev_private->chanlist_len);
8778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk(PCI9111_DRIVER_NAME ": chunk num samples = %d\n",
8788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev_private->chunk_num_samples);
8798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif
8808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	return 0;
8828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
8838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic void pci9111_ai_munge(comedi_device * dev, comedi_subdevice * s,
8858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	void *data, unsigned int num_bytes, unsigned int start_chan_index)
8868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
887790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	unsigned int i, num_samples = num_bytes / sizeof(short);
888790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	short *array = data;
8898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int resolution =
8908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		((pci9111_board_struct *) dev->board_ptr)->ai_resolution;
8918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
8928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	for (i = 0; i < num_samples; i++) {
8938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		if (resolution == PCI9111_HR_AI_RESOLUTION)
8948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			array[i] =
8958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				(array[i] & PCI9111_HR_AI_RESOLUTION_MASK) ^
8968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				PCI9111_HR_AI_RESOLUTION_2_CMP_BIT;
8978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		else
8988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			array[i] =
8998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				((array[i] >> 4) & PCI9111_AI_RESOLUTION_MASK) ^
9008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				PCI9111_AI_RESOLUTION_2_CMP_BIT;
9018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
9028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
9038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
9058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
9068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// INTERRUPT SECTION
9078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
9088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
9098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef INTERRUPT_DEBUG
9118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic irqreturn_t pci9111_interrupt(int irq, void *p_device PT_REGS_ARG)
9138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
9148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	comedi_device *dev = p_device;
9158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	comedi_subdevice *subdevice = dev->read_subdev;
9168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	comedi_async *async;
9178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	unsigned long irq_flags;
9188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	unsigned char intcsr;
9198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (!dev->attached) {
9218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		// Ignore interrupt before device fully attached.
9228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		// Might not even have allocated subdevices yet!
9238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return IRQ_NONE;
9248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
9258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	async = subdevice->async;
9278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
9298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Check if we are source of interrupt
9318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	intcsr = inb(dev_private->lcr_io_base +
9328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		PLX9050_REGISTER_INTERRUPT_CONTROL);
9338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (!(((intcsr & PLX9050_PCI_INTERRUPT_ENABLE) != 0)
9348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			&& (((intcsr & (PLX9050_LINTI1_ENABLE |
9358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							PLX9050_LINTI1_STATUS))
9368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					==
9378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					(PLX9050_LINTI1_ENABLE |
9388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						PLX9050_LINTI1_STATUS))
9398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				|| ((intcsr & (PLX9050_LINTI2_ENABLE |
9408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							PLX9050_LINTI2_STATUS))
9418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					==
9428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					(PLX9050_LINTI2_ENABLE |
9438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						PLX9050_LINTI2_STATUS))))) {
9448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		// Not the source of the interrupt.
9458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		// (N.B. not using PLX9050_SOFTWARE_INTERRUPT)
9468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
9478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return IRQ_NONE;
9488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
9498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) ==
9518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		(PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) {
9528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		// Interrupt comes from fifo_half-full signal
9538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		if (pci9111_is_fifo_full()) {
9558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			comedi_spin_unlock_irqrestore(&dev->spinlock,
9568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				irq_flags);
9578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow");
9588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			pci9111_interrupt_clear();
9598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			pci9111_ai_cancel(dev, subdevice);
9608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
9618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			comedi_event(dev, subdevice);
9628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			return IRQ_HANDLED;
9648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		}
9658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		if (pci9111_is_fifo_half_full()) {
9678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			unsigned int num_samples;
9688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			unsigned int bytes_written = 0;
9698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef INTERRUPT_DEBUG
9718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			printk(PCI9111_DRIVER_NAME ": fifo is half full\n");
9728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif
9738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			num_samples =
9758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				PCI9111_FIFO_HALF_SIZE >
9768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				dev_private->stop_counter
9778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				&& !dev_private->stop_is_none ? dev_private->
9788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				stop_counter : PCI9111_FIFO_HALF_SIZE;
9798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			insw(PCI9111_IO_BASE + PCI9111_REGISTER_AD_FIFO_VALUE,
9808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				dev_private->ai_bounce_buffer, num_samples);
9818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			if (dev_private->scan_delay < 1) {
9838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				bytes_written =
9848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					cfc_write_array_to_buffer(subdevice,
9858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					dev_private->ai_bounce_buffer,
986790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton					num_samples * sizeof(short));
9878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			} else {
9888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				int position = 0;
9898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				int to_read;
9908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
9918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				while (position < num_samples) {
9928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					if (dev_private->chunk_counter <
9938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						dev_private->chanlist_len) {
9948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						to_read =
9958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							dev_private->
9968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							chanlist_len -
9978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							dev_private->
9988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							chunk_counter;
9998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						if (to_read >
10018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							num_samples - position)
10028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							to_read =
10038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud								num_samples -
10048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud								position;
10058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						bytes_written +=
10078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							cfc_write_array_to_buffer
10088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							(subdevice,
10098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							dev_private->
10108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							ai_bounce_buffer +
10118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							position,
10128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							to_read *
1013790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton							sizeof(short));
10148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					} else {
10158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						to_read =
10168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							dev_private->
10178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							chunk_num_samples -
10188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							dev_private->
10198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							chunk_counter;
10208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						if (to_read >
10218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							num_samples - position)
10228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							to_read =
10238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud								num_samples -
10248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud								position;
10258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						bytes_written +=
1027790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton							sizeof(short) *
10288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							to_read;
10298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					}
10308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					position += to_read;
10328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					dev_private->chunk_counter += to_read;
10338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					if (dev_private->chunk_counter >=
10358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						dev_private->chunk_num_samples)
10368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						dev_private->chunk_counter = 0;
10378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				}
10388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			}
10398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			dev_private->stop_counter -=
1041790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton				bytes_written / sizeof(short);
10428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		}
10438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
10448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((dev_private->stop_counter == 0) && (!dev_private->stop_is_none)) {
10468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		async->events |= COMEDI_CB_EOA;
10478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_ai_cancel(dev, subdevice);
10488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
10498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	/* Very important, otherwise another interrupt request will be inserted
10518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	 * and will cause driver hangs on processing interrupt event. */
10528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_interrupt_clear();
10548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
10568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	comedi_event(dev, subdevice);
10588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	return IRQ_HANDLED;
10608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
10618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
10638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
10648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// INSTANT ANALOG INPUT OUTPUT SECTION
10658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
10668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
10678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
10698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// analog instant input
10708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
10718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef AI_INSN_DEBUG
10738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int pci9111_ai_insn_read(comedi_device * dev,
1075790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	comedi_subdevice * subdevice, comedi_insn * insn, unsigned int * data)
10768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
10778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int resolution =
10788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		((pci9111_board_struct *) dev->board_ptr)->ai_resolution;
10798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int timeout, i;
10818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_INSN_DEBUG
10838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk(PCI9111_DRIVER_NAME ": ai_insn set c/r/n = %2x/%2x/%2x\n",
10848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		CR_CHAN((&insn->chanspec)[0]),
10858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		CR_RANGE((&insn->chanspec)[0]), insn->n);
10868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif
10878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0]));
10898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0])) {
10918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_ai_range_set(CR_RANGE((&insn->chanspec)[0]));
10928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
10938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_fifo_reset();
10958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	for (i = 0; i < insn->n; i++) {
10978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_software_trigger();
10988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
10998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		timeout = PCI9111_AI_INSTANT_READ_TIMEOUT;
11008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		while (timeout--) {
11028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			if (!pci9111_is_fifo_empty())
11038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				goto conversion_done;
11048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		}
11058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		comedi_error(dev, "A/D read timeout");
11078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		data[i] = 0;
11088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_fifo_reset();
11098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return -ETIME;
11108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	      conversion_done:
11128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		if (resolution == PCI9111_HR_AI_RESOLUTION) {
11148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			data[i] = pci9111_hr_ai_get_data();
11158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		} else {
11168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			data[i] = pci9111_ai_get_data();
11178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		}
11188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
11198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_INSN_DEBUG
11218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk(PCI9111_DRIVER_NAME ": ai_insn get c/r/t = %2x/%2x/%2x\n",
11228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_ai_channel_get(),
11238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_ai_range_get(), pci9111_trigger_and_autoscan_get());
11248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif
11258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	return i;
11278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
11288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
11308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// Analog instant output
11318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
11328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int
11348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudpci9111_ao_insn_write(comedi_device * dev,
1135790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
11368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
11378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int i;
11388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	for (i = 0; i < insn->n; i++) {
11408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_ao_set_data(data[i]);
11418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev_private->ao_readback = data[i];
11428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
11438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	return i;
11458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
11468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
11488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// Analog output readback
11498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
11508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int pci9111_ao_insn_read(comedi_device * dev,
1152790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
11538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
11548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int i;
11558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	for (i = 0; i < insn->n; i++) {
11578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		data[i] = dev_private->ao_readback & PCI9111_AO_RESOLUTION_MASK;
11588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
11598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	return i;
11618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
11628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
11648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
11658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// DIGITAL INPUT OUTPUT SECTION
11668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
11678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
11688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
11708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// Digital inputs
11718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
11728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int pci9111_di_insn_bits(comedi_device * dev,
1174790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	comedi_subdevice * subdevice, comedi_insn * insn, unsigned int * data)
11758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
1176790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	unsigned int bits;
11778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	bits = pci9111_di_get_bits();
11798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	data[1] = bits;
11808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	return 2;
11828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
11838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
11858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// Digital outputs
11868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
11878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int pci9111_do_insn_bits(comedi_device * dev,
1189790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	comedi_subdevice * subdevice, comedi_insn * insn, unsigned int * data)
11908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
1191790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	unsigned int bits;
11928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Only set bits that have been masked
11948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// data[0] = mask
11958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// data[1] = bit state
11968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	data[0] &= PCI9111_DO_MASK;
11988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
11998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	bits = subdevice->state;
12008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	bits &= ~data[0];
12018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	bits |= data[0] & data[1];
12028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->state = bits;
12038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_do_set_bits(bits);
12058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	data[1] = bits;
12078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	return 2;
12098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
12108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
12128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
12138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// INITIALISATION SECTION
12148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
12158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// ------------------------------------------------------------------
12168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
12188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// Reset device
12198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
12208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int pci9111_reset(comedi_device * dev)
12228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
12238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Set trigger source to software
12248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
12268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		true, false);
12278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_trigger_source_set(dev, software);
12298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_pretrigger_set(dev, false);
12308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_autoscan_set(dev, false);
12318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Reset 8254 chip
12338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev_private->timer_divisor_1 = 0;
12358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev_private->timer_divisor_2 = 0;
12368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_timer_set(dev);
12388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	return 0;
12408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
12418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
12438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// Attach
12448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
12458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//      - Register PCI device
12468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//      - Declare device driver capability
12478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
12488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int pci9111_attach(comedi_device * dev, comedi_devconfig * it)
12508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
12518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	comedi_subdevice *subdevice;
12528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	unsigned long io_base, io_range, lcr_io_base, lcr_io_range;
12538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	struct pci_dev *pci_device;
12548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	int error, i;
12558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	const pci9111_board_struct *board;
12568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (alloc_private(dev, sizeof(pci9111_private_data_struct)) < 0) {
12588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return -ENOMEM;
12598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
12608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//
12618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Probe the device to determine what device in the series it is.
12628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//
12638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk("comedi%d: " PCI9111_DRIVER_NAME " driver\n", dev->minor);
12658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
12678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci_device != NULL;
12688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci_device =
12698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
12708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		if (pci_device->vendor == PCI_VENDOR_ID_ADLINK) {
12718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			for (i = 0; i < pci9111_board_nbr; i++) {
12728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				if (pci9111_boards[i].device_id ==
12738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					pci_device->device) {
12748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					// was a particular bus/slot requested?
12758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					if ((it->options[0] != 0)
12768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						|| (it->options[1] != 0)) {
12778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						// are we on the wrong bus/slot?
12788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						if (pci_device->bus->number !=
12798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							it->options[0]
12808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							|| PCI_SLOT(pci_device->
12818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud								devfn) !=
12828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							it->options[1]) {
12838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud							continue;
12848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						}
12858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					}
12868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					dev->board_ptr = pci9111_boards + i;
12888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					board = (pci9111_board_struct *) dev->
12898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud						board_ptr;
12908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					dev_private->pci_device = pci_device;
12918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud					goto found;
12928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				}
12938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			}
12948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		}
12958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
12968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
12978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
12988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev->minor, it->options[0], it->options[1]);
12998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	return -EIO;
13008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud      found:
13028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n",
13048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev->minor,
13058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci9111_boards[i].name,
13068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci_device->bus->number,
13078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		PCI_SLOT(pci_device->devfn),
13088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		PCI_FUNC(pci_device->devfn), pci_device->irq);
13098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// TODO: Warn about non-tested boards.
13118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	switch (board->device_id) {
13138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	};
13148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Read local configuration register base address [PCI_BASE_ADDRESS #1].
13168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	lcr_io_base = pci_resource_start(pci_device, 1);
13188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	lcr_io_range = pci_resource_len(pci_device, 1);
13198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n", dev->minor, lcr_io_base, lcr_io_range);
13218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Enable PCI device and request regions
13238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (comedi_pci_enable(pci_device, PCI9111_DRIVER_NAME) < 0) {
13248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
13258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return -EIO;
13268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
13278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Read PCI6308 register base address [PCI_BASE_ADDRESS #2].
13288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	io_base = pci_resource_start(pci_device, 2);
13308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	io_range = pci_resource_len(pci_device, 2);
13318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	printk("comedi%d: 6503 registers at address 0x%4lx [0x%4lx]\n",
13338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		dev->minor, io_base, io_range);
13348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev->iobase = io_base;
13368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev->board_name = board->name;
13378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev_private->io_range = io_range;
13388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev_private->is_valid = 0;
13398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev_private->lcr_io_base = lcr_io_base;
13408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev_private->lcr_io_range = lcr_io_range;
13418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	pci9111_reset(dev);
13438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Irq setup
13458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev->irq = 0;
13478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (pci_device->irq > 0) {
13488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		if (comedi_request_irq(pci_device->irq,
13498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				pci9111_interrupt,
13508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				IRQF_SHARED, PCI9111_DRIVER_NAME, dev) != 0) {
13518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			printk("comedi%d: unable to allocate irq  %u\n",
13528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud				dev->minor, pci_device->irq);
13538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			return -EINVAL;
13548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		}
13558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
13568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev->irq = pci_device->irq;
13578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//
13598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// TODO: Add external multiplexer setup (according to option[2]).
13608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//
13618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if ((error = alloc_subdevices(dev, 4)) < 0)
13638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		return error;
13648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice = dev->subdevices + 0;
13668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev->read_subdev = subdevice;
13678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->type = COMEDI_SUBD_AI;
13698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ;
13708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//
13728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// TODO: Add external multiplexer data
13738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//
13748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//    if (devpriv->usemux) { subdevice->n_chan = devpriv->usemux; }
13758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//    else { subdevice->n_chan = this_board->n_aichan; }
13768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	//
13778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->n_chan = board->ai_channel_nbr;
13798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->maxdata = board->ai_resolution_mask;
13808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->len_chanlist = board->ai_channel_nbr;
13818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->range_table = board->ai_range_list;
13828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->cancel = pci9111_ai_cancel;
13838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->insn_read = pci9111_ai_insn_read;
13848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->do_cmdtest = pci9111_ai_do_cmd_test;
13858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->do_cmd = pci9111_ai_do_cmd;
13868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->munge = pci9111_ai_munge;
13878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice = dev->subdevices + 1;
13898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->type = COMEDI_SUBD_AO;
13908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->subdev_flags = SDF_WRITABLE | SDF_COMMON;
13918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->n_chan = board->ao_channel_nbr;
13928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->maxdata = board->ao_resolution_mask;
13938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->len_chanlist = board->ao_channel_nbr;
13948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->range_table = board->ao_range_list;
13958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->insn_write = pci9111_ao_insn_write;
13968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->insn_read = pci9111_ao_insn_read;
13978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
13988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice = dev->subdevices + 2;
13998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->type = COMEDI_SUBD_DI;
14008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->subdev_flags = SDF_READABLE;
14018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->n_chan = PCI9111_DI_CHANNEL_NBR;
14028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->maxdata = 1;
14038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->range_table = &range_digital;
14048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->insn_bits = pci9111_di_insn_bits;
14058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
14068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice = dev->subdevices + 3;
14078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->type = COMEDI_SUBD_DO;
14088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->subdev_flags = SDF_READABLE | SDF_WRITABLE;
14098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->n_chan = PCI9111_DO_CHANNEL_NBR;
14108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->maxdata = 1;
14118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->range_table = &range_digital;
14128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	subdevice->insn_bits = pci9111_do_insn_bits;
14138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
14148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	dev_private->is_valid = 1;
14158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
14168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	return 0;
14178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
14188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
14198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
14208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud// Detach
14218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud//
14228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
14238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int pci9111_detach(comedi_device * dev)
14248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{
14258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Reset device
14268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
14278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (dev->private != 0) {
14288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		if (dev_private->is_valid)
14298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			pci9111_reset(dev);
14308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
14318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
14328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	// Release previously allocated irq
14338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
14348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (dev->irq != 0) {
14358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		comedi_free_irq(dev->irq, dev);
14368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
14378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
14388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	if (dev_private != 0 && dev_private->pci_device != 0) {
14398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		if (dev->iobase) {
14408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud			comedi_pci_disable(dev_private->pci_device);
14418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		}
14428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud		pci_dev_put(dev_private->pci_device);
14438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	}
14448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud
14458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud	return 0;
14468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}
1447