adl_pci9111.c revision 7ecac4c38a813021155c4207592693ad1949b9b7
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 417ecac4c38a813021155c4207592693ad1949b9b7Mark - start_src TRIG_NOW 427ecac4c38a813021155c4207592693ad1949b9b7Mark - 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. 712f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor - Add support for the PCI-9111DG with a probe routine to identify the card 722f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor type (perhaps with the help of the channel number readback of the A/D Data 732f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor register). 748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud - Add external multiplexer support. 758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud*/ 778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#include "../comedidev.h" 798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#include <linux/delay.h> 8170265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slaby#include <linux/interrupt.h> 828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#include "8253.h" 848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#include "comedi_pci.h" 858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#include "comedi_fc.h" 868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 872f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_DRIVER_NAME "adl_pci9111" 882f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_HR_DEVICE_ID 0x9111 898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* TODO: Add other pci9111 board id */ 918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 922f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_IO_RANGE 0x0100 938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_FIFO_HALF_SIZE 512 958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_CHANNEL_NBR 16 978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_RESOLUTION 12 998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_RESOLUTION_MASK 0x0FFF 1008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_RESOLUTION_2_CMP_BIT 0x0800 1018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_HR_AI_RESOLUTION 16 1038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_HR_AI_RESOLUTION_MASK 0xFFFF 1048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_HR_AI_RESOLUTION_2_CMP_BIT 0x8000 1058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS 10000 1078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AO_CHANNEL_NBR 1 1088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AO_RESOLUTION 12 1098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AO_RESOLUTION_MASK 0x0FFF 1108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_DI_CHANNEL_NBR 16 1118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_DO_CHANNEL_NBR 16 1128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_DO_MASK 0xFFFF 1138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_RANGE_SETTING_DELAY 10 1158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_INSTANT_READ_UDELAY_US 2 1168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AI_INSTANT_READ_TIMEOUT 100 1178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_CLOCK_PERIOD_NS 500 1198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_COUNTER_0 0x00 1218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_COUNTER_1 0x40 1228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_COUNTER_2 0x80 1238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_COUNTER_LATCH 0x00 1248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_READ_LOAD_LSB_ONLY 0x10 1258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_READ_LOAD_MSB_ONLY 0x20 1268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_READ_LOAD_LSB_MSB 0x30 1278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_MODE_0 0x00 1288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_MODE_1 0x02 1298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_MODE_2 0x04 1308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_MODE_3 0x06 1318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_MODE_4 0x08 1328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_MODE_5 0x0A 1338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_BINARY_COUNTER 0x00 1348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_8254_BCD_COUNTER 0x01 1358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud/* IO address map */ 1378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1382f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_AD_FIFO_VALUE 0x00 /* AD Data stored 1392f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor in FIFO */ 1402f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_DA_OUTPUT 0x00 1412f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_DIGITAL_IO 0x02 1422f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_EXTENDED_IO_PORTS 0x04 1432f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_AD_CHANNEL_CONTROL 0x06 /* Channel 1442f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor selection */ 1452f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_AD_CHANNEL_READBACK 0x06 1462f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_INPUT_SIGNAL_RANGE 0x08 1472f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_RANGE_STATUS_READBACK 0x08 1482f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_TRIGGER_MODE_CONTROL 0x0A 1492f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK 0x0A 1502f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_SOFTWARE_TRIGGER 0x0E 1512f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_INTERRUPT_CONTROL 0x0C 1528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_8254_COUNTER_0 0x40 1538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_8254_COUNTER_1 0x42 1542f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_8254_COUNTER_2 0X44 1558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_REGISTER_8254_CONTROL 0x46 1562f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_REGISTER_INTERRUPT_CLEAR 0x48 1578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1582f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_TRIGGER_MASK 0x0F 1592f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_PTRG_OFF (0 << 3) 1602f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_PTRG_ON (1 << 3) 1618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_EITS_EXTERNAL (1 << 2) 1628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_EITS_INTERNAL (0 << 2) 1638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_TPST_SOFTWARE_TRIGGER (0 << 1) 1648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_TPST_TIMER_PACER (1 << 1) 1658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_ASCAN_ON (1 << 0) 1668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_ASCAN_OFF (0 << 0) 1678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_ISC0_SET_IRQ_ON_ENDING_OF_AD_CONVERSION (0 << 0) 1698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL (1 << 0) 1702f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_ISC1_SET_IRQ_ON_TIMER_TICK (0 << 1) 1712f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_ISC1_SET_IRQ_ON_EXT_TRG (1 << 1) 1722f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_FFEN_SET_FIFO_ENABLE (0 << 2) 1738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_FFEN_SET_FIFO_DISABLE (1 << 2) 1748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_CHANNEL_MASK 0x0F 1768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_RANGE_MASK 0x07 1788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_FIFO_EMPTY_MASK 0x10 1798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_FIFO_HALF_FULL_MASK 0x20 1808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_FIFO_FULL_MASK 0x40 1818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PCI9111_AD_BUSY_MASK 0x80 1828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1832f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define PCI9111_IO_BASE (dev->iobase) 1848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud/* 1868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud * Define inlined function 1878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud */ 1888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_trigger_and_autoscan_get() \ 1908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK)&0x0F) 1918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_trigger_and_autoscan_set(flags) \ 193f7cbd7aad063b2a4b7aff6a743b2b00015ce3c3eBill Pemberton outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_TRIGGER_MODE_CONTROL) 1948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1952f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define pci9111_interrupt_and_fifo_get() \ 1962f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) >> 4) \ 1972f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor &0x03) 1988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_interrupt_and_fifo_set(flags) \ 200f7cbd7aad063b2a4b7aff6a743b2b00015ce3c3eBill Pemberton outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL) 2018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_interrupt_clear() \ 203f7cbd7aad063b2a4b7aff6a743b2b00015ce3c3eBill Pemberton outb(0, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CLEAR) 2048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_software_trigger() \ 206f7cbd7aad063b2a4b7aff6a743b2b00015ce3c3eBill Pemberton outb(0, PCI9111_IO_BASE+PCI9111_REGISTER_SOFTWARE_TRIGGER) 2078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2082f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define pci9111_fifo_reset() do { \ 2092f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ 2102f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \ 2112f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor outb(PCI9111_FFEN_SET_FIFO_DISABLE, \ 2122f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \ 2132f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ 2142f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \ 2152f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor } while (0) 2168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_is_fifo_full() \ 2188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ 2192f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor PCI9111_FIFO_FULL_MASK) == 0) 2208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_is_fifo_half_full() \ 2228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ 2232f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor PCI9111_FIFO_HALF_FULL_MASK) == 0) 2248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_is_fifo_empty() \ 2268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ 2272f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor PCI9111_FIFO_EMPTY_MASK) == 0) 2288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2292f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define pci9111_ai_channel_set(channel) \ 2302f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor outb((channel)&PCI9111_CHANNEL_MASK, \ 2312f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_CONTROL) 2328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2332f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define pci9111_ai_channel_get() \ 2342f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_READBACK) \ 2352f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor &PCI9111_CHANNEL_MASK) 2368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2372f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define pci9111_ai_range_set(range) \ 2382f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor outb((range)&PCI9111_RANGE_MASK, \ 2392f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor PCI9111_IO_BASE+PCI9111_REGISTER_INPUT_SIGNAL_RANGE) 2408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2412f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define pci9111_ai_range_get() \ 2422f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor (inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK) \ 2432f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor &PCI9111_RANGE_MASK) 2448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2452f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor#define pci9111_ai_get_data() \ 2462f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor (((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)>>4) \ 2472f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor &PCI9111_AI_RESOLUTION_MASK) \ 2482f6df34cd3455245c44b420d7c3fb11d1137df79Mark Rankilor ^ PCI9111_AI_RESOLUTION_2_CMP_BIT) 2498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2507ecac4c38a813021155c4207592693ad1949b9b7Mark#define pci9111_hr_ai_get_data() \ 2517ecac4c38a813021155c4207592693ad1949b9b7Mark ((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE) \ 2527ecac4c38a813021155c4207592693ad1949b9b7Mark & PCI9111_HR_AI_RESOLUTION_MASK) \ 2537ecac4c38a813021155c4207592693ad1949b9b7Mark ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT) 2548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2557ecac4c38a813021155c4207592693ad1949b9b7Mark#define pci9111_ao_set_data(data) \ 2567ecac4c38a813021155c4207592693ad1949b9b7Mark outw(data&PCI9111_AO_RESOLUTION_MASK, \ 2577ecac4c38a813021155c4207592693ad1949b9b7Mark PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT) 2588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_di_get_bits() \ 2608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud inw(PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO) 2618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_do_set_bits(bits) \ 263f7cbd7aad063b2a4b7aff6a743b2b00015ce3c3eBill Pemberton outw(bits, PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO) 2648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_control_set(flags) \ 266f7cbd7aad063b2a4b7aff6a743b2b00015ce3c3eBill Pemberton outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_8254_CONTROL) 2678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_0_set(data) \ 2698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \ 27053106ae68acf6eda9593150a25fc44e30fd5ff68Bill Pemberton outb((data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0) 2718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_1_set(data) \ 2738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \ 27453106ae68acf6eda9593150a25fc44e30fd5ff68Bill Pemberton outb((data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1) 2758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_2_set(data) \ 2778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \ 27853106ae68acf6eda9593150a25fc44e30fd5ff68Bill Pemberton outb((data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2) 2798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 28052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Function prototypes */ 2818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_attach(struct comedi_device *dev, 2830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 284da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_detach(struct comedi_device *dev); 2850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void pci9111_ai_munge(struct comedi_device *dev, 2860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, void *data, 2870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int num_bytes, 2880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int start_chan_index); 2898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2909ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange pci9111_hr_ai_range = { 2918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5, 2928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud { 2930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(10), 2940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(5), 2950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(2.5), 2960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(1.25), 2970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(0.625) 2980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 2998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = { 3027ecac4c38a813021155c4207592693ad1949b9b7Mark { PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 3037ecac4c38a813021155c4207592693ad1949b9b7Mark 0, 0, 0 }, 3047ecac4c38a813021155c4207592693ad1949b9b7Mark /* { PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 3057ecac4c38a813021155c4207592693ad1949b9b7Mark * 0, 0, 0 }, */ 3067ecac4c38a813021155c4207592693ad1949b9b7Mark { 0 } 3078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudMODULE_DEVICE_TABLE(pci, pci9111_pci_table); 3108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 31152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* */ 31252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Board specification structure */ 31352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* */ 3148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 315940579fbae1a3a8967fe619562c8e78080dd873dBill Pembertonstruct pci9111_board { 31652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton const char *name; /* driver name */ 3178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int device_id; 31852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ai_channel_nbr; /* num of A/D chans */ 31952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ao_channel_nbr; /* num of D/A chans */ 32052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ai_resolution; /* resolution of A/D */ 3218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int ai_resolution_mask; 32252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ao_resolution; /* resolution of D/A */ 3238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int ao_resolution_mask; 32452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton const struct comedi_lrange *ai_range_list; /* rangelist for A/D */ 32552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton const struct comedi_lrange *ao_range_list; /* rangelist for D/A */ 3268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int ai_acquisition_period_min_ns; 327940579fbae1a3a8967fe619562c8e78080dd873dBill Pemberton}; 3288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 329940579fbae1a3a8967fe619562c8e78080dd873dBill Pembertonstatic const struct pci9111_board pci9111_boards[] = { 3308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud { 3310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci9111_hr", 3320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = PCI9111_HR_DEVICE_ID, 3330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_channel_nbr = PCI9111_AI_CHANNEL_NBR, 3340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_channel_nbr = PCI9111_AO_CHANNEL_NBR, 3350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_resolution = PCI9111_HR_AI_RESOLUTION, 3360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_resolution_mask = PCI9111_HR_AI_RESOLUTION_MASK, 3370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_resolution = PCI9111_AO_RESOLUTION, 3380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_resolution_mask = PCI9111_AO_RESOLUTION_MASK, 3390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_range_list = &pci9111_hr_ai_range, 3400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_range_list = &range_bipolar10, 3410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_acquisition_period_min_ns = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS} 3428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_board_nbr \ 345940579fbae1a3a8967fe619562c8e78080dd873dBill Pemberton (sizeof(pci9111_boards)/sizeof(struct pci9111_board)) 3468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 347139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver pci9111_driver = { 34868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = PCI9111_DRIVER_NAME, 34968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 35068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = pci9111_attach, 35168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = pci9111_detach, 3528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 354727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __devinit pci9111_driver_pci_probe(struct pci_dev *dev, 355727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas const struct pci_device_id *ent) 356727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 357727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return comedi_pci_auto_config(dev, pci9111_driver.driver_name); 358727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 359727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 360727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __devexit pci9111_driver_pci_remove(struct pci_dev *dev) 361727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 362727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_pci_auto_unconfig(dev); 363727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 364727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 365727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic struct pci_driver pci9111_driver_pci_driver = { 366727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .id_table = pci9111_pci_table, 367727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .probe = &pci9111_driver_pci_probe, 368727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .remove = __devexit_p(&pci9111_driver_pci_remove) 369727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}; 370727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 371727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __init pci9111_driver_init_module(void) 372727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 373727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas int retval; 374727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 375727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas retval = comedi_driver_register(&pci9111_driver); 376727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas if (retval < 0) 377727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return retval; 378727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 379727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas pci9111_driver_pci_driver.name = (char *)pci9111_driver.driver_name; 380727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return pci_register_driver(&pci9111_driver_pci_driver); 381727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 382727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 383727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __exit pci9111_driver_cleanup_module(void) 384727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 385727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas pci_unregister_driver(&pci9111_driver_pci_driver); 386727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_driver_unregister(&pci9111_driver); 387727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 388727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 389727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_init(pci9111_driver_init_module); 390727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_exit(pci9111_driver_cleanup_module); 3918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 39252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Private data structure */ 3938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 394c350fa1944f4ec1fe392ce0f3fc879f3899bb15dBill Pembertonstruct pci9111_private_data { 3958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud struct pci_dev *pci_device; 39652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton unsigned long io_range; /* PCI6503 io range */ 3978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3987ecac4c38a813021155c4207592693ad1949b9b7Mark unsigned long lcr_io_base; /* Local configuration register base 3997ecac4c38a813021155c4207592693ad1949b9b7Mark * address */ 4008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned long lcr_io_range; 4018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int stop_counter; 4038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int stop_is_none; 4048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_delay; 4068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int chanlist_len; 4078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int chunk_counter; 4088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int chunk_num_samples; 4098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 41052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ao_readback; /* Last written analog output data */ 4118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4127ecac4c38a813021155c4207592693ad1949b9b7Mark unsigned int timer_divisor_1; /* Divisor values for the 8254 timer 4137ecac4c38a813021155c4207592693ad1949b9b7Mark * pacer */ 414525d1b1395858606103d4663a570cc8725ff2cedGreg Kroah-Hartman unsigned int timer_divisor_2; 4158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 41652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int is_valid; /* Is device valid */ 4178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 418790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE]; 419c350fa1944f4ec1fe392ce0f3fc879f3899bb15dBill Pemberton}; 4208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4217ecac4c38a813021155c4207592693ad1949b9b7Mark#define dev_private ((struct pci9111_private_data *)dev->private) 4228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 42352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 42452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* PLX9050 SECTION */ 42552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 4268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_REGISTER_INTERRUPT_CONTROL 0x4c 4288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_ENABLE (1 << 0) 4308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_ACTIVE_HIGH (1 << 1) 4318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_STATUS (1 << 2) 4328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_ENABLE (1 << 3) 4338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_ACTIVE_HIGH (1 << 4) 4348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_STATUS (1 << 5) 4358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_PCI_INTERRUPT_ENABLE (1 << 6) 4368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_SOFTWARE_INTERRUPT (1 << 7) 4378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic void plx9050_interrupt_control(unsigned long io_base, 4390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi1_enable, 4400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi1_active_high, 4410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi2_enable, 4420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi2_active_high, 4430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool interrupt_enable) 4448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 4458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags = 0; 4468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi1_enable) 4488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI1_ENABLE; 4498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi1_active_high) 4508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI1_ACTIVE_HIGH; 4518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi2_enable) 4528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI2_ENABLE; 4538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi2_active_high) 4548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI2_ACTIVE_HIGH; 4558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (interrupt_enable) 4578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_PCI_INTERRUPT_ENABLE; 4588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud outb(flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL); 4608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 4618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 46252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 46352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* MISCELLANEOUS SECTION */ 46452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 4658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 46652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* 8254 timer */ 4678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 468da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_timer_set(struct comedi_device *dev) 4698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 4708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_control_set(PCI9111_8254_COUNTER_0 | 4710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_READ_LOAD_LSB_MSB | 4720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_MODE_0 | 4730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_BINARY_COUNTER); 4748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_control_set(PCI9111_8254_COUNTER_1 | 4760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_READ_LOAD_LSB_MSB | 4770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_MODE_2 | 4780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_BINARY_COUNTER); 4798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_control_set(PCI9111_8254_COUNTER_2 | 4810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_READ_LOAD_LSB_MSB | 4820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_MODE_2 | 4830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_BINARY_COUNTER); 4848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4855f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 4868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_counter_2_set(dev_private->timer_divisor_2); 4888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_counter_1_set(dev_private->timer_divisor_1); 4898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 4908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 491655f78f6aaa059ad262bc55e1c3575724c14867bBill Pembertonenum pci9111_trigger_sources { 4928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud software, 4938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud timer_pacer, 4948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud external 495655f78f6aaa059ad262bc55e1c3575724c14867bBill Pemberton}; 4968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 497da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_trigger_source_set(struct comedi_device *dev, 4980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral enum pci9111_trigger_sources source) 4998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 5018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_trigger_and_autoscan_get() & 0x09; 5038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud switch (source) { 5058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case software: 5068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_SOFTWARE_TRIGGER; 5078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 5088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case timer_pacer: 5108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_TIMER_PACER; 5118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 5128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case external: 5148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_EITS_EXTERNAL; 5158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 5168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 5178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_and_autoscan_set(flags); 5198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 521da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_pretrigger_set(struct comedi_device *dev, bool pretrigger) 5228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 5248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_trigger_and_autoscan_get() & 0x07; 5268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pretrigger) 5288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_PTRG_ON; 5298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_and_autoscan_set(flags); 5318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 533da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_autoscan_set(struct comedi_device *dev, bool autoscan) 5348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 5368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_trigger_and_autoscan_get() & 0x0e; 5388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (autoscan) 5408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_ASCAN_ON; 5418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_and_autoscan_set(flags); 5438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5453ba97b3c6258cb67450e0873584489f97d0debc5Bill Pembertonenum pci9111_ISC0_sources { 5468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_eoc, 5478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_fifo_half_full 5483ba97b3c6258cb67450e0873584489f97d0debc5Bill Pemberton}; 5498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 55052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pembertonenum pci9111_ISC1_sources { 5518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_timer_tick, 5528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_external_trigger 55352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton}; 5548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 555da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_interrupt_source_set(struct comedi_device *dev, 5560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral enum pci9111_ISC0_sources irq_0_source, 5570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral enum pci9111_ISC1_sources irq_1_source) 5588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 5608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_interrupt_and_fifo_get() & 0x04; 5628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (irq_0_source == irq_on_fifo_half_full) 5648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL; 5658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (irq_1_source == irq_on_external_trigger) 5678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_ISC1_SET_IRQ_ON_EXT_TRG; 5688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_and_fifo_set(flags); 5708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 57252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 57352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* HARDWARE TRIGGERED ANALOG INPUT SECTION */ 57452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 5758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 57652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Cancel analog input autoscan */ 5778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef AI_DO_CMD_DEBUG 5798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_ai_cancel(struct comedi_device *dev, 5810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 5828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 58352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Disable interrupts */ 5848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, 5860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral true, false); 5878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, software); 5898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, false); 5918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 5938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG 5958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_cancel\n"); 5968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 5978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 5998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 6008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 60152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Test analog input command */ 6028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6037ecac4c38a813021155c4207592693ad1949b9b7Mark#define pci9111_check_trigger_src(src, flags) do { \ 6047ecac4c38a813021155c4207592693ad1949b9b7Mark tmp = src; \ 6057ecac4c38a813021155c4207592693ad1949b9b7Mark src &= flags; \ 6067ecac4c38a813021155c4207592693ad1949b9b7Mark if (!src || tmp != src) \ 6077ecac4c38a813021155c4207592693ad1949b9b7Mark error++; \ 6087ecac4c38a813021155c4207592693ad1949b9b7Mark } while (false); 6098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int 611da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonpci9111_ai_do_cmd_test(struct comedi_device *dev, 6120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_cmd *cmd) 6138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 6148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int tmp; 6158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int error = 0; 6168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int range, reference; 6178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int i; 6180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct pci9111_board *board = (struct pci9111_board *)dev->board_ptr; 6198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 62052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 1 : check if trigger are trivialy valid */ 6218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->start_src, TRIG_NOW); 6238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->scan_begin_src, 6240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT); 6258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->convert_src, TRIG_TIMER | TRIG_EXT); 6268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->scan_end_src, TRIG_COUNT); 6278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->stop_src, TRIG_COUNT | TRIG_NONE); 6288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 6308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 1; 6318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6327ecac4c38a813021155c4207592693ad1949b9b7Mark /* step 2 : make sure trigger sources are unique and mutually 6337ecac4c38a813021155c4207592693ad1949b9b7Mark * compatible */ 6348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->start_src != TRIG_NOW) 6368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_begin_src != TRIG_TIMER) && 6390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_begin_src != TRIG_FOLLOW) && 6400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_begin_src != TRIG_EXT)) 6418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6432306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT)) 6448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_TIMER) && 6460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral !((cmd->scan_begin_src == TRIG_TIMER) || 6472306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom (cmd->scan_begin_src == TRIG_FOLLOW))) 6488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_EXT) && 6500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral !((cmd->scan_begin_src == TRIG_EXT) || 6512306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom (cmd->scan_begin_src == TRIG_FOLLOW))) 6528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6532306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom 6548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_end_src != TRIG_COUNT) 6568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->stop_src != TRIG_COUNT) && (cmd->stop_src != TRIG_NONE)) 6588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 6618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 2; 6628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 66352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 3 : make sure arguments are trivialy compatible */ 6648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist_len < 1) { 6668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->chanlist_len = 1; 6678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist_len > board->ai_channel_nbr) { 6718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->chanlist_len = board->ai_channel_nbr; 6728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) { 6768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->start_arg = 0; 6778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_TIMER) && 6810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->convert_arg < board->ai_acquisition_period_min_ns)) { 6828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->convert_arg = board->ai_acquisition_period_min_ns; 6838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) { 6868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->convert_arg = 0; 6878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_begin_src == TRIG_TIMER) && 6910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_begin_arg < board->ai_acquisition_period_min_ns)) { 6928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = board->ai_acquisition_period_min_ns; 6938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6957ecac4c38a813021155c4207592693ad1949b9b7Mark if ((cmd->scan_begin_src == TRIG_FOLLOW) 6967ecac4c38a813021155c4207592693ad1949b9b7Mark && (cmd->scan_begin_arg != 0)) { 6978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = 0; 6988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_begin_src == TRIG_EXT) && (cmd->scan_begin_arg != 0)) { 7018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = 0; 7028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_end_src == TRIG_COUNT) && 7060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_end_arg != cmd->chanlist_len)) { 7078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_end_arg = cmd->chanlist_len; 7088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->stop_src == TRIG_COUNT) && (cmd->stop_arg < 1)) { 7128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->stop_arg = 1; 7138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->stop_src == TRIG_NONE) && (cmd->stop_arg != 0)) { 7168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->stop_arg = 0; 7178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 7218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 3; 7228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 72352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 4 : fix up any arguments */ 7248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->convert_src == TRIG_TIMER) { 7268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud tmp = cmd->convert_arg; 7278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, 7280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_1), 7290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_2), 7300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd->convert_arg), 7310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 7328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (tmp != cmd->convert_arg) 7338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 73552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* There's only one timer on this card, so the scan_begin timer must */ 73652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* be a multiple of chanlist_len*convert_arg */ 7378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_begin_src == TRIG_TIMER) { 7398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_begin_min; 7418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_begin_arg; 7428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_factor; 7438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud scan_begin_min = cmd->chanlist_len * cmd->convert_arg; 7458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_begin_arg != scan_begin_min) { 7478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (scan_begin_min < cmd->scan_begin_arg) { 7488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud scan_factor = 7490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_arg / scan_begin_min; 7508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud scan_begin_arg = scan_factor * scan_begin_min; 7518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_begin_arg != scan_begin_arg) { 7528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = scan_begin_arg; 7538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 7568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = scan_begin_min; 7578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 7638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 4; 7648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 76552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 5 : check channel list */ 7668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist) { 7688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud range = CR_RANGE(cmd->chanlist[0]); 7708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud reference = CR_AREF(cmd->chanlist[0]); 7718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist_len > 1) { 7738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < cmd->chanlist_len; i++) { 7748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (CR_CHAN(cmd->chanlist[i]) != i) { 7758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must be consecutive " 7770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "channels,counting upwards from 0\n"); 7788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (CR_RANGE(cmd->chanlist[i]) != range) { 7818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must all have the same gain\n"); 7838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (CR_AREF(cmd->chanlist[i]) != reference) { 7868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must all have the same reference\n"); 7888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 7928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((CR_CHAN(cmd->chanlist[0]) > 7930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (board->ai_channel_nbr - 1)) 7940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || (CR_CHAN(cmd->chanlist[0]) < 0)) { 7958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "channel number is out of limits\n"); 7978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 8038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 5; 8048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 8068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 8088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 80952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Analog input command */ 8108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_ai_do_cmd(struct comedi_device *dev, 8120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice) 8138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 814ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *async_cmd = &subdevice->async->cmd; 8158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!dev->irq) { 8178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 8180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "no irq assigned for PCI9111, cannot do hardware conversion"); 8198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -1; 8208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 82152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set channel scan limit */ 82252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* PCI9111 allows only scanning from channel 0 to channel n */ 82352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: handle the case of an external multiplexer */ 8248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (async_cmd->chanlist_len > 1) { 8268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_channel_set((async_cmd->chanlist_len) - 1); 8278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, true); 8288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 8298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_channel_set(CR_CHAN(async_cmd->chanlist[0])); 8308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, false); 8318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 83352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set gain */ 83452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* This is the same gain on every channel */ 8358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_range_set(CR_RANGE(async_cmd->chanlist[0])); 8378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud /* Set counter */ 8398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud switch (async_cmd->stop_src) { 8418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_COUNT: 8428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter = 8430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral async_cmd->stop_arg * async_cmd->chanlist_len; 8448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_is_none = 0; 8458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 8468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_NONE: 8488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter = 0; 8498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_is_none = 1; 8508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 8518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud default: 8538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, "Invalid stop trigger"); 8548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -1; 8558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 85752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set timer pacer */ 8588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->scan_delay = 0; 8608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud switch (async_cmd->convert_src) { 8618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_TIMER: 8628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, 8630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_1), 8640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_2), 8650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(async_cmd->convert_arg), 8660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral async_cmd-> 8670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral flags & TRIG_ROUND_MASK); 8688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG 8698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": divisors = %d, %d\n", 8700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->timer_divisor_1, 8710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->timer_divisor_2); 8728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 8738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, software); 8758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_timer_set(dev); 8768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 8778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_source_set(dev, irq_on_fifo_half_full, 8780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral irq_on_timer_tick); 8798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, timer_pacer); 8808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, 8810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral false, true, true); 8828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->scan_delay = 8840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (async_cmd->scan_begin_arg / (async_cmd->convert_arg * 8850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral async_cmd->chanlist_len)) - 1; 8868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 8888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_EXT: 8908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, external); 8928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 8938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_source_set(dev, irq_on_fifo_half_full, 8940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral irq_on_timer_tick); 8958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, 8960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral false, true, true); 8978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 8998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud default: 9018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, "Invalid convert trigger"); 9028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -1; 9038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter *= (1 + dev_private->scan_delay); 9068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chanlist_len = async_cmd->chanlist_len; 9078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_counter = 0; 9088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_num_samples = 9090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len * (1 + dev_private->scan_delay); 9108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG 9128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": start interruptions!\n"); 9138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": trigger source = %2x\n", 9140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_trigger_and_autoscan_get()); 9158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": irq source = %2x\n", 9160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_interrupt_and_fifo_get()); 9178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_do_cmd\n"); 9188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": stop counter = %d\n", 9190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->stop_counter); 9208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": scan delay = %d\n", 9210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->scan_delay); 9228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": chanlist_len = %d\n", 9230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len); 9248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": chunk num samples = %d\n", 9250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_num_samples); 9268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 9278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 9298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 9308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void pci9111_ai_munge(struct comedi_device *dev, 9320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, void *data, 9330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int num_bytes, 9340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int start_chan_index) 9358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 936790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int i, num_samples = num_bytes / sizeof(short); 937790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short *array = data; 9388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int resolution = 9390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ((struct pci9111_board *)dev->board_ptr)->ai_resolution; 9408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < num_samples; i++) { 9428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (resolution == PCI9111_HR_AI_RESOLUTION) 9438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud array[i] = 9440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (array[i] & PCI9111_HR_AI_RESOLUTION_MASK) ^ 9450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_HR_AI_RESOLUTION_2_CMP_BIT; 9468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud else 9478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud array[i] = 9480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ((array[i] >> 4) & PCI9111_AI_RESOLUTION_MASK) ^ 9490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_AI_RESOLUTION_2_CMP_BIT; 9508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 9528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 95352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 95452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* INTERRUPT SECTION */ 95552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 9568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef INTERRUPT_DEBUG 9588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 95970265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t pci9111_interrupt(int irq, void *p_device) 9608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 96171b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton struct comedi_device *dev = p_device; 96234c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *subdevice = dev->read_subdev; 963d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async; 9648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned long irq_flags; 9658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned char intcsr; 9668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!dev->attached) { 96852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Ignore interrupt before device fully attached. */ 96952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Might not even have allocated subdevices yet! */ 9708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_NONE; 9718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud async = subdevice->async; 9748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9755f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, irq_flags); 9768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 97752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Check if we are source of interrupt */ 9788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud intcsr = inb(dev_private->lcr_io_base + 9790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PLX9050_REGISTER_INTERRUPT_CONTROL); 9808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!(((intcsr & PLX9050_PCI_INTERRUPT_ENABLE) != 0) 9810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral && (((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) 9820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral == (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) 9830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || ((intcsr & (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS)) 9840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral == (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS))))) { 98552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Not the source of the interrupt. */ 98652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* (N.B. not using PLX9050_SOFTWARE_INTERRUPT) */ 9875f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 9888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_NONE; 9898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) == 9920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) { 99352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Interrupt comes from fifo_half-full signal */ 9948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci9111_is_fifo_full()) { 9960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral spin_unlock_irqrestore(&dev->spinlock, irq_flags); 9978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow"); 9988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_clear(); 9998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_cancel(dev, subdevice); 10008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 10018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_event(dev, subdevice); 10028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_HANDLED; 10048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci9111_is_fifo_half_full()) { 10078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int num_samples; 10088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int bytes_written = 0; 10098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef INTERRUPT_DEBUG 10118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": fifo is half full\n"); 10128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 10138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud num_samples = 10150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_FIFO_HALF_SIZE > 10160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->stop_counter 10170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral && !dev_private-> 10180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral stop_is_none ? dev_private->stop_counter : 10190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_FIFO_HALF_SIZE; 10208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud insw(PCI9111_IO_BASE + PCI9111_REGISTER_AD_FIFO_VALUE, 10210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->ai_bounce_buffer, num_samples); 10228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->scan_delay < 1) { 10248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bytes_written = 10250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cfc_write_array_to_buffer(subdevice, 10260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private-> 10270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ai_bounce_buffer, 10280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples * 10290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral sizeof(short)); 10308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 10318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int position = 0; 10328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int to_read; 10338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud while (position < num_samples) { 10358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->chunk_counter < 10360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len) { 10378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len - 10390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_counter; 10408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (to_read > 10420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - position) 10438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - 10450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral position; 10468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bytes_written += 10480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cfc_write_array_to_buffer 10490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (subdevice, 10500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->ai_bounce_buffer 10510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral + position, 10520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral to_read * sizeof(short)); 10538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 10548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_num_samples 10560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral - 10570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_counter; 10588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (to_read > 10590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - position) 10608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - 10620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral position; 10638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bytes_written += 10650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral sizeof(short) * to_read; 10668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud position += to_read; 10698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_counter += to_read; 10708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->chunk_counter >= 10720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_num_samples) 10738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_counter = 0; 10748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter -= 10780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bytes_written / sizeof(short); 10798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((dev_private->stop_counter == 0) && (!dev_private->stop_is_none)) { 10838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud async->events |= COMEDI_CB_EOA; 10848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_cancel(dev, subdevice); 10858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud /* Very important, otherwise another interrupt request will be inserted 10888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud * and will cause driver hangs on processing interrupt event. */ 10898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_clear(); 10918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10925f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 10938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_event(dev, subdevice); 10958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_HANDLED; 10978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 10988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 109952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 110052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* INSTANT ANALOG INPUT OUTPUT SECTION */ 110152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 11028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 110352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* analog instant input */ 11048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef AI_INSN_DEBUG 11068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1107da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_ai_insn_read(struct comedi_device *dev, 11080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice, 11090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 11108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 11118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int resolution = 11120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ((struct pci9111_board *)dev->board_ptr)->ai_resolution; 11138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int timeout, i; 11158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_INSN_DEBUG 11178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_insn set c/r/n = %2x/%2x/%2x\n", 11180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_CHAN((&insn->chanspec)[0]), 11190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_RANGE((&insn->chanspec)[0]), insn->n); 11208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 11218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0])); 11238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11242306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0])) 11258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_range_set(CR_RANGE((&insn->chanspec)[0])); 11268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 11288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < insn->n; i++) { 11308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_software_trigger(); 11318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud timeout = PCI9111_AI_INSTANT_READ_TIMEOUT; 11338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud while (timeout--) { 11358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!pci9111_is_fifo_empty()) 11368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud goto conversion_done; 11378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 11388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, "A/D read timeout"); 11408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = 0; 11418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 11428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -ETIME; 11438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralconversion_done: 11458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11462306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (resolution == PCI9111_HR_AI_RESOLUTION) 11478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = pci9111_hr_ai_get_data(); 11482306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom else 11498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = pci9111_ai_get_data(); 11508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 11518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_INSN_DEBUG 11538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_insn get c/r/t = %2x/%2x/%2x\n", 11540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_ai_channel_get(), 11550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_ai_range_get(), pci9111_trigger_and_autoscan_get()); 11568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 11578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return i; 11598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 116152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Analog instant output */ 11628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int 1164da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonpci9111_ao_insn_write(struct comedi_device *dev, 11650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_insn *insn, 11660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 11678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 11688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int i; 11698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < insn->n; i++) { 11718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ao_set_data(data[i]); 11728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->ao_readback = data[i]; 11738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 11748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return i; 11768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 117852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Analog output readback */ 11798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1180da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_ao_insn_read(struct comedi_device *dev, 11810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 11820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 11838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 11848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int i; 11858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11862306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom for (i = 0; i < insn->n; i++) 11878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = dev_private->ao_readback & PCI9111_AO_RESOLUTION_MASK; 11888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return i; 11908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 119252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 119352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* DIGITAL INPUT OUTPUT SECTION */ 119452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 11958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 119652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Digital inputs */ 11978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1198da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_di_insn_bits(struct comedi_device *dev, 11990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice, 12000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 12018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 1202790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int bits; 12038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits = pci9111_di_get_bits(); 12058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[1] = bits; 12068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 2; 12088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 12098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 121052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Digital outputs */ 12118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1212da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_do_insn_bits(struct comedi_device *dev, 12130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice, 12140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 12158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 1216790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int bits; 12178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 121852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Only set bits that have been masked */ 121952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* data[0] = mask */ 122052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* data[1] = bit state */ 12218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[0] &= PCI9111_DO_MASK; 12238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits = subdevice->state; 12258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits &= ~data[0]; 12268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits |= data[0] & data[1]; 12278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->state = bits; 12288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_do_set_bits(bits); 12308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[1] = bits; 12328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 2; 12348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 12358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 123652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 123752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* INITIALISATION SECTION */ 123852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 12398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 124052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Reset device */ 12418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1242da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_reset(struct comedi_device *dev) 12438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 124452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set trigger source to software */ 12458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, 12470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral true, false); 12488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, software); 12508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_pretrigger_set(dev, false); 12518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, false); 12528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 125352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Reset 8254 chip */ 12548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->timer_divisor_1 = 0; 12568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->timer_divisor_2 = 0; 12578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_timer_set(dev); 12598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 12618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 12628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 126352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Attach */ 126452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* - Register PCI device */ 126552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* - Declare device driver capability */ 12668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_attach(struct comedi_device *dev, 12680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it) 12698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 127034c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *subdevice; 12718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned long io_base, io_range, lcr_io_base, lcr_io_range; 127220fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy struct pci_dev *pci_device = NULL; 12738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int error, i; 1274940579fbae1a3a8967fe619562c8e78080dd873dBill Pemberton const struct pci9111_board *board; 12758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12762306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (alloc_private(dev, sizeof(struct pci9111_private_data)) < 0) 12778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -ENOMEM; 127852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Probe the device to determine what device in the series it is. */ 12798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: " PCI9111_DRIVER_NAME " driver\n", dev->minor); 12818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 128220fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy for_each_pci_dev(pci_device) { 12838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci_device->vendor == PCI_VENDOR_ID_ADLINK) { 12848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < pci9111_board_nbr; i++) { 12858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci9111_boards[i].device_id == 12860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_device->device) { 12877ecac4c38a813021155c4207592693ad1949b9b7Mark /* was a particular bus/slot 12887ecac4c38a813021155c4207592693ad1949b9b7Mark * requested? */ 12898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((it->options[0] != 0) 12900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || (it->options[1] != 0)) { 12917ecac4c38a813021155c4207592693ad1949b9b7Mark /* are we on the wrong 12927ecac4c38a813021155c4207592693ad1949b9b7Mark * bus/slot? */ 12938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci_device->bus->number != 12940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral it->options[0] 12950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || 12960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pci_device->devfn) 12970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral != it->options[1]) { 12988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud continue; 12998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->board_ptr = pci9111_boards + i; 13030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral board = 13040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (struct pci9111_board *) 13050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->board_ptr; 13068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->pci_device = pci_device; 13078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud goto found; 13088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", 13140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, it->options[0], it->options[1]); 13158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -EIO; 13168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralfound: 13188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n", 13200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, 13210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_boards[i].name, 13220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_device->bus->number, 13230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pci_device->devfn), 13240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_FUNC(pci_device->devfn), pci_device->irq); 13258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 132652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: Warn about non-tested boards. */ 13278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13287ecac4c38a813021155c4207592693ad1949b9b7Mark /* Read local configuration register base address 13297ecac4c38a813021155c4207592693ad1949b9b7Mark * [PCI_BASE_ADDRESS #1]. */ 13308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud lcr_io_base = pci_resource_start(pci_device, 1); 13328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud lcr_io_range = pci_resource_len(pci_device, 1); 13338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 13350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n", 13360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, lcr_io_base, lcr_io_range); 13378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 133852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Enable PCI device and request regions */ 13398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (comedi_pci_enable(pci_device, PCI9111_DRIVER_NAME) < 0) { 13400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 13410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ("comedi%d: Failed to enable PCI device and request regions\n", 13420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor); 13438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -EIO; 13448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 134552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Read PCI6308 register base address [PCI_BASE_ADDRESS #2]. */ 13468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud io_base = pci_resource_start(pci_device, 2); 13488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud io_range = pci_resource_len(pci_device, 2); 13498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: 6503 registers at address 0x%4lx [0x%4lx]\n", 13510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, io_base, io_range); 13528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->iobase = io_base; 13548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->board_name = board->name; 13558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->io_range = io_range; 13568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->is_valid = 0; 13578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->lcr_io_base = lcr_io_base; 13588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->lcr_io_range = lcr_io_range; 13598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_reset(dev); 13618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 136252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Irq setup */ 13638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->irq = 0; 13658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci_device->irq > 0) { 13665f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman if (request_irq(pci_device->irq, pci9111_interrupt, 13678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud IRQF_SHARED, PCI9111_DRIVER_NAME, dev) != 0) { 13688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: unable to allocate irq %u\n", 13690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, pci_device->irq); 13708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -EINVAL; 13718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->irq = pci_device->irq; 13748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 137552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: Add external multiplexer setup (according to option[2]). */ 13768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1377c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton error = alloc_subdevices(dev, 4); 1378c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (error < 0) 13798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return error; 13808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 0; 13828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->read_subdev = subdevice; 13838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_AI; 13858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; 13868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 138752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: Add external multiplexer data */ 138852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* if (devpriv->usemux) { subdevice->n_chan = devpriv->usemux; } */ 138952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* else { subdevice->n_chan = this_board->n_aichan; } */ 13908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = board->ai_channel_nbr; 13928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = board->ai_resolution_mask; 13938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->len_chanlist = board->ai_channel_nbr; 13948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = board->ai_range_list; 13958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->cancel = pci9111_ai_cancel; 13968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_read = pci9111_ai_insn_read; 13978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->do_cmdtest = pci9111_ai_do_cmd_test; 13988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->do_cmd = pci9111_ai_do_cmd; 13998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->munge = pci9111_ai_munge; 14008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 1; 14028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_AO; 14038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_WRITABLE | SDF_COMMON; 14048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = board->ao_channel_nbr; 14058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = board->ao_resolution_mask; 14068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->len_chanlist = board->ao_channel_nbr; 14078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = board->ao_range_list; 14088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_write = pci9111_ao_insn_write; 14098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_read = pci9111_ao_insn_read; 14108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 2; 14128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_DI; 14138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_READABLE; 14148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = PCI9111_DI_CHANNEL_NBR; 14158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = 1; 14168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = &range_digital; 14178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_bits = pci9111_di_insn_bits; 14188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 3; 14208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_DO; 14218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_READABLE | SDF_WRITABLE; 14228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = PCI9111_DO_CHANNEL_NBR; 14238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = 1; 14248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = &range_digital; 14258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_bits = pci9111_do_insn_bits; 14268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->is_valid = 1; 14288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 14308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 14318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 143252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Detach */ 14338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1434da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_detach(struct comedi_device *dev) 14358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 143652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Reset device */ 14378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1438525d1b1395858606103d4663a570cc8725ff2cedGreg Kroah-Hartman if (dev->private != NULL) { 14398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->is_valid) 14408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_reset(dev); 14418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 144352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Release previously allocated irq */ 14448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14452306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (dev->irq != 0) 14465f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 14478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1448525d1b1395858606103d4663a570cc8725ff2cedGreg Kroah-Hartman if (dev_private != NULL && dev_private->pci_device != NULL) { 14492306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (dev->iobase) 14508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_pci_disable(dev_private->pci_device); 14518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci_dev_put(dev_private->pci_device); 14528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 14538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 14558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 145690f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 145790f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 145890f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 145990f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 1460