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) \ 2698be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson do { \ 2708be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson outb(data & 0xFF, \ 2718be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \ 272842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb((data >> 8) & 0xFF, \ 2738be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \ 2748be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson } while (0) 2758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_1_set(data) \ 2778be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson do { \ 2788be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson outb(data & 0xFF, \ 2798be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \ 280842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb((data >> 8) & 0xFF, \ 2818be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \ 2828be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson } while (0) 2838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_8254_counter_2_set(data) \ 2858be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson do { \ 2868be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson outb(data & 0xFF, \ 2878be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \ 288842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson outb((data >> 8) & 0xFF, \ 2898be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \ 2908be11ffcf59e9bcb5f0a2a2b2e7b43d56c797b98Maurice Dawson } while (0) 2918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 29252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Function prototypes */ 2938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 2940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_attach(struct comedi_device *dev, 2950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 296da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_detach(struct comedi_device *dev); 2970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void pci9111_ai_munge(struct comedi_device *dev, 2980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, void *data, 2990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int num_bytes, 3000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int start_chan_index); 3018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3029ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange pci9111_hr_ai_range = { 3038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5, 3048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud { 3050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(10), 3060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(5), 3070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(2.5), 3080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(1.25), 3090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(0.625) 3100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 3118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = { 3148c0690eaf7a666183fb9c49d275d9f986acd4239Peter Huewe { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID) }, 3158c0690eaf7a666183fb9c49d275d9f986acd4239Peter Huewe /* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */ 3167ecac4c38a813021155c4207592693ad1949b9b7Mark { 0 } 3178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel PacaudMODULE_DEVICE_TABLE(pci, pci9111_pci_table); 3208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 32152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* */ 32252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Board specification structure */ 32352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* */ 3248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 325940579fbae1a3a8967fe619562c8e78080dd873dBill Pembertonstruct pci9111_board { 32652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton const char *name; /* driver name */ 3278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int device_id; 32852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ai_channel_nbr; /* num of A/D chans */ 32952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ao_channel_nbr; /* num of D/A chans */ 33052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ai_resolution; /* resolution of A/D */ 3318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int ai_resolution_mask; 33252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ao_resolution; /* resolution of D/A */ 3338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int ao_resolution_mask; 33452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton const struct comedi_lrange *ai_range_list; /* rangelist for A/D */ 33552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton const struct comedi_lrange *ao_range_list; /* rangelist for D/A */ 3368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int ai_acquisition_period_min_ns; 337940579fbae1a3a8967fe619562c8e78080dd873dBill Pemberton}; 3388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 339940579fbae1a3a8967fe619562c8e78080dd873dBill Pembertonstatic const struct pci9111_board pci9111_boards[] = { 3408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud { 3410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci9111_hr", 3420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = PCI9111_HR_DEVICE_ID, 3430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_channel_nbr = PCI9111_AI_CHANNEL_NBR, 3440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_channel_nbr = PCI9111_AO_CHANNEL_NBR, 3450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_resolution = PCI9111_HR_AI_RESOLUTION, 3460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_resolution_mask = PCI9111_HR_AI_RESOLUTION_MASK, 3470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_resolution = PCI9111_AO_RESOLUTION, 3480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_resolution_mask = PCI9111_AO_RESOLUTION_MASK, 3490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_range_list = &pci9111_hr_ai_range, 3500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_range_list = &range_bipolar10, 3510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ai_acquisition_period_min_ns = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS} 3528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 3548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define pci9111_board_nbr \ 355842ec6ba3bdf6de35359726b0428095fdd0f9b45Maurice Dawson (sizeof(pci9111_boards)/sizeof(struct pci9111_board)) 3568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 357139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver pci9111_driver = { 35868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = PCI9111_DRIVER_NAME, 35968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 36068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = pci9111_attach, 36168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = pci9111_detach, 3628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud}; 3638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 364727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __devinit pci9111_driver_pci_probe(struct pci_dev *dev, 365727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas const struct pci_device_id *ent) 366727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 367727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return comedi_pci_auto_config(dev, pci9111_driver.driver_name); 368727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 369727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 370727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __devexit pci9111_driver_pci_remove(struct pci_dev *dev) 371727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 372727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_pci_auto_unconfig(dev); 373727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 374727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 375727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic struct pci_driver pci9111_driver_pci_driver = { 376727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .id_table = pci9111_pci_table, 377727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .probe = &pci9111_driver_pci_probe, 378727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .remove = __devexit_p(&pci9111_driver_pci_remove) 379727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}; 380727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 381727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __init pci9111_driver_init_module(void) 382727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 383727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas int retval; 384727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 385727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas retval = comedi_driver_register(&pci9111_driver); 386727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas if (retval < 0) 387727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return retval; 388727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 389727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas pci9111_driver_pci_driver.name = (char *)pci9111_driver.driver_name; 390727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return pci_register_driver(&pci9111_driver_pci_driver); 391727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 392727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 393727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __exit pci9111_driver_cleanup_module(void) 394727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 395727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas pci_unregister_driver(&pci9111_driver_pci_driver); 396727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_driver_unregister(&pci9111_driver); 397727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 398727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 399727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_init(pci9111_driver_init_module); 400727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_exit(pci9111_driver_cleanup_module); 4018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 40252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Private data structure */ 4038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 404c350fa1944f4ec1fe392ce0f3fc879f3899bb15dBill Pembertonstruct pci9111_private_data { 4058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud struct pci_dev *pci_device; 40652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton unsigned long io_range; /* PCI6503 io range */ 4078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4087ecac4c38a813021155c4207592693ad1949b9b7Mark unsigned long lcr_io_base; /* Local configuration register base 4097ecac4c38a813021155c4207592693ad1949b9b7Mark * address */ 4108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned long lcr_io_range; 4118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int stop_counter; 4138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int stop_is_none; 4148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_delay; 4168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int chanlist_len; 4178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int chunk_counter; 4188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int chunk_num_samples; 4198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 42052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int ao_readback; /* Last written analog output data */ 4218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4227ecac4c38a813021155c4207592693ad1949b9b7Mark unsigned int timer_divisor_1; /* Divisor values for the 8254 timer 4237ecac4c38a813021155c4207592693ad1949b9b7Mark * pacer */ 424525d1b1395858606103d4663a570cc8725ff2cedGreg Kroah-Hartman unsigned int timer_divisor_2; 4258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 42652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton int is_valid; /* Is device valid */ 4278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 428790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE]; 429c350fa1944f4ec1fe392ce0f3fc879f3899bb15dBill Pemberton}; 4308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4317ecac4c38a813021155c4207592693ad1949b9b7Mark#define dev_private ((struct pci9111_private_data *)dev->private) 4328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 43352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 43452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* PLX9050 SECTION */ 43552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 4368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_REGISTER_INTERRUPT_CONTROL 0x4c 4388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_ENABLE (1 << 0) 4408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_ACTIVE_HIGH (1 << 1) 4418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI1_STATUS (1 << 2) 4428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_ENABLE (1 << 3) 4438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_ACTIVE_HIGH (1 << 4) 4448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_LINTI2_STATUS (1 << 5) 4458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_PCI_INTERRUPT_ENABLE (1 << 6) 4468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#define PLX9050_SOFTWARE_INTERRUPT (1 << 7) 4478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic void plx9050_interrupt_control(unsigned long io_base, 4490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi1_enable, 4500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi1_active_high, 4510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi2_enable, 4520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool LINTi2_active_high, 4530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bool interrupt_enable) 4548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 4558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags = 0; 4568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi1_enable) 4588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI1_ENABLE; 4598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi1_active_high) 4608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI1_ACTIVE_HIGH; 4618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi2_enable) 4628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI2_ENABLE; 4638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (LINTi2_active_high) 4648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_LINTI2_ACTIVE_HIGH; 4658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (interrupt_enable) 4678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PLX9050_PCI_INTERRUPT_ENABLE; 4688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud outb(flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL); 4708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 4718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 47252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 47352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* MISCELLANEOUS SECTION */ 47452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 4758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 47652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* 8254 timer */ 4778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 478da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_timer_set(struct comedi_device *dev) 4798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 4808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_control_set(PCI9111_8254_COUNTER_0 | 4810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_READ_LOAD_LSB_MSB | 4820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_MODE_0 | 4830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_BINARY_COUNTER); 4848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_control_set(PCI9111_8254_COUNTER_1 | 4860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_READ_LOAD_LSB_MSB | 4870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_MODE_2 | 4880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_BINARY_COUNTER); 4898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_control_set(PCI9111_8254_COUNTER_2 | 4910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_READ_LOAD_LSB_MSB | 4920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_MODE_2 | 4930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_8254_BINARY_COUNTER); 4948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4955f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 4968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 4978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_counter_2_set(dev_private->timer_divisor_2); 4988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_8254_counter_1_set(dev_private->timer_divisor_1); 4998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 501655f78f6aaa059ad262bc55e1c3575724c14867bBill Pembertonenum pci9111_trigger_sources { 5028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud software, 5038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud timer_pacer, 5048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud external 505655f78f6aaa059ad262bc55e1c3575724c14867bBill Pemberton}; 5068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 507da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_trigger_source_set(struct comedi_device *dev, 5080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral enum pci9111_trigger_sources source) 5098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 5118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_trigger_and_autoscan_get() & 0x09; 5138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud switch (source) { 5158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case software: 5168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_SOFTWARE_TRIGGER; 5178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 5188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case timer_pacer: 5208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_TIMER_PACER; 5218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 5228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case external: 5248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_EITS_EXTERNAL; 5258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 5268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 5278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_and_autoscan_set(flags); 5298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 531da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_pretrigger_set(struct comedi_device *dev, bool pretrigger) 5328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 5348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_trigger_and_autoscan_get() & 0x07; 5368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pretrigger) 5388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_PTRG_ON; 5398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_and_autoscan_set(flags); 5418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 543da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_autoscan_set(struct comedi_device *dev, bool autoscan) 5448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 5468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_trigger_and_autoscan_get() & 0x0e; 5488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (autoscan) 5508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_ASCAN_ON; 5518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_and_autoscan_set(flags); 5538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5553ba97b3c6258cb67450e0873584489f97d0debc5Bill Pembertonenum pci9111_ISC0_sources { 5568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_eoc, 5578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_fifo_half_full 5583ba97b3c6258cb67450e0873584489f97d0debc5Bill Pemberton}; 5598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 56052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pembertonenum pci9111_ISC1_sources { 5618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_timer_tick, 5628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud irq_on_external_trigger 56352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton}; 5648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 565da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci9111_interrupt_source_set(struct comedi_device *dev, 5660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral enum pci9111_ISC0_sources irq_0_source, 5670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral enum pci9111_ISC1_sources irq_1_source) 5688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 5698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int flags; 5708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags = pci9111_interrupt_and_fifo_get() & 0x04; 5728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (irq_0_source == irq_on_fifo_half_full) 5748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL; 5758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (irq_1_source == irq_on_external_trigger) 5778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud flags |= PCI9111_ISC1_SET_IRQ_ON_EXT_TRG; 5788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_and_fifo_set(flags); 5808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 5818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 58252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 58352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* HARDWARE TRIGGERED ANALOG INPUT SECTION */ 58452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 5858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 58652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Cancel analog input autoscan */ 5878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef AI_DO_CMD_DEBUG 5898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_ai_cancel(struct comedi_device *dev, 5910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 5928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 59352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Disable interrupts */ 5948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, 5960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral true, false); 5978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 5988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, software); 5998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, false); 6018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 6038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG 6058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_cancel\n"); 6068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 6078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 6098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 6108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 61152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Test analog input command */ 6128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6137ecac4c38a813021155c4207592693ad1949b9b7Mark#define pci9111_check_trigger_src(src, flags) do { \ 6147ecac4c38a813021155c4207592693ad1949b9b7Mark tmp = src; \ 6157ecac4c38a813021155c4207592693ad1949b9b7Mark src &= flags; \ 6167ecac4c38a813021155c4207592693ad1949b9b7Mark if (!src || tmp != src) \ 6177ecac4c38a813021155c4207592693ad1949b9b7Mark error++; \ 6187ecac4c38a813021155c4207592693ad1949b9b7Mark } while (false); 6198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int 621da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonpci9111_ai_do_cmd_test(struct comedi_device *dev, 6220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_cmd *cmd) 6238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 6248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int tmp; 6258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int error = 0; 6268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int range, reference; 6278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int i; 6280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct pci9111_board *board = (struct pci9111_board *)dev->board_ptr; 6298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 63052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 1 : check if trigger are trivialy valid */ 6318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->start_src, TRIG_NOW); 6338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->scan_begin_src, 6340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT); 6358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->convert_src, TRIG_TIMER | TRIG_EXT); 6368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->scan_end_src, TRIG_COUNT); 6378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_check_trigger_src(cmd->stop_src, TRIG_COUNT | TRIG_NONE); 6388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 6408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 1; 6418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6427ecac4c38a813021155c4207592693ad1949b9b7Mark /* step 2 : make sure trigger sources are unique and mutually 6437ecac4c38a813021155c4207592693ad1949b9b7Mark * compatible */ 6448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->start_src != TRIG_NOW) 6468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_begin_src != TRIG_TIMER) && 6490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_begin_src != TRIG_FOLLOW) && 6500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_begin_src != TRIG_EXT)) 6518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6532306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT)) 6548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_TIMER) && 6560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral !((cmd->scan_begin_src == TRIG_TIMER) || 6572306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom (cmd->scan_begin_src == TRIG_FOLLOW))) 6588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_EXT) && 6600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral !((cmd->scan_begin_src == TRIG_EXT) || 6612306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom (cmd->scan_begin_src == TRIG_FOLLOW))) 6628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6632306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom 6648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_end_src != TRIG_COUNT) 6668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->stop_src != TRIG_COUNT) && (cmd->stop_src != TRIG_NONE)) 6688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 6718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 2; 6728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 67352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 3 : make sure arguments are trivialy compatible */ 6748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist_len < 1) { 6768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->chanlist_len = 1; 6778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist_len > board->ai_channel_nbr) { 6818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->chanlist_len = board->ai_channel_nbr; 6828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) { 6868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->start_arg = 0; 6878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 6908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_TIMER) && 6910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->convert_arg < board->ai_acquisition_period_min_ns)) { 6928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->convert_arg = board->ai_acquisition_period_min_ns; 6938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) { 6968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->convert_arg = 0; 6978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 6988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 6998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_begin_src == TRIG_TIMER) && 7010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_begin_arg < board->ai_acquisition_period_min_ns)) { 7028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = board->ai_acquisition_period_min_ns; 7038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7057ecac4c38a813021155c4207592693ad1949b9b7Mark if ((cmd->scan_begin_src == TRIG_FOLLOW) 7067ecac4c38a813021155c4207592693ad1949b9b7Mark && (cmd->scan_begin_arg != 0)) { 7078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = 0; 7088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_begin_src == TRIG_EXT) && (cmd->scan_begin_arg != 0)) { 7118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = 0; 7128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->scan_end_src == TRIG_COUNT) && 7160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (cmd->scan_end_arg != cmd->chanlist_len)) { 7178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_end_arg = cmd->chanlist_len; 7188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->stop_src == TRIG_COUNT) && (cmd->stop_arg < 1)) { 7228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->stop_arg = 1; 7238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((cmd->stop_src == TRIG_NONE) && (cmd->stop_arg != 0)) { 7268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->stop_arg = 0; 7278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 7318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 3; 7328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 73352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 4 : fix up any arguments */ 7348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->convert_src == TRIG_TIMER) { 7368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud tmp = cmd->convert_arg; 7378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, 7380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_1), 7390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_2), 7400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(cmd->convert_arg), 7410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 7428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (tmp != cmd->convert_arg) 7438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 74552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* There's only one timer on this card, so the scan_begin timer must */ 74652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* be a multiple of chanlist_len*convert_arg */ 7478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_begin_src == TRIG_TIMER) { 7498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_begin_min; 7518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_begin_arg; 7528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int scan_factor; 7538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud scan_begin_min = cmd->chanlist_len * cmd->convert_arg; 7558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_begin_arg != scan_begin_min) { 7578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (scan_begin_min < cmd->scan_begin_arg) { 7588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud scan_factor = 7590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_arg / scan_begin_min; 7608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud scan_begin_arg = scan_factor * scan_begin_min; 7618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->scan_begin_arg != scan_begin_arg) { 7628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = scan_begin_arg; 7638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 7668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud cmd->scan_begin_arg = scan_begin_min; 7678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 7738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 4; 7748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 77552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Step 5 : check channel list */ 7768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist) { 7788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud range = CR_RANGE(cmd->chanlist[0]); 7808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud reference = CR_AREF(cmd->chanlist[0]); 7818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 7828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (cmd->chanlist_len > 1) { 7838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < cmd->chanlist_len; i++) { 7848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (CR_CHAN(cmd->chanlist[i]) != i) { 7858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must be consecutive " 7870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "channels,counting upwards from 0\n"); 7888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (CR_RANGE(cmd->chanlist[i]) != range) { 7918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must all have the same gain\n"); 7938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 7958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (CR_AREF(cmd->chanlist[i]) != reference) { 7968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 7970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "entries in chanlist must all have the same reference\n"); 7988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 7998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 8028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((CR_CHAN(cmd->chanlist[0]) > 8030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (board->ai_channel_nbr - 1)) 8040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || (CR_CHAN(cmd->chanlist[0]) < 0)) { 8058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 8060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "channel number is out of limits\n"); 8078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud error++; 8088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (error) 8138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 5; 8148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 8168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 8188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 81952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Analog input command */ 8208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_ai_do_cmd(struct comedi_device *dev, 8220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice) 8238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 824ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *async_cmd = &subdevice->async->cmd; 8258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!dev->irq) { 8278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, 8280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "no irq assigned for PCI9111, cannot do hardware conversion"); 8298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -1; 8308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 83152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set channel scan limit */ 83252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* PCI9111 allows only scanning from channel 0 to channel n */ 83352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: handle the case of an external multiplexer */ 8348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (async_cmd->chanlist_len > 1) { 8368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_channel_set((async_cmd->chanlist_len) - 1); 8378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, true); 8388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 8398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_channel_set(CR_CHAN(async_cmd->chanlist[0])); 8408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, false); 8418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 84352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set gain */ 84452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* This is the same gain on every channel */ 8458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_range_set(CR_RANGE(async_cmd->chanlist[0])); 8478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud /* Set counter */ 8498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud switch (async_cmd->stop_src) { 8518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_COUNT: 8528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter = 8530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral async_cmd->stop_arg * async_cmd->chanlist_len; 8548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_is_none = 0; 8558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 8568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_NONE: 8588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter = 0; 8598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_is_none = 1; 8608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 8618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud default: 8638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, "Invalid stop trigger"); 8648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -1; 8658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 8668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 86752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set timer pacer */ 8688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->scan_delay = 0; 8708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud switch (async_cmd->convert_src) { 8718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_TIMER: 8728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS, 8730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_1), 8740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(dev_private->timer_divisor_2), 8750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &(async_cmd->convert_arg), 8760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral async_cmd-> 8770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral flags & TRIG_ROUND_MASK); 8788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG 8798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": divisors = %d, %d\n", 8800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->timer_divisor_1, 8810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->timer_divisor_2); 8828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 8838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, software); 8858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_timer_set(dev); 8868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 8878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_source_set(dev, irq_on_fifo_half_full, 8880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral irq_on_timer_tick); 8898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, timer_pacer); 8908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, 8910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral false, true, true); 8928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 8936c2fd308045ba902fbe9f4408daa7b949fa8f5a1Ian Abbott if (async_cmd->scan_begin_src == TRIG_TIMER) { 8946c2fd308045ba902fbe9f4408daa7b949fa8f5a1Ian Abbott dev_private->scan_delay = 8956c2fd308045ba902fbe9f4408daa7b949fa8f5a1Ian Abbott (async_cmd->scan_begin_arg / 8966c2fd308045ba902fbe9f4408daa7b949fa8f5a1Ian Abbott (async_cmd->convert_arg * 8976c2fd308045ba902fbe9f4408daa7b949fa8f5a1Ian Abbott async_cmd->chanlist_len)) - 1; 8986c2fd308045ba902fbe9f4408daa7b949fa8f5a1Ian Abbott } 8998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 9018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud case TRIG_EXT: 9038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, external); 9058cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 9068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_source_set(dev, irq_on_fifo_half_full, 9070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral irq_on_timer_tick); 9088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, 9090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral false, true, true); 9108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud break; 9128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud default: 9148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, "Invalid convert trigger"); 9158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -1; 9168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter *= (1 + dev_private->scan_delay); 9198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chanlist_len = async_cmd->chanlist_len; 9208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_counter = 0; 9218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_num_samples = 9220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len * (1 + dev_private->scan_delay); 9238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_DO_CMD_DEBUG 9258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": start interruptions!\n"); 9268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": trigger source = %2x\n", 9270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_trigger_and_autoscan_get()); 9288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": irq source = %2x\n", 9290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_interrupt_and_fifo_get()); 9308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_do_cmd\n"); 9318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": stop counter = %d\n", 9320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->stop_counter); 9338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": scan delay = %d\n", 9340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->scan_delay); 9358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": chanlist_len = %d\n", 9360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len); 9378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": chunk num samples = %d\n", 9380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_num_samples); 9398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 9408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 9428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 9438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void pci9111_ai_munge(struct comedi_device *dev, 9450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, void *data, 9460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int num_bytes, 9470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int start_chan_index) 9488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 949790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int i, num_samples = num_bytes / sizeof(short); 950790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short *array = data; 9518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int resolution = 9520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ((struct pci9111_board *)dev->board_ptr)->ai_resolution; 9538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < num_samples; i++) { 9558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (resolution == PCI9111_HR_AI_RESOLUTION) 9568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud array[i] = 9570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (array[i] & PCI9111_HR_AI_RESOLUTION_MASK) ^ 9580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_HR_AI_RESOLUTION_2_CMP_BIT; 9598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud else 9608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud array[i] = 9610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ((array[i] >> 4) & PCI9111_AI_RESOLUTION_MASK) ^ 9620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_AI_RESOLUTION_2_CMP_BIT; 9638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 9658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 96652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 96752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* INTERRUPT SECTION */ 96852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 9698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef INTERRUPT_DEBUG 9718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 97270265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t pci9111_interrupt(int irq, void *p_device) 9738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 97471b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton struct comedi_device *dev = p_device; 97534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *subdevice = dev->read_subdev; 976d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton struct comedi_async *async; 9778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned long irq_flags; 9788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned char intcsr; 9798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!dev->attached) { 98152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Ignore interrupt before device fully attached. */ 98252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Might not even have allocated subdevices yet! */ 9838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_NONE; 9848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 9858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud async = subdevice->async; 9878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 9885f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, irq_flags); 9898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 99052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Check if we are source of interrupt */ 9918cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud intcsr = inb(dev_private->lcr_io_base + 9920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PLX9050_REGISTER_INTERRUPT_CONTROL); 9938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!(((intcsr & PLX9050_PCI_INTERRUPT_ENABLE) != 0) 9940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral && (((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) 9950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral == (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) 9960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || ((intcsr & (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS)) 9970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral == (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS))))) { 99852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Not the source of the interrupt. */ 99952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* (N.B. not using PLX9050_SOFTWARE_INTERRUPT) */ 10005f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 10018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_NONE; 10028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) == 10050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) { 100652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Interrupt comes from fifo_half-full signal */ 10078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci9111_is_fifo_full()) { 10090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral spin_unlock_irqrestore(&dev->spinlock, irq_flags); 10108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow"); 10118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_clear(); 10128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_cancel(dev, subdevice); 10138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 10148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_event(dev, subdevice); 10158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_HANDLED; 10178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci9111_is_fifo_half_full()) { 10208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int num_samples; 10218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned int bytes_written = 0; 10228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef INTERRUPT_DEBUG 10248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": fifo is half full\n"); 10258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 10268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud num_samples = 10280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_FIFO_HALF_SIZE > 10290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->stop_counter 10300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral && !dev_private-> 10310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral stop_is_none ? dev_private->stop_counter : 10320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI9111_FIFO_HALF_SIZE; 10338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud insw(PCI9111_IO_BASE + PCI9111_REGISTER_AD_FIFO_VALUE, 10340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->ai_bounce_buffer, num_samples); 10358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->scan_delay < 1) { 10378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bytes_written = 10380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cfc_write_array_to_buffer(subdevice, 10390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private-> 10400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ai_bounce_buffer, 10410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples * 10420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral sizeof(short)); 10438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 10448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int position = 0; 10458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int to_read; 10468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud while (position < num_samples) { 10488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->chunk_counter < 10490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len) { 10508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chanlist_len - 10520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_counter; 10538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (to_read > 10550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - position) 10568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - 10580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral position; 10598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bytes_written += 10610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cfc_write_array_to_buffer 10620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (subdevice, 10630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->ai_bounce_buffer 10640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral + position, 10650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral to_read * sizeof(short)); 10668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } else { 10678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_num_samples 10690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral - 10700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_counter; 10718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (to_read > 10720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - position) 10738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud to_read = 10740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral num_samples - 10750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral position; 10768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10778cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bytes_written += 10780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral sizeof(short) * to_read; 10798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud position += to_read; 10828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_counter += to_read; 10838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->chunk_counter >= 10850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev_private->chunk_num_samples) 10868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->chunk_counter = 0; 10878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->stop_counter -= 10910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral bytes_written / sizeof(short); 10928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10938cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10948cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 10958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((dev_private->stop_counter == 0) && (!dev_private->stop_is_none)) { 10968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud async->events |= COMEDI_CB_EOA; 10978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_cancel(dev, subdevice); 10988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 10998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud /* Very important, otherwise another interrupt request will be inserted 11018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud * and will cause driver hangs on processing interrupt event. */ 11028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_interrupt_clear(); 11048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11055f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, irq_flags); 11068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_event(dev, subdevice); 11088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return IRQ_HANDLED; 11108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 111252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 111352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* INSTANT ANALOG INPUT OUTPUT SECTION */ 111452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 11158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 111652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* analog instant input */ 11178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#undef AI_INSN_DEBUG 11198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1120da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_ai_insn_read(struct comedi_device *dev, 11210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice, 11220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 11238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 11248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int resolution = 11250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ((struct pci9111_board *)dev->board_ptr)->ai_resolution; 11268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int timeout, i; 11288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_INSN_DEBUG 11308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_insn set c/r/n = %2x/%2x/%2x\n", 11310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_CHAN((&insn->chanspec)[0]), 11320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CR_RANGE((&insn->chanspec)[0]), insn->n); 11338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 11348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0])); 11368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11372306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0])) 11388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ai_range_set(CR_RANGE((&insn->chanspec)[0])); 11398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 11418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < insn->n; i++) { 11438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_software_trigger(); 11448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud timeout = PCI9111_AI_INSTANT_READ_TIMEOUT; 11468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud while (timeout--) { 11488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (!pci9111_is_fifo_empty()) 11498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud goto conversion_done; 11508cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 11518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_error(dev, "A/D read timeout"); 11538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = 0; 11548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_fifo_reset(); 11558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -ETIME; 11568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralconversion_done: 11588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11592306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (resolution == PCI9111_HR_AI_RESOLUTION) 11608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = pci9111_hr_ai_get_data(); 11612306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom else 11628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = pci9111_ai_get_data(); 11638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 11648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#ifdef AI_INSN_DEBUG 11668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud printk(PCI9111_DRIVER_NAME ": ai_insn get c/r/t = %2x/%2x/%2x\n", 11670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_ai_channel_get(), 11680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_ai_range_get(), pci9111_trigger_and_autoscan_get()); 11698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud#endif 11708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return i; 11728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 117452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Analog instant output */ 11758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaudstatic int 1177da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonpci9111_ao_insn_write(struct comedi_device *dev, 11780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_insn *insn, 11790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 11808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 11818cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int i; 11828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11838cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < insn->n; i++) { 11848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_ao_set_data(data[i]); 11858cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->ao_readback = data[i]; 11868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 11878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return i; 11898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 11908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 119152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Analog output readback */ 11928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1193da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_ao_insn_read(struct comedi_device *dev, 11940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 11950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 11968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 11978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int i; 11988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 11992306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom for (i = 0; i < insn->n; i++) 12008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[i] = dev_private->ao_readback & PCI9111_AO_RESOLUTION_MASK; 12018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return i; 12038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 12048cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 120552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 120652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* DIGITAL INPUT OUTPUT SECTION */ 120752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 12088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 120952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Digital inputs */ 12108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1211da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_di_insn_bits(struct comedi_device *dev, 12120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice, 12130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 12148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 1215790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int bits; 12168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits = pci9111_di_get_bits(); 12188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[1] = bits; 12198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 2; 12218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 12228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 122352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Digital outputs */ 12248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1225da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_do_insn_bits(struct comedi_device *dev, 12260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *subdevice, 12270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 12288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 1229790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int bits; 12308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 123152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Only set bits that have been masked */ 123252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* data[0] = mask */ 123352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* data[1] = bit state */ 12348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[0] &= PCI9111_DO_MASK; 12368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits = subdevice->state; 12388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits &= ~data[0]; 12398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud bits |= data[0] & data[1]; 12408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->state = bits; 12418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_do_set_bits(bits); 12438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud data[1] = bits; 12458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 2; 12478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 12488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 124952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 125052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* INITIALISATION SECTION */ 125152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* ------------------------------------------------------------------ */ 12528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 125352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Reset device */ 12548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1255da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_reset(struct comedi_device *dev) 12568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 125752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Set trigger source to software */ 12588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true, 12600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral true, false); 12618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_trigger_source_set(dev, software); 12638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_pretrigger_set(dev, false); 12648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_autoscan_set(dev, false); 12658cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 126652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Reset 8254 chip */ 12678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->timer_divisor_1 = 0; 12698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->timer_divisor_2 = 0; 12708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_timer_set(dev); 12728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 12748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 12758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 127652f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Attach */ 127752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* - Register PCI device */ 127852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* - Declare device driver capability */ 12798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci9111_attach(struct comedi_device *dev, 12810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it) 12828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 128334c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *subdevice; 12848cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud unsigned long io_base, io_range, lcr_io_base, lcr_io_range; 128520fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy struct pci_dev *pci_device = NULL; 12868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud int error, i; 1287940579fbae1a3a8967fe619562c8e78080dd873dBill Pemberton const struct pci9111_board *board; 12888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12892306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (alloc_private(dev, sizeof(struct pci9111_private_data)) < 0) 12908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -ENOMEM; 129152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Probe the device to determine what device in the series it is. */ 12928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 12938522e70b44021d1cc44de1f6c491ac21cc8f4f3dMaurice Dawson printk(KERN_ERR "comedi%d: " PCI9111_DRIVER_NAME " driver\n", 12948522e70b44021d1cc44de1f6c491ac21cc8f4f3dMaurice Dawson dev->minor); 12958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 129620fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy for_each_pci_dev(pci_device) { 12978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci_device->vendor == PCI_VENDOR_ID_ADLINK) { 12988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud for (i = 0; i < pci9111_board_nbr; i++) { 12998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci9111_boards[i].device_id == 13000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_device->device) { 13017ecac4c38a813021155c4207592693ad1949b9b7Mark /* was a particular bus/slot 13027ecac4c38a813021155c4207592693ad1949b9b7Mark * requested? */ 13038cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if ((it->options[0] != 0) 13040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || (it->options[1] != 0)) { 13057ecac4c38a813021155c4207592693ad1949b9b7Mark /* are we on the wrong 13067ecac4c38a813021155c4207592693ad1949b9b7Mark * bus/slot? */ 13078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci_device->bus->number != 13080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral it->options[0] 13090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || 13100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pci_device->devfn) 13110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral != it->options[1]) { 13128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud continue; 13138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->board_ptr = pci9111_boards + i; 13170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral board = 13180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (struct pci9111_board *) 13190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->board_ptr; 13208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->pci_device = pci_device; 13218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud goto found; 13228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13278522e70b44021d1cc44de1f6c491ac21cc8f4f3dMaurice Dawson printk(KERN_ERR 13288522e70b44021d1cc44de1f6c491ac21cc8f4f3dMaurice Dawson "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", 13298522e70b44021d1cc44de1f6c491ac21cc8f4f3dMaurice Dawson dev->minor, it->options[0], it->options[1]); 13308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -EIO; 13318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralfound: 13338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13348522e70b44021d1cc44de1f6c491ac21cc8f4f3dMaurice Dawson printk(KERN_ERR "comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n", 13350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, 13360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci9111_boards[i].name, 13370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_device->bus->number, 13380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pci_device->devfn), 13390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_FUNC(pci_device->devfn), pci_device->irq); 13408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 134152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: Warn about non-tested boards. */ 13428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13437ecac4c38a813021155c4207592693ad1949b9b7Mark /* Read local configuration register base address 13447ecac4c38a813021155c4207592693ad1949b9b7Mark * [PCI_BASE_ADDRESS #1]. */ 13458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud lcr_io_base = pci_resource_start(pci_device, 1); 13478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud lcr_io_range = pci_resource_len(pci_device, 1); 13488cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 13500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n", 13510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, lcr_io_base, lcr_io_range); 13528cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 135352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Enable PCI device and request regions */ 13548cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (comedi_pci_enable(pci_device, PCI9111_DRIVER_NAME) < 0) { 13550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 13560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ("comedi%d: Failed to enable PCI device and request regions\n", 13570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor); 13588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -EIO; 13598cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 136052f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Read PCI6308 register base address [PCI_BASE_ADDRESS #2]. */ 13618cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13628cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud io_base = pci_resource_start(pci_device, 2); 13638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud io_range = pci_resource_len(pci_device, 2); 13648cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13658522e70b44021d1cc44de1f6c491ac21cc8f4f3dMaurice Dawson printk(KERN_ERR "comedi%d: 6503 registers at address 0x%4lx [0x%4lx]\n", 13660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, io_base, io_range); 13678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->iobase = io_base; 13698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->board_name = board->name; 13708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->io_range = io_range; 13718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->is_valid = 0; 13728cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->lcr_io_base = lcr_io_base; 13738cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->lcr_io_range = lcr_io_range; 13748cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13758cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_reset(dev); 13768cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 137752f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Irq setup */ 13788cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13798cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->irq = 0; 13808cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (pci_device->irq > 0) { 13815f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman if (request_irq(pci_device->irq, pci9111_interrupt, 13828cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud IRQF_SHARED, PCI9111_DRIVER_NAME, dev) != 0) { 13838522e70b44021d1cc44de1f6c491ac21cc8f4f3dMaurice Dawson printk(KERN_ERR 13848522e70b44021d1cc44de1f6c491ac21cc8f4f3dMaurice Dawson "comedi%d: unable to allocate irq %u\n", 13858522e70b44021d1cc44de1f6c491ac21cc8f4f3dMaurice Dawson dev->minor, pci_device->irq); 13868cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return -EINVAL; 13878cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13888cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 13898cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->irq = pci_device->irq; 13908cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 139152f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: Add external multiplexer setup (according to option[2]). */ 13928cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1393c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton error = alloc_subdevices(dev, 4); 1394c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (error < 0) 13958cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return error; 13968cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 13978cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 0; 13988cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev->read_subdev = subdevice; 13998cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14008cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_AI; 14018cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; 14028cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 140352f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* TODO: Add external multiplexer data */ 140452f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* if (devpriv->usemux) { subdevice->n_chan = devpriv->usemux; } */ 140552f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* else { subdevice->n_chan = this_board->n_aichan; } */ 14068cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14078cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = board->ai_channel_nbr; 14088cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = board->ai_resolution_mask; 14098cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->len_chanlist = board->ai_channel_nbr; 14108cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = board->ai_range_list; 14118cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->cancel = pci9111_ai_cancel; 14128cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_read = pci9111_ai_insn_read; 14138cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->do_cmdtest = pci9111_ai_do_cmd_test; 14148cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->do_cmd = pci9111_ai_do_cmd; 14158cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->munge = pci9111_ai_munge; 14168cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14178cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 1; 14188cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_AO; 14198cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_WRITABLE | SDF_COMMON; 14208cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = board->ao_channel_nbr; 14218cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = board->ao_resolution_mask; 14228cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->len_chanlist = board->ao_channel_nbr; 14238cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = board->ao_range_list; 14248cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_write = pci9111_ao_insn_write; 14258cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_read = pci9111_ao_insn_read; 14268cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14278cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 2; 14288cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_DI; 14298cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_READABLE; 14308cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = PCI9111_DI_CHANNEL_NBR; 14318cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = 1; 14328cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = &range_digital; 14338cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_bits = pci9111_di_insn_bits; 14348cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14358cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice = dev->subdevices + 3; 14368cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->type = COMEDI_SUBD_DO; 14378cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->subdev_flags = SDF_READABLE | SDF_WRITABLE; 14388cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->n_chan = PCI9111_DO_CHANNEL_NBR; 14398cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->maxdata = 1; 14408cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->range_table = &range_digital; 14418cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud subdevice->insn_bits = pci9111_do_insn_bits; 14428cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14438cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud dev_private->is_valid = 1; 14448cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14458cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 14468cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 14478cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 144852f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton/* Detach */ 14498cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1450da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci9111_detach(struct comedi_device *dev) 14518cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud{ 145252f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Reset device */ 14538cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1454525d1b1395858606103d4663a570cc8725ff2cedGreg Kroah-Hartman if (dev->private != NULL) { 14558cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud if (dev_private->is_valid) 14568cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci9111_reset(dev); 14578cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14588cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 145952f8ac983079ad6bba3c055152a39ccc5e76350aBill Pemberton /* Release previously allocated irq */ 14608cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14612306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (dev->irq != 0) 14625f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 14638cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 1464525d1b1395858606103d4663a570cc8725ff2cedGreg Kroah-Hartman if (dev_private != NULL && dev_private->pci_device != NULL) { 14652306d9b1ee065d0dfb56af4cd05195ec61d69256Rich Folsom if (dev->iobase) 14668cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud comedi_pci_disable(dev_private->pci_device); 14678cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud pci_dev_put(dev_private->pci_device); 14688cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud } 14698cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud 14708cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud return 0; 14718cb9b9fb975476b6b3128f2d192d4e2ddf94c5a0Emmanuel Pacaud} 147290f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 147390f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 147490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 147590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 1476