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