adl_pci9111.c revision 90f703d30dd3e0c16ff80f35e34e511385a05ad5
18cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud/* 28cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 38cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi/drivers/adl_pci9111.c 48cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 58cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud Hardware driver for PCI9111 ADLink cards: 68cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 78cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud PCI-9111HR 88cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 98cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud Copyright (C) 2002-2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr> 108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud This program is free software; you can redistribute it and/or modify 128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud it under the terms of the GNU General Public License as published by 138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud the Free Software Foundation; either version 2 of the License, or 148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud (at your option) any later version. 158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud This program is distributed in the hope that it will be useful, 178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud but WITHOUT ANY WARRANTY; without even the implied warranty of 188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud GNU General Public License for more details. 208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud You should have received a copy of the GNU General Public License 228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud along with this program; if not, write to the Free Software 238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud*/ 258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud/* 278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudDriver: adl_pci9111 288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudDescription: Adlink PCI-9111HR 298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudAuthor: Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr> 308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudDevices: [ADLink] PCI-9111HR (adl_pci9111) 318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudStatus: experimental 328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudSupports: 348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud - ai_insn read 368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud - ao_insn read/write 378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud - di_insn read 388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud - do_insn read/write 398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud - ai_do_cmd mode with the following sources: 408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud - start_src TRIG_NOW 428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud - scan_begin_src TRIG_FOLLOW TRIG_TIMER TRIG_EXT 438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud - convert_src TRIG_TIMER TRIG_EXT 448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud - scan_end_src TRIG_COUNT 458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud - stop_src TRIG_COUNT TRIG_NONE 468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud The scanned channels must be consecutive and start from 0. They must 488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud all have the same range and aref. 498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudConfiguration options: 518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud [0] - PCI bus number (optional) 538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud [1] - PCI slot number (optional) 548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud If bus/slot is not specified, the first available PCI 568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud device will be used. 578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud*/ 598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud/* 618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudCHANGELOG: 628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2005/02/17 Extend AI streaming capabilities. Now, scan_begin_arg can be 648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud a multiple of chanlist_len*convert_arg. 658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2002/02/19 Fixed the two's complement conversion in pci9111_(hr_)ai_get_data. 668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2002/02/18 Added external trigger support for analog input. 678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudTODO: 698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud - Really test implemented functionality. 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 2508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_hr_ai_get_data() \ 2518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud (inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE) & PCI9111_HR_AI_RESOLUTION_MASK) \ 2528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT 2538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_ao_set_data(data) \ 255f7cbd7aad063b2a4b7aff6a743b2b00015ce3c3eBill Pemberton outw(data&PCI9111_AO_RESOLUTION_MASK, PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT) 2568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_di_get_bits() \ 2588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud inw(PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO) 2598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_do_set_bits(bits) \ 261f7cbd7aad063b2a4b7aff6a743b2b00015ce3c3eBill Pemberton outw(bits, PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO) 2628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_control_set(flags) \ 264f7cbd7aad063b2a4b7aff6a743b2b00015ce3c3eBill Pemberton outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_8254_CONTROL) 2658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_0_set(data) \ 2678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \ 26853106ae68acf6eda9593150a25fc44e30fd5ff68Bill Pemberton outb((data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0) 2698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_1_set(data) \ 2718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \ 27253106ae68acf6eda9593150a25fc44e30fd5ff68Bill Pemberton outb((data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1) 2738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_2_set(data) \ 2758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \ 27653106ae68acf6eda9593150a25fc44e30fd5ff68Bill Pemberton outb((data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2) 2778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 27852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Function prototypes */ 2798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_attach(struct comedi_device *dev, 2810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 282da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_detach(struct comedi_device *dev); 2830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void pci9111_ai_munge(struct comedi_device *dev, 2840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, void *data, 2850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int num_bytes, 2860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int start_chan_index); 2878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2889ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange pci9111_hr_ai_range = { 2898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5, 2908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud { 2910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(10), 2920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(5), 2930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(2.5), 2940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(1.25), 2950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(0.625) 2960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 2978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 2988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = { 3000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral { 3010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID, 3020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_ANY_ID, 0, 0, 0}, 3030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral /* { PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */ 3040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral { 3050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral 0} 3068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudMODULE_DEVICE_TABLE(pci, pci9111_pci_table); 3098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 31052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* */ 31152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Board specification structure */ 31252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* */ 3138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 314940579fbae1a3a8967fe619562c8e78080dd873dBill Pembertonstruct pci9111_board { 31552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton const char *name; /* driver name */ 3168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int device_id; 31752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ai_channel_nbr; /* num of A/D chans */ 31852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ao_channel_nbr; /* num of D/A chans */ 31952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ai_resolution; /* resolution of A/D */ 3208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int ai_resolution_mask; 32152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ao_resolution; /* resolution of D/A */ 3228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int ao_resolution_mask; 32352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton const struct comedi_lrange *ai_range_list; /* rangelist for A/D */ 32452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton const struct comedi_lrange *ao_range_list; /* rangelist for D/A */ 3258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int ai_acquisition_period_min_ns; 326940579fbae1a3a8967fe619562c8e78080dd873dBill Pemberton}; 3278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 328940579fbae1a3a8967fe619562c8e78080dd873dBill Pembertonstatic const struct pci9111_board pci9111_boards[] = { 3298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud { 3300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci9111_hr", 3310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = PCI9111_HR_DEVICE_ID, 3320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_channel_nbr = PCI9111_AI_CHANNEL_NBR, 3330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_channel_nbr = PCI9111_AO_CHANNEL_NBR, 3340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_resolution = PCI9111_HR_AI_RESOLUTION, 3350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_resolution_mask = PCI9111_HR_AI_RESOLUTION_MASK, 3360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_resolution = PCI9111_AO_RESOLUTION, 3370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_resolution_mask = PCI9111_AO_RESOLUTION_MASK, 3380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_range_list = &pci9111_hr_ai_range, 3390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_range_list = &range_bipolar10, 3400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_acquisition_period_min_ns = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS} 3418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_board_nbr \ 344940579fbae1a3a8967fe619562c8e78080dd873dBill Pemberton (sizeof(pci9111_boards)/sizeof(struct pci9111_board)) 3458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 346139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver pci9111_driver = { 34768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = PCI9111_DRIVER_NAME, 34868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 34968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = pci9111_attach, 35068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = pci9111_detach, 3518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudCOMEDI_PCI_INITCLEANUP(pci9111_driver, pci9111_pci_table); 3548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 35552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Private data structure */ 3568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 357c350fa1944f4ec1fe392ce0f3fc879f3899bb15dBill Pembertonstruct pci9111_private_data { 3588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud struct pci_dev *pci_device; 35952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton unsigned long io_range; /* PCI6503 io range */ 3608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 36152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton unsigned long lcr_io_base; /* Local configuration register base address */ 3628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned long lcr_io_range; 3638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int stop_counter; 3658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int stop_is_none; 3668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_delay; 3688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int chanlist_len; 3698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int chunk_counter; 3708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int chunk_num_samples; 3718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 37252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ao_readback; /* Last written analog output data */ 3738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 374525d1b1395858606103d4663a570cc8725ff2cedGreg Kroah-Hartman unsigned int timer_divisor_1; /* Divisor values for the 8254 timer pacer */ 375525d1b1395858606103d4663a570cc8725ff2cedGreg Kroah-Hartman unsigned int timer_divisor_2; 3768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 37752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int is_valid; /* Is device valid */ 3788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 379790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE]; 380c350fa1944f4ec1fe392ce0f3fc879f3899bb15dBill Pemberton}; 3818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 382c350fa1944f4ec1fe392ce0f3fc879f3899bb15dBill Pemberton#define dev_private ((struct pci9111_private_data *)dev->private) 3838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 38452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 38552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* PLX9050 SECTION */ 38652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 3878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_REGISTER_INTERRUPT_CONTROL 0x4c 3898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_ENABLE (1 << 0) 3918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_ACTIVE_HIGH (1 << 1) 3928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_STATUS (1 << 2) 3938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_ENABLE (1 << 3) 3948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_ACTIVE_HIGH (1 << 4) 3958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_STATUS (1 << 5) 3968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_PCI_INTERRUPT_ENABLE (1 << 6) 3978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_SOFTWARE_INTERRUPT (1 << 7) 3988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic void plx9050_interrupt_control(unsigned long io_base, 4000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi1_enable, 4010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi1_active_high, 4020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi2_enable, 4030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi2_active_high, 4040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool interrupt_enable) 4058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 4068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags = 0; 4078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi1_enable) 4098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI1_ENABLE; 4108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi1_active_high) 4118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI1_ACTIVE_HIGH; 4128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi2_enable) 4138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI2_ENABLE; 4148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi2_active_high) 4158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI2_ACTIVE_HIGH; 4168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (interrupt_enable) 4188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_PCI_INTERRUPT_ENABLE; 4198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud outb(flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL); 4218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 4228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 42352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 42452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* MISCELLANEOUS SECTION */ 42552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 4268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 42752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* 8254 timer */ 4288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 429da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_timer_set(struct comedi_device *dev) 4308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 4318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_control_set(PCI9111_8254_COUNTER_0 | 4320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_READ_LOAD_LSB_MSB | 4330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_MODE_0 | 4340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_BINARY_COUNTER); 4358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_control_set(PCI9111_8254_COUNTER_1 | 4370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_READ_LOAD_LSB_MSB | 4380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_MODE_2 | 4390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_BINARY_COUNTER); 4408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_control_set(PCI9111_8254_COUNTER_2 | 4420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_READ_LOAD_LSB_MSB | 4430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_MODE_2 | 4440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_BINARY_COUNTER); 4458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4465f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 4478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_counter_2_set(dev_private->timer_divisor_2); 4498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_counter_1_set(dev_private->timer_divisor_1); 4508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 4518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 452655f78f6aaa059ad262bc55e1c3575724c14867bBill Pembertonenum pci9111_trigger_sources { 4538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud software, 4548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud timer_pacer, 4558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud external 456655f78f6aaa059ad262bc55e1c3575724c14867bBill Pemberton}; 4578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 458da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_trigger_source_set(struct comedi_device *dev, 4590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral enum pci9111_trigger_sources source) 4608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 4618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 4628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_trigger_and_autoscan_get() & 0x09; 4648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud switch (source) { 4668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case software: 4678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_SOFTWARE_TRIGGER; 4688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 4698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case timer_pacer: 4718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_TIMER_PACER; 4728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 4738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case external: 4758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_EITS_EXTERNAL; 4768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 4778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 4788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_and_autoscan_set(flags); 4808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 4818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 482da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_pretrigger_set(struct comedi_device *dev, bool pretrigger) 4838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 4848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 4858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_trigger_and_autoscan_get() & 0x07; 4878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pretrigger) 4898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_PTRG_ON; 4908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_and_autoscan_set(flags); 4928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 4938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 494da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_autoscan_set(struct comedi_device *dev, bool autoscan) 4958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 4968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 4978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_trigger_and_autoscan_get() & 0x0e; 4998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (autoscan) 5018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_ASCAN_ON; 5028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_and_autoscan_set(flags); 5048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5063ba97b3c6258cb67450e0873584489f97d0debc5Bill Pembertonenum pci9111_ISC0_sources { 5078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_eoc, 5088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_fifo_half_full 5093ba97b3c6258cb67450e0873584489f97d0debc5Bill Pemberton}; 5108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 51152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pembertonenum pci9111_ISC1_sources { 5128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_timer_tick, 5138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_external_trigger 51452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton}; 5158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 516da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_interrupt_source_set(struct comedi_device *dev, 5170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral enum pci9111_ISC0_sources irq_0_source, 5180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral enum pci9111_ISC1_sources irq_1_source) 5198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 5218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_interrupt_and_fifo_get() & 0x04; 5238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (irq_0_source == irq_on_fifo_half_full) 5258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL; 5268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (irq_1_source == irq_on_external_trigger) 5288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_ISC1_SET_IRQ_ON_EXT_TRG; 5298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_and_fifo_set(flags); 5318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 53352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 53452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* HARDWARE TRIGGERED ANALOG INPUT SECTION */ 53552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 5368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 53752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Cancel analog input autoscan */ 5388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef AI_DO_CMD_DEBUG 5408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_ai_cancel(struct comedi_device *dev, 5420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 5438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 54452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Disable interrupts */ 5458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, 5470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral true, false); 5488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, software); 5508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, false); 5528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 5548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG 5568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_cancel\n"); 5578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 5588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 5608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 56252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Test analog input command */ 5638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 564f7cbd7aad063b2a4b7aff6a743b2b00015ce3c3eBill Pemberton#define pci9111_check_trigger_src(src, flags) \ 5658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud tmp = src; \ 5668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud src &= flags; \ 5678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!src || tmp != src) error++ 5688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int 570da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonpci9111_ai_do_cmd_test(struct comedi_device *dev, 5710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_cmd *cmd) 5728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int tmp; 5748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int error = 0; 5758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int range, reference; 5768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int i; 5770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct pci9111_board *board = (struct pci9111_board *)dev->board_ptr; 5788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 57952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 1 : check if trigger are trivialy valid */ 5808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->start_src, TRIG_NOW); 5828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->scan_begin_src, 5830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT); 5848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->convert_src, TRIG_TIMER | TRIG_EXT); 5858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->scan_end_src, TRIG_COUNT); 5868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->stop_src, TRIG_COUNT | TRIG_NONE); 5878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 5898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 1; 5908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 59152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* step 2 : make sure trigger sources are unique and mutually compatible */ 5928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->start_src != TRIG_NOW) 5948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 5958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_begin_src != TRIG_TIMER) && 5970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_begin_src != TRIG_FOLLOW) && 5980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_begin_src != TRIG_EXT)) 5998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6012306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT)) 6028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_TIMER) && 6040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral !((cmd->scan_begin_src == TRIG_TIMER) || 6052306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom (cmd->scan_begin_src == TRIG_FOLLOW))) 6068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_EXT) && 6080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral !((cmd->scan_begin_src == TRIG_EXT) || 6092306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom (cmd->scan_begin_src == TRIG_FOLLOW))) 6108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6112306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom 6128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_end_src != TRIG_COUNT) 6148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->stop_src != TRIG_COUNT) && (cmd->stop_src != TRIG_NONE)) 6168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 6198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 2; 6208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 62152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 3 : make sure arguments are trivialy compatible */ 6228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist_len < 1) { 6248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->chanlist_len = 1; 6258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist_len > board->ai_channel_nbr) { 6298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->chanlist_len = board->ai_channel_nbr; 6308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) { 6348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->start_arg = 0; 6358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_TIMER) && 6390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->convert_arg < board->ai_acquisition_period_min_ns)) { 6408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->convert_arg = board->ai_acquisition_period_min_ns; 6418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) { 6448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->convert_arg = 0; 6458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_begin_src == TRIG_TIMER) && 6490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_begin_arg < board->ai_acquisition_period_min_ns)) { 6508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = board->ai_acquisition_period_min_ns; 6518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_begin_src == TRIG_FOLLOW) && (cmd->scan_begin_arg != 0)) { 6548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = 0; 6558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_begin_src == TRIG_EXT) && (cmd->scan_begin_arg != 0)) { 6588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = 0; 6598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_end_src == TRIG_COUNT) && 6630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_end_arg != cmd->chanlist_len)) { 6648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_end_arg = cmd->chanlist_len; 6658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->stop_src == TRIG_COUNT) && (cmd->stop_arg < 1)) { 6698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->stop_arg = 1; 6708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->stop_src == TRIG_NONE) && (cmd->stop_arg != 0)) { 6738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->stop_arg = 0; 6748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 6788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 3; 6798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 68052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 4 : fix up any arguments */ 6818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->convert_src == TRIG_TIMER) { 6838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud tmp = cmd->convert_arg; 6848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, 6850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_1), 6860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_2), 6870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd->convert_arg), 6880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 6898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (tmp != cmd->convert_arg) 6908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 69252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* There's only one timer on this card, so the scan_begin timer must */ 69352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* be a multiple of chanlist_len*convert_arg */ 6948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_begin_src == TRIG_TIMER) { 6968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_begin_min; 6988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_begin_arg; 6998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_factor; 7008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud scan_begin_min = cmd->chanlist_len * cmd->convert_arg; 7028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_begin_arg != scan_begin_min) { 7048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (scan_begin_min < cmd->scan_begin_arg) { 7058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud scan_factor = 7060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_arg / scan_begin_min; 7078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud scan_begin_arg = scan_factor * scan_begin_min; 7088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_begin_arg != scan_begin_arg) { 7098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = scan_begin_arg; 7108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 7138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = scan_begin_min; 7148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 7208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 4; 7218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 72252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 5 : check channel list */ 7238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist) { 7258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud range = CR_RANGE(cmd->chanlist[0]); 7278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud reference = CR_AREF(cmd->chanlist[0]); 7288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist_len > 1) { 7308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < cmd->chanlist_len; i++) { 7318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (CR_CHAN(cmd->chanlist[i]) != i) { 7328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must be consecutive " 7340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "channels,counting upwards from 0\n"); 7358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (CR_RANGE(cmd->chanlist[i]) != range) { 7388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must all have the same gain\n"); 7408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (CR_AREF(cmd->chanlist[i]) != reference) { 7438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must all have the same reference\n"); 7458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 7498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((CR_CHAN(cmd->chanlist[0]) > 7500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (board->ai_channel_nbr - 1)) 7510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || (CR_CHAN(cmd->chanlist[0]) < 0)) { 7528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "channel number is out of limits\n"); 7548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 7608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 5; 7618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 7638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 7658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 76652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Analog input command */ 7678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_ai_do_cmd(struct comedi_device *dev, 7690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice) 7708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 771ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *async_cmd = &subdevice->async->cmd; 7728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!dev->irq) { 7748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "no irq assigned for PCI9111, cannot do hardware conversion"); 7768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -1; 7778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 77852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set channel scan limit */ 77952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* PCI9111 allows only scanning from channel 0 to channel n */ 78052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: handle the case of an external multiplexer */ 7818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (async_cmd->chanlist_len > 1) { 7838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_channel_set((async_cmd->chanlist_len) - 1); 7848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, true); 7858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 7868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_channel_set(CR_CHAN(async_cmd->chanlist[0])); 7878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, false); 7888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 79052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set gain */ 79152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* This is the same gain on every channel */ 7928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_range_set(CR_RANGE(async_cmd->chanlist[0])); 7948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud /* Set counter */ 7968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud switch (async_cmd->stop_src) { 7988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_COUNT: 7998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter = 8000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral async_cmd->stop_arg * async_cmd->chanlist_len; 8018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_is_none = 0; 8028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 8038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_NONE: 8058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter = 0; 8068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_is_none = 1; 8078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 8088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud default: 8108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, "Invalid stop trigger"); 8118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -1; 8128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 81452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set timer pacer */ 8158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->scan_delay = 0; 8178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud switch (async_cmd->convert_src) { 8188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_TIMER: 8198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, 8200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_1), 8210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_2), 8220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(async_cmd->convert_arg), 8230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral async_cmd-> 8240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral flags & TRIG_ROUND_MASK); 8258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG 8268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": divisors = %d, %d\n", 8270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->timer_divisor_1, 8280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->timer_divisor_2); 8298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 8308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, software); 8328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_timer_set(dev); 8338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 8348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_source_set(dev, irq_on_fifo_half_full, 8350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral irq_on_timer_tick); 8368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, timer_pacer); 8378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, 8380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral false, true, true); 8398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->scan_delay = 8410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (async_cmd->scan_begin_arg / (async_cmd->convert_arg * 8420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral async_cmd->chanlist_len)) - 1; 8438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 8458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_EXT: 8478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, external); 8498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 8508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_source_set(dev, irq_on_fifo_half_full, 8510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral irq_on_timer_tick); 8528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, 8530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral false, true, true); 8548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 8568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud default: 8588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, "Invalid convert trigger"); 8598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -1; 8608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter *= (1 + dev_private->scan_delay); 8638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chanlist_len = async_cmd->chanlist_len; 8648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_counter = 0; 8658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_num_samples = 8660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len * (1 + dev_private->scan_delay); 8678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG 8698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": start interruptions!\n"); 8708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": trigger source = %2x\n", 8710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_trigger_and_autoscan_get()); 8728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": irq source = %2x\n", 8730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_interrupt_and_fifo_get()); 8748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_do_cmd\n"); 8758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": stop counter = %d\n", 8760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->stop_counter); 8778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": scan delay = %d\n", 8780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->scan_delay); 8798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": chanlist_len = %d\n", 8800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len); 8818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": chunk num samples = %d\n", 8820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_num_samples); 8838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 8848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 8868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 8878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void pci9111_ai_munge(struct comedi_device *dev, 8890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, void *data, 8900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int num_bytes, 8910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int start_chan_index) 8928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 893790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int i, num_samples = num_bytes / sizeof(short); 894790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short *array = data; 8958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int resolution = 8960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ((struct pci9111_board *)dev->board_ptr)->ai_resolution; 8978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < num_samples; i++) { 8998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (resolution == PCI9111_HR_AI_RESOLUTION) 9008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud array[i] = 9010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (array[i] & PCI9111_HR_AI_RESOLUTION_MASK) ^ 9020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_HR_AI_RESOLUTION_2_CMP_BIT; 9038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud else 9048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud array[i] = 9050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ((array[i] >> 4) & PCI9111_AI_RESOLUTION_MASK) ^ 9060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_AI_RESOLUTION_2_CMP_BIT; 9078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 9098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 91052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 91152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* INTERRUPT SECTION */ 91252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 9138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef INTERRUPT_DEBUG 9158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 91670265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t pci9111_interrupt(int irq, void *p_device) 9178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 91871b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton struct comedi_device *dev = p_device; 91934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *subdevice = dev->read_subdev; 920d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async; 9218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned long irq_flags; 9228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned char intcsr; 9238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!dev->attached) { 92552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Ignore interrupt before device fully attached. */ 92652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Might not even have allocated subdevices yet! */ 9278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_NONE; 9288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud async = subdevice->async; 9318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9325f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, irq_flags); 9338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 93452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Check if we are source of interrupt */ 9358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud intcsr = inb(dev_private->lcr_io_base + 9360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PLX9050_REGISTER_INTERRUPT_CONTROL); 9378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!(((intcsr & PLX9050_PCI_INTERRUPT_ENABLE) != 0) 9380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral && (((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) 9390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral == (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) 9400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || ((intcsr & (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS)) 9410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral == (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS))))) { 94252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Not the source of the interrupt. */ 94352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* (N.B. not using PLX9050_SOFTWARE_INTERRUPT) */ 9445f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 9458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_NONE; 9468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) == 9490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) { 95052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Interrupt comes from fifo_half-full signal */ 9518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci9111_is_fifo_full()) { 9530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral spin_unlock_irqrestore(&dev->spinlock, irq_flags); 9548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow"); 9558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_clear(); 9568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_cancel(dev, subdevice); 9578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 9588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_event(dev, subdevice); 9598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_HANDLED; 9618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci9111_is_fifo_half_full()) { 9648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int num_samples; 9658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int bytes_written = 0; 9668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef INTERRUPT_DEBUG 9688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": fifo is half full\n"); 9698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 9708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud num_samples = 9720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_FIFO_HALF_SIZE > 9730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->stop_counter 9740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral && !dev_private-> 9750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral stop_is_none ? dev_private->stop_counter : 9760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_FIFO_HALF_SIZE; 9778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud insw(PCI9111_IO_BASE + PCI9111_REGISTER_AD_FIFO_VALUE, 9780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->ai_bounce_buffer, num_samples); 9798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->scan_delay < 1) { 9818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bytes_written = 9820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cfc_write_array_to_buffer(subdevice, 9830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private-> 9840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ai_bounce_buffer, 9850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples * 9860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral sizeof(short)); 9878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 9888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int position = 0; 9898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int to_read; 9908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud while (position < num_samples) { 9928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->chunk_counter < 9930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len) { 9948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 9950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len - 9960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_counter; 9978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (to_read > 9990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - position) 10008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - 10020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral position; 10038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bytes_written += 10050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cfc_write_array_to_buffer 10060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (subdevice, 10070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->ai_bounce_buffer 10080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral + position, 10090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral to_read * sizeof(short)); 10108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 10118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_num_samples 10130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral - 10140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_counter; 10158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (to_read > 10160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - position) 10178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - 10190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral position; 10208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bytes_written += 10220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral sizeof(short) * to_read; 10238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud position += to_read; 10268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_counter += to_read; 10278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->chunk_counter >= 10290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_num_samples) 10308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_counter = 0; 10318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter -= 10350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bytes_written / sizeof(short); 10368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((dev_private->stop_counter == 0) && (!dev_private->stop_is_none)) { 10408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud async->events |= COMEDI_CB_EOA; 10418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_cancel(dev, subdevice); 10428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud /* Very important, otherwise another interrupt request will be inserted 10458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud * and will cause driver hangs on processing interrupt event. */ 10468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_clear(); 10488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10495f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 10508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_event(dev, subdevice); 10528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_HANDLED; 10548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 10558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 105652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 105752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* INSTANT ANALOG INPUT OUTPUT SECTION */ 105852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 10598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 106052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* analog instant input */ 10618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef AI_INSN_DEBUG 10638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1064da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_ai_insn_read(struct comedi_device *dev, 10650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice, 10660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 10678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 10688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int resolution = 10690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ((struct pci9111_board *)dev->board_ptr)->ai_resolution; 10708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int timeout, i; 10728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_INSN_DEBUG 10748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_insn set c/r/n = %2x/%2x/%2x\n", 10750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_CHAN((&insn->chanspec)[0]), 10760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_RANGE((&insn->chanspec)[0]), insn->n); 10778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 10788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0])); 10808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10812306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0])) 10828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_range_set(CR_RANGE((&insn->chanspec)[0])); 10838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 10858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < insn->n; i++) { 10878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_software_trigger(); 10888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud timeout = PCI9111_AI_INSTANT_READ_TIMEOUT; 10908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud while (timeout--) { 10928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!pci9111_is_fifo_empty()) 10938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud goto conversion_done; 10948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, "A/D read timeout"); 10978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = 0; 10988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 10998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -ETIME; 11008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralconversion_done: 11028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11032306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (resolution == PCI9111_HR_AI_RESOLUTION) 11048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = pci9111_hr_ai_get_data(); 11052306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom else 11068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = pci9111_ai_get_data(); 11078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 11088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_INSN_DEBUG 11108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_insn get c/r/t = %2x/%2x/%2x\n", 11110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_ai_channel_get(), 11120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_ai_range_get(), pci9111_trigger_and_autoscan_get()); 11138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 11148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return i; 11168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 111852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Analog instant output */ 11198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int 1121da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonpci9111_ao_insn_write(struct comedi_device *dev, 11220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_insn *insn, 11230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 11248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 11258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int i; 11268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < insn->n; i++) { 11288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ao_set_data(data[i]); 11298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->ao_readback = data[i]; 11308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 11318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return i; 11338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 113552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Analog output readback */ 11368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1137da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_ao_insn_read(struct comedi_device *dev, 11380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 11390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 11408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 11418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int i; 11428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11432306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom for (i = 0; i < insn->n; i++) 11448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = dev_private->ao_readback & PCI9111_AO_RESOLUTION_MASK; 11458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return i; 11478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 114952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 115052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* DIGITAL INPUT OUTPUT SECTION */ 115152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 11528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 115352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Digital inputs */ 11548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1155da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_di_insn_bits(struct comedi_device *dev, 11560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice, 11570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 11588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 1159790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int bits; 11608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits = pci9111_di_get_bits(); 11628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[1] = bits; 11638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 2; 11658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 116752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Digital outputs */ 11688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1169da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_do_insn_bits(struct comedi_device *dev, 11700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice, 11710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 11728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 1173790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int bits; 11748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 117552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Only set bits that have been masked */ 117652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* data[0] = mask */ 117752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* data[1] = bit state */ 11788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[0] &= PCI9111_DO_MASK; 11808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits = subdevice->state; 11828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits &= ~data[0]; 11838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits |= data[0] & data[1]; 11848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->state = bits; 11858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_do_set_bits(bits); 11878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[1] = bits; 11898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 2; 11918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 119352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 119452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* INITIALISATION SECTION */ 119552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 11968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 119752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Reset device */ 11988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1199da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_reset(struct comedi_device *dev) 12008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 120152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set trigger source to software */ 12028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, 12040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral true, false); 12058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, software); 12078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_pretrigger_set(dev, false); 12088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, false); 12098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 121052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Reset 8254 chip */ 12118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->timer_divisor_1 = 0; 12138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->timer_divisor_2 = 0; 12148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_timer_set(dev); 12168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 12188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 12198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 122052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Attach */ 122152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* - Register PCI device */ 122252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* - Declare device driver capability */ 12238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_attach(struct comedi_device *dev, 12250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it) 12268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 122734c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *subdevice; 12288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned long io_base, io_range, lcr_io_base, lcr_io_range; 12298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud struct pci_dev *pci_device; 12308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int error, i; 1231940579fbae1a3a8967fe619562c8e78080dd873dBill Pemberton const struct pci9111_board *board; 12328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12332306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (alloc_private(dev, sizeof(struct pci9111_private_data)) < 0) 12348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -ENOMEM; 123552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Probe the device to determine what device in the series it is. */ 12368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: " PCI9111_DRIVER_NAME " driver\n", dev->minor); 12388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); 12400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_device != NULL; 12410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) { 12428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci_device->vendor == PCI_VENDOR_ID_ADLINK) { 12438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < pci9111_board_nbr; i++) { 12448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci9111_boards[i].device_id == 12450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_device->device) { 124652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* was a particular bus/slot requested? */ 12478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((it->options[0] != 0) 12480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || (it->options[1] != 0)) { 124952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* are we on the wrong bus/slot? */ 12508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci_device->bus->number != 12510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral it->options[0] 12520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || 12530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pci_device->devfn) 12540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral != it->options[1]) { 12558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud continue; 12568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 12578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 12588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->board_ptr = pci9111_boards + i; 12600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral board = 12610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (struct pci9111_board *) 12620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->board_ptr; 12638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->pci_device = pci_device; 12648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud goto found; 12658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 12668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 12678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 12688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 12698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", 12710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, it->options[0], it->options[1]); 12728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -EIO; 12738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralfound: 12758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n", 12770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, 12780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_boards[i].name, 12790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_device->bus->number, 12800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pci_device->devfn), 12810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_FUNC(pci_device->devfn), pci_device->irq); 12828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 128352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: Warn about non-tested boards. */ 12848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 128552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Read local configuration register base address [PCI_BASE_ADDRESS #1]. */ 12868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud lcr_io_base = pci_resource_start(pci_device, 1); 12888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud lcr_io_range = pci_resource_len(pci_device, 1); 12898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 12910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n", 12920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, lcr_io_base, lcr_io_range); 12938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 129452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Enable PCI device and request regions */ 12958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (comedi_pci_enable(pci_device, PCI9111_DRIVER_NAME) < 0) { 12960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 12970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ("comedi%d: Failed to enable PCI device and request regions\n", 12980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor); 12998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -EIO; 13008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 130152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Read PCI6308 register base address [PCI_BASE_ADDRESS #2]. */ 13028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud io_base = pci_resource_start(pci_device, 2); 13048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud io_range = pci_resource_len(pci_device, 2); 13058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: 6503 registers at address 0x%4lx [0x%4lx]\n", 13070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, io_base, io_range); 13088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->iobase = io_base; 13108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->board_name = board->name; 13118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->io_range = io_range; 13128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->is_valid = 0; 13138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->lcr_io_base = lcr_io_base; 13148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->lcr_io_range = lcr_io_range; 13158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_reset(dev); 13178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 131852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Irq setup */ 13198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->irq = 0; 13218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci_device->irq > 0) { 13225f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman if (request_irq(pci_device->irq, pci9111_interrupt, 13238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud IRQF_SHARED, PCI9111_DRIVER_NAME, dev) != 0) { 13248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: unable to allocate irq %u\n", 13250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, pci_device->irq); 13268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -EINVAL; 13278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->irq = pci_device->irq; 13308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 133152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: Add external multiplexer setup (according to option[2]). */ 13328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1333c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton error = alloc_subdevices(dev, 4); 1334c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (error < 0) 13358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return error; 13368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 0; 13388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->read_subdev = subdevice; 13398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_AI; 13418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; 13428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 134352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: Add external multiplexer data */ 134452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* if (devpriv->usemux) { subdevice->n_chan = devpriv->usemux; } */ 134552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* else { subdevice->n_chan = this_board->n_aichan; } */ 13468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = board->ai_channel_nbr; 13488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = board->ai_resolution_mask; 13498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->len_chanlist = board->ai_channel_nbr; 13508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = board->ai_range_list; 13518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->cancel = pci9111_ai_cancel; 13528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_read = pci9111_ai_insn_read; 13538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->do_cmdtest = pci9111_ai_do_cmd_test; 13548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->do_cmd = pci9111_ai_do_cmd; 13558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->munge = pci9111_ai_munge; 13568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 1; 13588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_AO; 13598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_WRITABLE | SDF_COMMON; 13608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = board->ao_channel_nbr; 13618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = board->ao_resolution_mask; 13628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->len_chanlist = board->ao_channel_nbr; 13638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = board->ao_range_list; 13648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_write = pci9111_ao_insn_write; 13658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_read = pci9111_ao_insn_read; 13668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 2; 13688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_DI; 13698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_READABLE; 13708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = PCI9111_DI_CHANNEL_NBR; 13718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = 1; 13728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = &range_digital; 13738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_bits = pci9111_di_insn_bits; 13748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 3; 13768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_DO; 13778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_READABLE | SDF_WRITABLE; 13788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = PCI9111_DO_CHANNEL_NBR; 13798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = 1; 13808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = &range_digital; 13818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_bits = pci9111_do_insn_bits; 13828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->is_valid = 1; 13848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 13868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 13878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 138852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Detach */ 13898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1390da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_detach(struct comedi_device *dev) 13918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 139252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Reset device */ 13938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1394525d1b1395858606103d4663a570cc8725ff2cedGreg Kroah-Hartman if (dev->private != NULL) { 13958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->is_valid) 13968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_reset(dev); 13978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 139952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Release previously allocated irq */ 14008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14012306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (dev->irq != 0) 14025f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 14038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1404525d1b1395858606103d4663a570cc8725ff2cedGreg Kroah-Hartman if (dev_private != NULL && dev_private->pci_device != NULL) { 14052306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (dev->iobase) 14068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_pci_disable(dev_private->pci_device); 14078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci_dev_put(dev_private->pci_device); 14088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 14098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 14118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 141290f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 141390f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 141490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 141590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 1416