adl_pci9111.c revision 842ec6ba3bdf6de35359726b0428095fdd0f9b45
18cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud/* 28cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawsoncomedi/drivers/adl_pci9111.c 48cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice DawsonHardware driver for PCI9111 ADLink cards: 68cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice DawsonPCI-9111HR 88cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice DawsonCopyright (C) 2002-2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr> 108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice DawsonThis program is free software; you can redistribute it and/or modify 12842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawsonit under the terms of the GNU General Public License as published by 13842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawsonthe Free Software Foundation; either version 2 of the License, or 14842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson(at your option) any later version. 158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 16842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice DawsonThis program is distributed in the hope that it will be useful, 17842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawsonbut WITHOUT ANY WARRANTY; without even the implied warranty of 18842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice DawsonMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice DawsonGNU General Public License for more details. 208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 21842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice DawsonYou should have received a copy of the GNU General Public License 22842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawsonalong with this program; if not, write to the Free Software 23842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice DawsonFoundation, 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 35842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson - ai_insn read 36842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson - ao_insn read/write 37842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson - di_insn read 38842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson - do_insn read/write 39842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson - ai_do_cmd mode with the following sources: 408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 41842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson - start_src TRIG_NOW 42842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson - scan_begin_src TRIG_FOLLOW TRIG_TIMER TRIG_EXT 43842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson - convert_src TRIG_TIMER TRIG_EXT 44842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson - scan_end_src TRIG_COUNT 45842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson - stop_src TRIG_COUNT TRIG_NONE 468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 47842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice DawsonThe scanned channels must be consecutive and start from 0. They must 48842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawsonall have the same range and aref. 498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudConfiguration options: 518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 52842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson [0] - PCI bus number (optional) 53842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson [1] - PCI slot number (optional) 548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 55842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice DawsonIf bus/slot is not specified, the first available PCI 56842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawsondevice will be used. 578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud*/ 598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud/* 618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudCHANGELOG: 628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 63842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson2005/02/17 Extend AI streaming capabilities. Now, scan_begin_arg can be 64842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawsona multiple of chanlist_len*convert_arg. 65842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson2002/02/19 Fixed the two's complement conversion in pci9111_(hr_)ai_get_data. 66842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson2002/02/18 Added external trigger support for analog input. 678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudTODO: 698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 70842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson - Really test implemented functionality. 71842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson - Add support for the PCI-9111DG with a probe routine to identify 72842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson the card type (perhaps with the help of the channel number readback 73842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson of the A/D Data register). 74842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson - 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() \ 190842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK)&0x0F) 1918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_trigger_and_autoscan_set(flags) \ 193842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_TRIGGER_MODE_CONTROL) 1948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 195842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson#define pci9111_interrupt_and_fifo_get() \ 196842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) \ 197842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson >> 4) & 0x03) 1988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_interrupt_and_fifo_set(flags) \ 200842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL) 2018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_interrupt_clear() \ 203842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb(0, PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CLEAR) 2048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_software_trigger() \ 206842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb(0, PCI9111_IO_BASE+PCI9111_REGISTER_SOFTWARE_TRIGGER) 2078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 208842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson#define pci9111_fifo_reset() do { \ 209842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ 210842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \ 211842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb(PCI9111_FFEN_SET_FIFO_DISABLE, \ 212842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \ 213842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb(PCI9111_FFEN_SET_FIFO_ENABLE, \ 214842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \ 215842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson } while (0) 2168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_is_fifo_full() \ 218842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ 219842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson PCI9111_FIFO_FULL_MASK) == 0) 2208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_is_fifo_half_full() \ 222842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ 223842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson PCI9111_FIFO_HALF_FULL_MASK) == 0) 2248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_is_fifo_empty() \ 226842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \ 227842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson PCI9111_FIFO_EMPTY_MASK) == 0) 2288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 229842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson#define pci9111_ai_channel_set(channel) \ 230842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb((channel)&PCI9111_CHANNEL_MASK, \ 231842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_CONTROL) 2328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 233842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson#define pci9111_ai_channel_get() \ 234842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_READBACK) \ 235842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson &PCI9111_CHANNEL_MASK) 2368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 237842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson#define pci9111_ai_range_set(range) \ 238842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb((range)&PCI9111_RANGE_MASK, \ 239842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_INPUT_SIGNAL_RANGE) 2408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 241842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson#define pci9111_ai_range_get() \ 242842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson (inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK) \ 243842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson &PCI9111_RANGE_MASK) 2448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 245842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson#define pci9111_ai_get_data() \ 246842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson (((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)>>4) \ 247842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson &PCI9111_AI_RESOLUTION_MASK) \ 248842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson ^ PCI9111_AI_RESOLUTION_2_CMP_BIT) 2498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 250842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson#define pci9111_hr_ai_get_data() \ 251842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson ((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE) \ 252842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson &PCI9111_HR_AI_RESOLUTION_MASK) \ 253842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT) 2548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 255842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson#define pci9111_ao_set_data(data) \ 256842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outw(data&PCI9111_AO_RESOLUTION_MASK, \ 257842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT) 2588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_di_get_bits() \ 260842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson inw(PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO) 2618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_do_set_bits(bits) \ 263842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outw(bits, PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO) 2648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_control_set(flags) \ 266842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb(flags, PCI9111_IO_BASE+PCI9111_REGISTER_8254_CONTROL) 2678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_0_set(data) \ 269842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \ 270842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb((data >> 8) & 0xFF, \ 271842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0) 2728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_1_set(data) \ 274842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \ 275842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb((data >> 8) & 0xFF, \ 276842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1) 2778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_2_set(data) \ 279842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \ 280842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb((data >> 8) & 0xFF, \ 281842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2) 2828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 28352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Function prototypes */ 2848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_attach(struct comedi_device *dev, 2860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 287da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_detach(struct comedi_device *dev); 2880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void pci9111_ai_munge(struct comedi_device *dev, 2890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, void *data, 2900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int num_bytes, 2910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int start_chan_index); 2928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2939ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange pci9111_hr_ai_range = { 2948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5, 2958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud { 2960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(10), 2970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(5), 2980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(2.5), 2990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(1.25), 3000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(0.625) 3010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 3028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = { 3057ecac4c38a813021155c4207592693ad1949b9b7Mark { PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 3067ecac4c38a813021155c4207592693ad1949b9b7Mark 0, 0, 0 }, 3077ecac4c38a813021155c4207592693ad1949b9b7Mark /* { PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 3087ecac4c38a813021155c4207592693ad1949b9b7Mark * 0, 0, 0 }, */ 3097ecac4c38a813021155c4207592693ad1949b9b7Mark { 0 } 3108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudMODULE_DEVICE_TABLE(pci, pci9111_pci_table); 3138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 31452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* */ 31552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Board specification structure */ 31652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* */ 3178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 318940579fbae1a3a8967fe619562c8e78080dd873dBill Pembertonstruct pci9111_board { 31952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton const char *name; /* driver name */ 3208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int device_id; 32152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ai_channel_nbr; /* num of A/D chans */ 32252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ao_channel_nbr; /* num of D/A chans */ 32352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ai_resolution; /* resolution of A/D */ 3248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int ai_resolution_mask; 32552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ao_resolution; /* resolution of D/A */ 3268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int ao_resolution_mask; 32752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton const struct comedi_lrange *ai_range_list; /* rangelist for A/D */ 32852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton const struct comedi_lrange *ao_range_list; /* rangelist for D/A */ 3298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int ai_acquisition_period_min_ns; 330940579fbae1a3a8967fe619562c8e78080dd873dBill Pemberton}; 3318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 332940579fbae1a3a8967fe619562c8e78080dd873dBill Pembertonstatic const struct pci9111_board pci9111_boards[] = { 3338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud { 3340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci9111_hr", 3350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = PCI9111_HR_DEVICE_ID, 3360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_channel_nbr = PCI9111_AI_CHANNEL_NBR, 3370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_channel_nbr = PCI9111_AO_CHANNEL_NBR, 3380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_resolution = PCI9111_HR_AI_RESOLUTION, 3390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_resolution_mask = PCI9111_HR_AI_RESOLUTION_MASK, 3400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_resolution = PCI9111_AO_RESOLUTION, 3410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_resolution_mask = PCI9111_AO_RESOLUTION_MASK, 3420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_range_list = &pci9111_hr_ai_range, 3430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_range_list = &range_bipolar10, 3440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_acquisition_period_min_ns = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS} 3458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_board_nbr \ 348842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson (sizeof(pci9111_boards)/sizeof(struct pci9111_board)) 3498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 350139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver pci9111_driver = { 35168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = PCI9111_DRIVER_NAME, 35268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 35368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = pci9111_attach, 35468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = pci9111_detach, 3558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 357727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __devinit pci9111_driver_pci_probe(struct pci_dev *dev, 358727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas const struct pci_device_id *ent) 359727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 360727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return comedi_pci_auto_config(dev, pci9111_driver.driver_name); 361727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 362727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 363727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __devexit pci9111_driver_pci_remove(struct pci_dev *dev) 364727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 365727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_pci_auto_unconfig(dev); 366727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 367727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 368727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic struct pci_driver pci9111_driver_pci_driver = { 369727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .id_table = pci9111_pci_table, 370727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .probe = &pci9111_driver_pci_probe, 371727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .remove = __devexit_p(&pci9111_driver_pci_remove) 372727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}; 373727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 374727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __init pci9111_driver_init_module(void) 375727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 376727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas int retval; 377727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 378727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas retval = comedi_driver_register(&pci9111_driver); 379727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas if (retval < 0) 380727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return retval; 381727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 382727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas pci9111_driver_pci_driver.name = (char *)pci9111_driver.driver_name; 383727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return pci_register_driver(&pci9111_driver_pci_driver); 384727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 385727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 386727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __exit pci9111_driver_cleanup_module(void) 387727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 388727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas pci_unregister_driver(&pci9111_driver_pci_driver); 389727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_driver_unregister(&pci9111_driver); 390727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 391727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 392727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_init(pci9111_driver_init_module); 393727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_exit(pci9111_driver_cleanup_module); 3948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 39552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Private data structure */ 3968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 397c350fa1944f4ec1fe392ce0f3fc879f3899bb15dBill Pembertonstruct pci9111_private_data { 3988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud struct pci_dev *pci_device; 39952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton unsigned long io_range; /* PCI6503 io range */ 4008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4017ecac4c38a813021155c4207592693ad1949b9b7Mark unsigned long lcr_io_base; /* Local configuration register base 4027ecac4c38a813021155c4207592693ad1949b9b7Mark * address */ 4038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned long lcr_io_range; 4048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int stop_counter; 4068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int stop_is_none; 4078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_delay; 4098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int chanlist_len; 4108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int chunk_counter; 4118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int chunk_num_samples; 4128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 41352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ao_readback; /* Last written analog output data */ 4148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4157ecac4c38a813021155c4207592693ad1949b9b7Mark unsigned int timer_divisor_1; /* Divisor values for the 8254 timer 4167ecac4c38a813021155c4207592693ad1949b9b7Mark * pacer */ 417525d1b1395858606103d4663a570cc8725ff2cedGreg Kroah-Hartman unsigned int timer_divisor_2; 4188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 41952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int is_valid; /* Is device valid */ 4208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 421790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE]; 422c350fa1944f4ec1fe392ce0f3fc879f3899bb15dBill Pemberton}; 4238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4247ecac4c38a813021155c4207592693ad1949b9b7Mark#define dev_private ((struct pci9111_private_data *)dev->private) 4258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 42652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 42752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* PLX9050 SECTION */ 42852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 4298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_REGISTER_INTERRUPT_CONTROL 0x4c 4318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_ENABLE (1 << 0) 4338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_ACTIVE_HIGH (1 << 1) 4348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_STATUS (1 << 2) 4358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_ENABLE (1 << 3) 4368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_ACTIVE_HIGH (1 << 4) 4378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_STATUS (1 << 5) 4388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_PCI_INTERRUPT_ENABLE (1 << 6) 4398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_SOFTWARE_INTERRUPT (1 << 7) 4408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic void plx9050_interrupt_control(unsigned long io_base, 4420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi1_enable, 4430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi1_active_high, 4440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi2_enable, 4450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi2_active_high, 4460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool interrupt_enable) 4478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 4488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags = 0; 4498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi1_enable) 4518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI1_ENABLE; 4528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi1_active_high) 4538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI1_ACTIVE_HIGH; 4548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi2_enable) 4558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI2_ENABLE; 4568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi2_active_high) 4578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI2_ACTIVE_HIGH; 4588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (interrupt_enable) 4608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_PCI_INTERRUPT_ENABLE; 4618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud outb(flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL); 4638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 4648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 46552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 46652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* MISCELLANEOUS SECTION */ 46752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 4688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 46952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* 8254 timer */ 4708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 471da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_timer_set(struct comedi_device *dev) 4728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 4738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_control_set(PCI9111_8254_COUNTER_0 | 4740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_READ_LOAD_LSB_MSB | 4750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_MODE_0 | 4760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_BINARY_COUNTER); 4778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_control_set(PCI9111_8254_COUNTER_1 | 4790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_READ_LOAD_LSB_MSB | 4800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_MODE_2 | 4810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_BINARY_COUNTER); 4828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_control_set(PCI9111_8254_COUNTER_2 | 4840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_READ_LOAD_LSB_MSB | 4850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_MODE_2 | 4860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_BINARY_COUNTER); 4878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4885f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 4898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_counter_2_set(dev_private->timer_divisor_2); 4918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_counter_1_set(dev_private->timer_divisor_1); 4928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 4938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 494655f78f6aaa059ad262bc55e1c3575724c14867bBill Pembertonenum pci9111_trigger_sources { 4958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud software, 4968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud timer_pacer, 4978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud external 498655f78f6aaa059ad262bc55e1c3575724c14867bBill Pemberton}; 4998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 500da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_trigger_source_set(struct comedi_device *dev, 5010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral enum pci9111_trigger_sources source) 5028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 5048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_trigger_and_autoscan_get() & 0x09; 5068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud switch (source) { 5088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case software: 5098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_SOFTWARE_TRIGGER; 5108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 5118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case timer_pacer: 5138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_TIMER_PACER; 5148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 5158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case external: 5178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_EITS_EXTERNAL; 5188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 5198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 5208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_and_autoscan_set(flags); 5228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 524da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_pretrigger_set(struct comedi_device *dev, bool pretrigger) 5258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 5278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_trigger_and_autoscan_get() & 0x07; 5298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pretrigger) 5318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_PTRG_ON; 5328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_and_autoscan_set(flags); 5348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 536da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_autoscan_set(struct comedi_device *dev, bool autoscan) 5378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 5398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_trigger_and_autoscan_get() & 0x0e; 5418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (autoscan) 5438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_ASCAN_ON; 5448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_and_autoscan_set(flags); 5468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5483ba97b3c6258cb67450e0873584489f97d0debc5Bill Pembertonenum pci9111_ISC0_sources { 5498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_eoc, 5508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_fifo_half_full 5513ba97b3c6258cb67450e0873584489f97d0debc5Bill Pemberton}; 5528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 55352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pembertonenum pci9111_ISC1_sources { 5548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_timer_tick, 5558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_external_trigger 55652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton}; 5578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 558da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_interrupt_source_set(struct comedi_device *dev, 5590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral enum pci9111_ISC0_sources irq_0_source, 5600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral enum pci9111_ISC1_sources irq_1_source) 5618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 5638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_interrupt_and_fifo_get() & 0x04; 5658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (irq_0_source == irq_on_fifo_half_full) 5678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL; 5688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (irq_1_source == irq_on_external_trigger) 5708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_ISC1_SET_IRQ_ON_EXT_TRG; 5718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_and_fifo_set(flags); 5738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 57552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 57652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* HARDWARE TRIGGERED ANALOG INPUT SECTION */ 57752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 5788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 57952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Cancel analog input autoscan */ 5808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef AI_DO_CMD_DEBUG 5828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_ai_cancel(struct comedi_device *dev, 5840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 5858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 58652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Disable interrupts */ 5878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, 5890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral true, false); 5908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, software); 5928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, false); 5948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 5968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG 5988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_cancel\n"); 5998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 6008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 6028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 6038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 60452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Test analog input command */ 6058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6067ecac4c38a813021155c4207592693ad1949b9b7Mark#define pci9111_check_trigger_src(src, flags) do { \ 6077ecac4c38a813021155c4207592693ad1949b9b7Mark tmp = src; \ 6087ecac4c38a813021155c4207592693ad1949b9b7Mark src &= flags; \ 6097ecac4c38a813021155c4207592693ad1949b9b7Mark if (!src || tmp != src) \ 6107ecac4c38a813021155c4207592693ad1949b9b7Mark error++; \ 6117ecac4c38a813021155c4207592693ad1949b9b7Mark } while (false); 6128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int 614da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonpci9111_ai_do_cmd_test(struct comedi_device *dev, 6150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_cmd *cmd) 6168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 6178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int tmp; 6188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int error = 0; 6198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int range, reference; 6208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int i; 6210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct pci9111_board *board = (struct pci9111_board *)dev->board_ptr; 6228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 62352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 1 : check if trigger are trivialy valid */ 6248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->start_src, TRIG_NOW); 6268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->scan_begin_src, 6270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT); 6288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->convert_src, TRIG_TIMER | TRIG_EXT); 6298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->scan_end_src, TRIG_COUNT); 6308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->stop_src, TRIG_COUNT | TRIG_NONE); 6318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 6338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 1; 6348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6357ecac4c38a813021155c4207592693ad1949b9b7Mark /* step 2 : make sure trigger sources are unique and mutually 6367ecac4c38a813021155c4207592693ad1949b9b7Mark * compatible */ 6378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->start_src != TRIG_NOW) 6398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_begin_src != TRIG_TIMER) && 6420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_begin_src != TRIG_FOLLOW) && 6430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_begin_src != TRIG_EXT)) 6448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6462306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT)) 6478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_TIMER) && 6490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral !((cmd->scan_begin_src == TRIG_TIMER) || 6502306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom (cmd->scan_begin_src == TRIG_FOLLOW))) 6518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_EXT) && 6530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral !((cmd->scan_begin_src == TRIG_EXT) || 6542306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom (cmd->scan_begin_src == TRIG_FOLLOW))) 6558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6562306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom 6578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_end_src != TRIG_COUNT) 6598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->stop_src != TRIG_COUNT) && (cmd->stop_src != TRIG_NONE)) 6618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 6648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 2; 6658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 66652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 3 : make sure arguments are trivialy compatible */ 6678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist_len < 1) { 6698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->chanlist_len = 1; 6708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist_len > board->ai_channel_nbr) { 6748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->chanlist_len = board->ai_channel_nbr; 6758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) { 6798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->start_arg = 0; 6808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_TIMER) && 6840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->convert_arg < board->ai_acquisition_period_min_ns)) { 6858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->convert_arg = board->ai_acquisition_period_min_ns; 6868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) { 6898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->convert_arg = 0; 6908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_begin_src == TRIG_TIMER) && 6940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_begin_arg < board->ai_acquisition_period_min_ns)) { 6958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = board->ai_acquisition_period_min_ns; 6968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6987ecac4c38a813021155c4207592693ad1949b9b7Mark if ((cmd->scan_begin_src == TRIG_FOLLOW) 6997ecac4c38a813021155c4207592693ad1949b9b7Mark && (cmd->scan_begin_arg != 0)) { 7008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = 0; 7018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_begin_src == TRIG_EXT) && (cmd->scan_begin_arg != 0)) { 7048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = 0; 7058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_end_src == TRIG_COUNT) && 7090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_end_arg != cmd->chanlist_len)) { 7108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_end_arg = cmd->chanlist_len; 7118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->stop_src == TRIG_COUNT) && (cmd->stop_arg < 1)) { 7158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->stop_arg = 1; 7168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->stop_src == TRIG_NONE) && (cmd->stop_arg != 0)) { 7198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->stop_arg = 0; 7208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 7248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 3; 7258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 72652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 4 : fix up any arguments */ 7278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->convert_src == TRIG_TIMER) { 7298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud tmp = cmd->convert_arg; 7308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, 7310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_1), 7320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_2), 7330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd->convert_arg), 7340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 7358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (tmp != cmd->convert_arg) 7368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 73852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* There's only one timer on this card, so the scan_begin timer must */ 73952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* be a multiple of chanlist_len*convert_arg */ 7408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_begin_src == TRIG_TIMER) { 7428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_begin_min; 7448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_begin_arg; 7458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_factor; 7468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud scan_begin_min = cmd->chanlist_len * cmd->convert_arg; 7488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_begin_arg != scan_begin_min) { 7508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (scan_begin_min < cmd->scan_begin_arg) { 7518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud scan_factor = 7520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_arg / scan_begin_min; 7538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud scan_begin_arg = scan_factor * scan_begin_min; 7548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_begin_arg != scan_begin_arg) { 7558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = scan_begin_arg; 7568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 7598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = scan_begin_min; 7608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 7668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 4; 7678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 76852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 5 : check channel list */ 7698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist) { 7718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud range = CR_RANGE(cmd->chanlist[0]); 7738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud reference = CR_AREF(cmd->chanlist[0]); 7748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist_len > 1) { 7768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < cmd->chanlist_len; i++) { 7778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (CR_CHAN(cmd->chanlist[i]) != i) { 7788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must be consecutive " 7800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "channels,counting upwards from 0\n"); 7818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (CR_RANGE(cmd->chanlist[i]) != range) { 7848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must all have the same gain\n"); 7868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (CR_AREF(cmd->chanlist[i]) != reference) { 7898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must all have the same reference\n"); 7918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 7958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((CR_CHAN(cmd->chanlist[0]) > 7960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (board->ai_channel_nbr - 1)) 7970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || (CR_CHAN(cmd->chanlist[0]) < 0)) { 7988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "channel number is out of limits\n"); 8008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 8018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 8068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 5; 8078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 8098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 8118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 81252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Analog input command */ 8138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_ai_do_cmd(struct comedi_device *dev, 8150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice) 8168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 817ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *async_cmd = &subdevice->async->cmd; 8188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!dev->irq) { 8208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 8210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "no irq assigned for PCI9111, cannot do hardware conversion"); 8228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -1; 8238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 82452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set channel scan limit */ 82552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* PCI9111 allows only scanning from channel 0 to channel n */ 82652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: handle the case of an external multiplexer */ 8278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (async_cmd->chanlist_len > 1) { 8298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_channel_set((async_cmd->chanlist_len) - 1); 8308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, true); 8318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 8328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_channel_set(CR_CHAN(async_cmd->chanlist[0])); 8338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, false); 8348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 83652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set gain */ 83752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* This is the same gain on every channel */ 8388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_range_set(CR_RANGE(async_cmd->chanlist[0])); 8408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud /* Set counter */ 8428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud switch (async_cmd->stop_src) { 8448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_COUNT: 8458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter = 8460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral async_cmd->stop_arg * async_cmd->chanlist_len; 8478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_is_none = 0; 8488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 8498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_NONE: 8518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter = 0; 8528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_is_none = 1; 8538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 8548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud default: 8568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, "Invalid stop trigger"); 8578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -1; 8588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 86052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set timer pacer */ 8618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->scan_delay = 0; 8638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud switch (async_cmd->convert_src) { 8648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_TIMER: 8658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, 8660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_1), 8670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_2), 8680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(async_cmd->convert_arg), 8690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral async_cmd-> 8700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral flags & TRIG_ROUND_MASK); 8718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG 8728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": divisors = %d, %d\n", 8730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->timer_divisor_1, 8740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->timer_divisor_2); 8758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 8768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, software); 8788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_timer_set(dev); 8798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 8808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_source_set(dev, irq_on_fifo_half_full, 8810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral irq_on_timer_tick); 8828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, timer_pacer); 8838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, 8840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral false, true, true); 8858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8866c2fd308045ba902fbe9f4408daa7b949fa8f5a1Ian Abbott if (async_cmd->scan_begin_src == TRIG_TIMER) { 8876c2fd308045ba902fbe9f4408daa7b949fa8f5a1Ian Abbott dev_private->scan_delay = 8886c2fd308045ba902fbe9f4408daa7b949fa8f5a1Ian Abbott (async_cmd->scan_begin_arg / 8896c2fd308045ba902fbe9f4408daa7b949fa8f5a1Ian Abbott (async_cmd->convert_arg * 8906c2fd308045ba902fbe9f4408daa7b949fa8f5a1Ian Abbott async_cmd->chanlist_len)) - 1; 8916c2fd308045ba902fbe9f4408daa7b949fa8f5a1Ian Abbott } 8928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 8948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_EXT: 8968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, external); 8988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 8998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_source_set(dev, irq_on_fifo_half_full, 9000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral irq_on_timer_tick); 9018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, 9020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral false, true, true); 9038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 9058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud default: 9078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, "Invalid convert trigger"); 9088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -1; 9098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter *= (1 + dev_private->scan_delay); 9128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chanlist_len = async_cmd->chanlist_len; 9138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_counter = 0; 9148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_num_samples = 9150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len * (1 + dev_private->scan_delay); 9168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG 9188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": start interruptions!\n"); 9198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": trigger source = %2x\n", 9200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_trigger_and_autoscan_get()); 9218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": irq source = %2x\n", 9220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_interrupt_and_fifo_get()); 9238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_do_cmd\n"); 9248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": stop counter = %d\n", 9250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->stop_counter); 9268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": scan delay = %d\n", 9270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->scan_delay); 9288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": chanlist_len = %d\n", 9290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len); 9308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": chunk num samples = %d\n", 9310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_num_samples); 9328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 9338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 9358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 9368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void pci9111_ai_munge(struct comedi_device *dev, 9380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, void *data, 9390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int num_bytes, 9400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int start_chan_index) 9418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 942790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int i, num_samples = num_bytes / sizeof(short); 943790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short *array = data; 9448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int resolution = 9450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ((struct pci9111_board *)dev->board_ptr)->ai_resolution; 9468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < num_samples; i++) { 9488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (resolution == PCI9111_HR_AI_RESOLUTION) 9498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud array[i] = 9500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (array[i] & PCI9111_HR_AI_RESOLUTION_MASK) ^ 9510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_HR_AI_RESOLUTION_2_CMP_BIT; 9528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud else 9538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud array[i] = 9540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ((array[i] >> 4) & PCI9111_AI_RESOLUTION_MASK) ^ 9550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_AI_RESOLUTION_2_CMP_BIT; 9568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 9588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 95952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 96052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* INTERRUPT SECTION */ 96152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 9628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef INTERRUPT_DEBUG 9648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 96570265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t pci9111_interrupt(int irq, void *p_device) 9668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 96771b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton struct comedi_device *dev = p_device; 96834c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *subdevice = dev->read_subdev; 969d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async; 9708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned long irq_flags; 9718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned char intcsr; 9728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!dev->attached) { 97452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Ignore interrupt before device fully attached. */ 97552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Might not even have allocated subdevices yet! */ 9768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_NONE; 9778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud async = subdevice->async; 9808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9815f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, irq_flags); 9828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 98352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Check if we are source of interrupt */ 9848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud intcsr = inb(dev_private->lcr_io_base + 9850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PLX9050_REGISTER_INTERRUPT_CONTROL); 9868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!(((intcsr & PLX9050_PCI_INTERRUPT_ENABLE) != 0) 9870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral && (((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) 9880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral == (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) 9890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || ((intcsr & (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS)) 9900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral == (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS))))) { 99152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Not the source of the interrupt. */ 99252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* (N.B. not using PLX9050_SOFTWARE_INTERRUPT) */ 9935f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 9948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_NONE; 9958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) == 9980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) { 99952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Interrupt comes from fifo_half-full signal */ 10008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci9111_is_fifo_full()) { 10020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral spin_unlock_irqrestore(&dev->spinlock, irq_flags); 10038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow"); 10048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_clear(); 10058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_cancel(dev, subdevice); 10068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 10078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_event(dev, subdevice); 10088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_HANDLED; 10108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci9111_is_fifo_half_full()) { 10138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int num_samples; 10148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int bytes_written = 0; 10158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef INTERRUPT_DEBUG 10178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": fifo is half full\n"); 10188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 10198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud num_samples = 10210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_FIFO_HALF_SIZE > 10220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->stop_counter 10230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral && !dev_private-> 10240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral stop_is_none ? dev_private->stop_counter : 10250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_FIFO_HALF_SIZE; 10268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud insw(PCI9111_IO_BASE + PCI9111_REGISTER_AD_FIFO_VALUE, 10270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->ai_bounce_buffer, num_samples); 10288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->scan_delay < 1) { 10308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bytes_written = 10310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cfc_write_array_to_buffer(subdevice, 10320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private-> 10330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ai_bounce_buffer, 10340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples * 10350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral sizeof(short)); 10368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 10378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int position = 0; 10388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int to_read; 10398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud while (position < num_samples) { 10418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->chunk_counter < 10420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len) { 10438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len - 10450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_counter; 10468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (to_read > 10480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - position) 10498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - 10510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral position; 10528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bytes_written += 10540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cfc_write_array_to_buffer 10550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (subdevice, 10560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->ai_bounce_buffer 10570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral + position, 10580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral to_read * sizeof(short)); 10598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 10608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_num_samples 10620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral - 10630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_counter; 10648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (to_read > 10650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - position) 10668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - 10680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral position; 10698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bytes_written += 10710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral sizeof(short) * to_read; 10728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud position += to_read; 10758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_counter += to_read; 10768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->chunk_counter >= 10780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_num_samples) 10798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_counter = 0; 10808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter -= 10840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bytes_written / sizeof(short); 10858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((dev_private->stop_counter == 0) && (!dev_private->stop_is_none)) { 10898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud async->events |= COMEDI_CB_EOA; 10908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_cancel(dev, subdevice); 10918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud /* Very important, otherwise another interrupt request will be inserted 10948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud * and will cause driver hangs on processing interrupt event. */ 10958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_clear(); 10978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10985f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 10998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_event(dev, subdevice); 11018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_HANDLED; 11038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 110552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 110652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* INSTANT ANALOG INPUT OUTPUT SECTION */ 110752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 11088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 110952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* analog instant input */ 11108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef AI_INSN_DEBUG 11128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1113da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_ai_insn_read(struct comedi_device *dev, 11140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice, 11150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 11168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 11178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int resolution = 11180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ((struct pci9111_board *)dev->board_ptr)->ai_resolution; 11198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int timeout, i; 11218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_INSN_DEBUG 11238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_insn set c/r/n = %2x/%2x/%2x\n", 11240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_CHAN((&insn->chanspec)[0]), 11250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_RANGE((&insn->chanspec)[0]), insn->n); 11268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 11278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0])); 11298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11302306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0])) 11318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_range_set(CR_RANGE((&insn->chanspec)[0])); 11328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 11348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < insn->n; i++) { 11368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_software_trigger(); 11378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud timeout = PCI9111_AI_INSTANT_READ_TIMEOUT; 11398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud while (timeout--) { 11418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!pci9111_is_fifo_empty()) 11428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud goto conversion_done; 11438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 11448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, "A/D read timeout"); 11468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = 0; 11478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 11488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -ETIME; 11498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralconversion_done: 11518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11522306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (resolution == PCI9111_HR_AI_RESOLUTION) 11538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = pci9111_hr_ai_get_data(); 11542306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom else 11558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = pci9111_ai_get_data(); 11568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 11578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_INSN_DEBUG 11598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_insn get c/r/t = %2x/%2x/%2x\n", 11600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_ai_channel_get(), 11610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_ai_range_get(), pci9111_trigger_and_autoscan_get()); 11628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 11638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return i; 11658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 116752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Analog instant output */ 11688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int 1170da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonpci9111_ao_insn_write(struct comedi_device *dev, 11710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_insn *insn, 11720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 11738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 11748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int i; 11758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < insn->n; i++) { 11778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ao_set_data(data[i]); 11788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->ao_readback = data[i]; 11798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 11808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return i; 11828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 118452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Analog output readback */ 11858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1186da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_ao_insn_read(struct comedi_device *dev, 11870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 11880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 11898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 11908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int i; 11918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11922306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom for (i = 0; i < insn->n; i++) 11938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = dev_private->ao_readback & PCI9111_AO_RESOLUTION_MASK; 11948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return i; 11968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 119852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 119952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* DIGITAL INPUT OUTPUT SECTION */ 120052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 12018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 120252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Digital inputs */ 12038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1204da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_di_insn_bits(struct comedi_device *dev, 12050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice, 12060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 12078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 1208790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int bits; 12098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits = pci9111_di_get_bits(); 12118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[1] = bits; 12128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 2; 12148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 12158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 121652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Digital outputs */ 12178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1218da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_do_insn_bits(struct comedi_device *dev, 12190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice, 12200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 12218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 1222790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int bits; 12238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 122452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Only set bits that have been masked */ 122552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* data[0] = mask */ 122652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* data[1] = bit state */ 12278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[0] &= PCI9111_DO_MASK; 12298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits = subdevice->state; 12318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits &= ~data[0]; 12328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits |= data[0] & data[1]; 12338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->state = bits; 12348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_do_set_bits(bits); 12368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[1] = bits; 12388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 2; 12408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 12418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 124252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 124352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* INITIALISATION SECTION */ 124452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 12458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 124652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Reset device */ 12478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1248da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_reset(struct comedi_device *dev) 12498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 125052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set trigger source to software */ 12518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, 12530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral true, false); 12548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, software); 12568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_pretrigger_set(dev, false); 12578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, false); 12588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 125952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Reset 8254 chip */ 12608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->timer_divisor_1 = 0; 12628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->timer_divisor_2 = 0; 12638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_timer_set(dev); 12658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 12678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 12688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 126952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Attach */ 127052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* - Register PCI device */ 127152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* - Declare device driver capability */ 12728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_attach(struct comedi_device *dev, 12740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it) 12758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 127634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *subdevice; 12778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned long io_base, io_range, lcr_io_base, lcr_io_range; 127820fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy struct pci_dev *pci_device = NULL; 12798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int error, i; 1280940579fbae1a3a8967fe619562c8e78080dd873dBill Pemberton const struct pci9111_board *board; 12818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12822306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (alloc_private(dev, sizeof(struct pci9111_private_data)) < 0) 12838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -ENOMEM; 128452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Probe the device to determine what device in the series it is. */ 12858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: " PCI9111_DRIVER_NAME " driver\n", dev->minor); 12878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 128820fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy for_each_pci_dev(pci_device) { 12898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci_device->vendor == PCI_VENDOR_ID_ADLINK) { 12908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < pci9111_board_nbr; i++) { 12918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci9111_boards[i].device_id == 12920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_device->device) { 12937ecac4c38a813021155c4207592693ad1949b9b7Mark /* was a particular bus/slot 12947ecac4c38a813021155c4207592693ad1949b9b7Mark * requested? */ 12958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((it->options[0] != 0) 12960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || (it->options[1] != 0)) { 12977ecac4c38a813021155c4207592693ad1949b9b7Mark /* are we on the wrong 12987ecac4c38a813021155c4207592693ad1949b9b7Mark * bus/slot? */ 12998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci_device->bus->number != 13000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral it->options[0] 13010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || 13020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pci_device->devfn) 13030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral != it->options[1]) { 13048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud continue; 13058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->board_ptr = pci9111_boards + i; 13090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral board = 13100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (struct pci9111_board *) 13110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->board_ptr; 13128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->pci_device = pci_device; 13138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud goto found; 13148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", 13200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, it->options[0], it->options[1]); 13218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -EIO; 13228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralfound: 13248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n", 13260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, 13270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_boards[i].name, 13280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_device->bus->number, 13290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pci_device->devfn), 13300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_FUNC(pci_device->devfn), pci_device->irq); 13318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 133252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: Warn about non-tested boards. */ 13338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13347ecac4c38a813021155c4207592693ad1949b9b7Mark /* Read local configuration register base address 13357ecac4c38a813021155c4207592693ad1949b9b7Mark * [PCI_BASE_ADDRESS #1]. */ 13368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud lcr_io_base = pci_resource_start(pci_device, 1); 13388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud lcr_io_range = pci_resource_len(pci_device, 1); 13398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 13410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n", 13420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, lcr_io_base, lcr_io_range); 13438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 134452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Enable PCI device and request regions */ 13458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (comedi_pci_enable(pci_device, PCI9111_DRIVER_NAME) < 0) { 13460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 13470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ("comedi%d: Failed to enable PCI device and request regions\n", 13480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor); 13498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -EIO; 13508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 135152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Read PCI6308 register base address [PCI_BASE_ADDRESS #2]. */ 13528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud io_base = pci_resource_start(pci_device, 2); 13548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud io_range = pci_resource_len(pci_device, 2); 13558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: 6503 registers at address 0x%4lx [0x%4lx]\n", 13570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, io_base, io_range); 13588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->iobase = io_base; 13608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->board_name = board->name; 13618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->io_range = io_range; 13628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->is_valid = 0; 13638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->lcr_io_base = lcr_io_base; 13648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->lcr_io_range = lcr_io_range; 13658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_reset(dev); 13678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 136852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Irq setup */ 13698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->irq = 0; 13718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci_device->irq > 0) { 13725f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman if (request_irq(pci_device->irq, pci9111_interrupt, 13738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud IRQF_SHARED, PCI9111_DRIVER_NAME, dev) != 0) { 13748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk("comedi%d: unable to allocate irq %u\n", 13750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, pci_device->irq); 13768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -EINVAL; 13778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->irq = pci_device->irq; 13808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 138152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: Add external multiplexer setup (according to option[2]). */ 13828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1383c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton error = alloc_subdevices(dev, 4); 1384c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (error < 0) 13858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return error; 13868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 0; 13888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->read_subdev = subdevice; 13898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_AI; 13918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; 13928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 139352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: Add external multiplexer data */ 139452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* if (devpriv->usemux) { subdevice->n_chan = devpriv->usemux; } */ 139552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* else { subdevice->n_chan = this_board->n_aichan; } */ 13968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = board->ai_channel_nbr; 13988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = board->ai_resolution_mask; 13998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->len_chanlist = board->ai_channel_nbr; 14008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = board->ai_range_list; 14018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->cancel = pci9111_ai_cancel; 14028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_read = pci9111_ai_insn_read; 14038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->do_cmdtest = pci9111_ai_do_cmd_test; 14048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->do_cmd = pci9111_ai_do_cmd; 14058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->munge = pci9111_ai_munge; 14068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 1; 14088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_AO; 14098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_WRITABLE | SDF_COMMON; 14108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = board->ao_channel_nbr; 14118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = board->ao_resolution_mask; 14128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->len_chanlist = board->ao_channel_nbr; 14138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = board->ao_range_list; 14148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_write = pci9111_ao_insn_write; 14158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_read = pci9111_ao_insn_read; 14168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 2; 14188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_DI; 14198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_READABLE; 14208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = PCI9111_DI_CHANNEL_NBR; 14218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = 1; 14228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = &range_digital; 14238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_bits = pci9111_di_insn_bits; 14248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 3; 14268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_DO; 14278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_READABLE | SDF_WRITABLE; 14288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = PCI9111_DO_CHANNEL_NBR; 14298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = 1; 14308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = &range_digital; 14318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_bits = pci9111_do_insn_bits; 14328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->is_valid = 1; 14348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 14368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 14378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 143852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Detach */ 14398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1440da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_detach(struct comedi_device *dev) 14418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 144252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Reset device */ 14438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1444525d1b1395858606103d4663a570cc8725ff2cedGreg Kroah-Hartman if (dev->private != NULL) { 14458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->is_valid) 14468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_reset(dev); 14478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 144952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Release previously allocated irq */ 14508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14512306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (dev->irq != 0) 14525f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 14538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1454525d1b1395858606103d4663a570cc8725ff2cedGreg Kroah-Hartman if (dev_private != NULL && dev_private->pci_device != NULL) { 14552306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (dev->iobase) 14568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_pci_disable(dev_private->pci_device); 14578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci_dev_put(dev_private->pci_device); 14588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 14598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 14618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 146290f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 146390f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 146490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 146590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 1466