16a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 26a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott comedi/drivers/amplc_pc236.c 36a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott Driver for Amplicon PC36AT and PCI236 DIO boards. 46a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 56a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott Copyright (C) 2002 MEV Ltd. <http://www.mev.co.uk/> 66a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 76a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott COMEDI - Linux Control and Measurement Device Interface 86a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott Copyright (C) 2000 David A. Schleef <ds@schleef.org> 96a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 106a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott This program is free software; you can redistribute it and/or modify 116a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott it under the terms of the GNU General Public License as published by 126a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott the Free Software Foundation; either version 2 of the License, or 136a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott (at your option) any later version. 146a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 156a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott This program is distributed in the hope that it will be useful, 166a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott but WITHOUT ANY WARRANTY; without even the implied warranty of 176a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 186a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott GNU General Public License for more details. 196a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 206a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott You should have received a copy of the GNU General Public License 216a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott along with this program; if not, write to the Free Software 226a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 236a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 246a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott*/ 256a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 266a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan AbbottDriver: amplc_pc236 276a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan AbbottDescription: Amplicon PC36AT, PCI236 286a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan AbbottAuthor: Ian Abbott <abbotti@mev.co.uk> 296a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan AbbottDevices: [Amplicon] PC36AT (pc36at), PCI236 (pci236 or amplc_pc236) 300d6e5dad12c5a2860e3d13b4d7a4702f90386003Ian AbbottUpdated: Wed, 01 Apr 2009 15:41:25 +0100 316a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan AbbottStatus: works 326a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 336a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan AbbottConfiguration options - PC36AT: 346a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott [0] - I/O port base address 356a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott [1] - IRQ (optional) 366a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 376a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan AbbottConfiguration options - PCI236: 386a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott [0] - PCI bus of device (optional) 396a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott [1] - PCI slot of device (optional) 406a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott If bus/slot is not specified, the first available PCI device will be 416a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott used. 426a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 436a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan AbbottThe PC36AT ISA board and PCI236 PCI board have a single 8255 appearing 446a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbottas subdevice 0. 456a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 466a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan AbbottSubdevice 1 pretends to be a digital input device, but it always returns 476a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott0 when read. However, if you run a command with scan_begin_src=TRIG_EXT, 480d6e5dad12c5a2860e3d13b4d7a4702f90386003Ian Abbotta rising edge on port C bit 3 acts as an external trigger, which can be 496a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbottused to wake up tasks. This is like the comedi_parport device, but the 506a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbottonly way to physically disable the interrupt on the PC36AT is to remove 516a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbottthe IRQ jumper. If no interrupt is connected, then subdevice 1 is 526a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbottunused. 536a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott*/ 546a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 5570265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slaby#include <linux/interrupt.h> 5670265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slaby 576a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#include "../comedidev.h" 586a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 596a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#include "comedi_pci.h" 606a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 616a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#include "8255.h" 626a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#include "plx9052.h" 636a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 646a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#define PC236_DRIVER_NAME "amplc_pc236" 656a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 666a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* PCI236 PCI configuration register information */ 676a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#define PCI_VENDOR_ID_AMPLICON 0x14dc 686a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009 696a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#define PCI_DEVICE_ID_INVALID 0xffff 706a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 716a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* PC36AT / PCI236 registers */ 726a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 736a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#define PC236_IO_SIZE 4 746a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#define PC236_LCR_IO_SIZE 128 756a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 766a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 776a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * INTCSR values for PCI236. 786a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 796a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* Disable interrupt, also clear any interrupt there */ 8053106ae68acf6eda9593150a25fc44e30fd5ff68Bill Pemberton#define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1ENAB_DISABLED \ 819f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi | PLX9052_INTCSR_LI1POL_HIGH \ 829f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi | PLX9052_INTCSR_LI2POL_HIGH \ 839f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi | PLX9052_INTCSR_PCIENAB_DISABLED \ 849f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi | PLX9052_INTCSR_LI1SEL_EDGE \ 859f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi | PLX9052_INTCSR_LI1CLRINT_ASSERTED) 866a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* Enable interrupt, also clear any interrupt there. */ 8753106ae68acf6eda9593150a25fc44e30fd5ff68Bill Pemberton#define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB_ENABLED \ 889f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi | PLX9052_INTCSR_LI1POL_HIGH \ 899f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi | PLX9052_INTCSR_LI2POL_HIGH \ 909f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi | PLX9052_INTCSR_PCIENAB_ENABLED \ 919f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi | PLX9052_INTCSR_LI1SEL_EDGE \ 929f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi | PLX9052_INTCSR_LI1CLRINT_ASSERTED) 936a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 946a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 956a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Board descriptions for Amplicon PC36AT and PCI236. 966a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 976a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 986a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbottenum pc236_bustype { isa_bustype, pci_bustype }; 996a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbottenum pc236_model { pc36at_model, pci236_model, anypci_model }; 1006a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 10157ad869651d1d2f163a1c5ccb577ee794847fd77Bill Pembertonstruct pc236_board { 1026a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott const char *name; 1036a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott const char *fancy_name; 1046a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott unsigned short devid; 1056a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott enum pc236_bustype bustype; 1066a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott enum pc236_model model; 10757ad869651d1d2f163a1c5ccb577ee794847fd77Bill Pemberton}; 10857ad869651d1d2f163a1c5ccb577ee794847fd77Bill Pembertonstatic const struct pc236_board pc236_boards[] = { 1096a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott { 1100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pc36at", 1110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fancy_name = "PC36AT", 1120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .bustype = isa_bustype, 1130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .model = pc36at_model, 1140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 1156a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 1166a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott { 1170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci236", 1180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fancy_name = "PCI236", 1190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .devid = PCI_DEVICE_ID_AMPLICON_PCI236, 1200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .bustype = pci_bustype, 1210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .model = pci236_model, 1220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 1236a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif 1246a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 1256a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott { 1260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = PC236_DRIVER_NAME, 1270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .fancy_name = PC236_DRIVER_NAME, 1280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .devid = PCI_DEVICE_ID_INVALID, 1290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .bustype = pci_bustype, 1300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .model = anypci_model, /* wildcard */ 1310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 1326a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif 1336a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott}; 1346a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 1356a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 1366a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbottstatic DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = { 1377b0be12b26d86ea2bd5079f0d723289e2f5a43a9Peter Huewe { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236) }, 1387b0be12b26d86ea2bd5079f0d723289e2f5a43a9Peter Huewe {0} 1396a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott}; 1406a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 1416a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan AbbottMODULE_DEVICE_TABLE(pci, pc236_pci_table); 1426a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif /* CONFIG_COMEDI_PCI */ 1436a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 1446a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 1456a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Useful for shorthand access to the particular board structure 1466a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 14757ad869651d1d2f163a1c5ccb577ee794847fd77Bill Pemberton#define thisboard ((const struct pc236_board *)dev->board_ptr) 1486a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 1496a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* this structure is for data unique to this hardware driver. If 1506a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott several hardware drivers keep similar information in this structure, 1519f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi feel free to suggest moving the variable to the struct comedi_device struct. 1529f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi */ 153f1ee810a1383b623ec523edd521467a7b620a09aBill Pembertonstruct pc236_private { 1546a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 1556a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* PCI device */ 1566a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott struct pci_dev *pci_dev; 1579f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */ 1586a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif 1596a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott int enable_irq; 160f1ee810a1383b623ec523edd521467a7b620a09aBill Pemberton}; 1616a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 162f1ee810a1383b623ec523edd521467a7b620a09aBill Pemberton#define devpriv ((struct pc236_private *)dev->private) 1636a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 1646a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 165139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pemberton * The struct comedi_driver structure tells the Comedi core module 1666a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * which functions to call to configure/deconfigure (attach/detach) 1676a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * the board, and also about the kernel module that contains 1686a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * the device code. 1696a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 170da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it); 171da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pc236_detach(struct comedi_device *dev); 172139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_amplc_pc236 = { 17368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = PC236_DRIVER_NAME, 17468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 17568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = pc236_attach, 17668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = pc236_detach, 17768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .board_name = &pc236_boards[0].name, 17868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .offset = sizeof(struct pc236_board), 1798629efa4cbf6f89a54a85af4b8bc31762af01800Bill Pemberton .num_names = ARRAY_SIZE(pc236_boards), 1806a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott}; 1816a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 1826a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 183727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __devinit driver_amplc_pc236_pci_probe(struct pci_dev *dev, 184727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas const struct pci_device_id 185727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas *ent) 186727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 187727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return comedi_pci_auto_config(dev, driver_amplc_pc236.driver_name); 188727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 189727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 190727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __devexit driver_amplc_pc236_pci_remove(struct pci_dev *dev) 191727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 192727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_pci_auto_unconfig(dev); 193727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 194727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 195727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic struct pci_driver driver_amplc_pc236_pci_driver = { 196727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .id_table = pc236_pci_table, 197727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .probe = &driver_amplc_pc236_pci_probe, 198727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .remove = __devexit_p(&driver_amplc_pc236_pci_remove) 199727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}; 200727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 201727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __init driver_amplc_pc236_init_module(void) 202727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 203727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas int retval; 204727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 205727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas retval = comedi_driver_register(&driver_amplc_pc236); 206727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas if (retval < 0) 207727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return retval; 208727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 209727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas driver_amplc_pc236_pci_driver.name = 210727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas (char *)driver_amplc_pc236.driver_name; 211727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return pci_register_driver(&driver_amplc_pc236_pci_driver); 212727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 213727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 214727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __exit driver_amplc_pc236_cleanup_module(void) 215727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 216727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas pci_unregister_driver(&driver_amplc_pc236_pci_driver); 217727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_driver_unregister(&driver_amplc_pc236); 218727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 219727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 220727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_init(driver_amplc_pc236_init_module); 221727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_exit(driver_amplc_pc236_cleanup_module); 2226a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#else 2237114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic int __init driver_amplc_pc236_init_module(void) 2247114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{ 2257114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas return comedi_driver_register(&driver_amplc_pc236); 2267114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas} 2277114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas 2287114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic void __exit driver_amplc_pc236_cleanup_module(void) 2297114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{ 2307114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas comedi_driver_unregister(&driver_amplc_pc236); 2317114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas} 2327114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas 2337114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_init(driver_amplc_pc236_init_module); 2347114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_exit(driver_amplc_pc236_cleanup_module); 2356a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif 2366a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 2376a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbottstatic int pc236_request_region(unsigned minor, unsigned long from, 2380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned long extent); 239814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void pc236_intr_disable(struct comedi_device *dev); 240814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic void pc236_intr_enable(struct comedi_device *dev); 241814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pembertonstatic int pc236_intr_check(struct comedi_device *dev); 2420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pc236_intr_insn(struct comedi_device *dev, 2430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_insn *insn, 2440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 2450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pc236_intr_cmdtest(struct comedi_device *dev, 2460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 2470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd); 2480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pc236_intr_cmd(struct comedi_device *dev, 2490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 2500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pc236_intr_cancel(struct comedi_device *dev, 2510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 25270265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t pc236_interrupt(int irq, void *d); 2536a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 2546a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 2556a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * This function looks for a PCI device matching the requested board name, 2566a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * bus and slot. 2576a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 2586a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 2596a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbottstatic int 260da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonpc236_find_pci(struct comedi_device *dev, int bus, int slot, 2610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct pci_dev **pci_dev_p) 2626a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott{ 2636a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott struct pci_dev *pci_dev = NULL; 2646a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 2656a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott *pci_dev_p = NULL; 2666a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 2676a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* Look for matching PCI device. */ 2686a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL); 2690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_dev != NULL; 2700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, 2710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_ANY_ID, pci_dev)) { 2726a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* If bus/slot specified, check them. */ 2736a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (bus || slot) { 2746a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (bus != pci_dev->bus->number 2750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral || slot != PCI_SLOT(pci_dev->devfn)) 2766a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott continue; 2776a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 2786a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (thisboard->model == anypci_model) { 2796a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* Match any supported model. */ 2806a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott int i; 2816a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 2826a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott for (i = 0; i < ARRAY_SIZE(pc236_boards); i++) { 2836a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (pc236_boards[i].bustype != pci_bustype) 2846a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott continue; 2856a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (pci_dev->device == pc236_boards[i].devid) { 2866a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* Change board_ptr to matched board. */ 2876a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott dev->board_ptr = &pc236_boards[i]; 2886a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott break; 2896a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 2906a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 2916a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (i == ARRAY_SIZE(pc236_boards)) 2926a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott continue; 2936a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } else { 2946a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* Match specific model name. */ 2956a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (pci_dev->device != thisboard->devid) 2966a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott continue; 2976a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 2986a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 2996a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* Found a match. */ 3006a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott *pci_dev_p = pci_dev; 3016a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return 0; 3026a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 3036a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* No match found. */ 3046a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (bus || slot) { 3056a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk(KERN_ERR 3060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "comedi%d: error! no %s found at pci %02x:%02x!\n", 3070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, thisboard->name, bus, slot); 3086a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } else { 3096a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk(KERN_ERR "comedi%d: error! no %s found!\n", 3100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, thisboard->name); 3116a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 3126a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return -EIO; 3136a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott} 3146a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif 3156a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 3166a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 3176a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Attach is called by the Comedi core to configure the driver 3186a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * for a particular board. If you specified a board_name array 3196a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * in the driver structure, dev->board_ptr contains that 3206a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * address. 3216a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 322da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) 3236a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott{ 32434c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 3256a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott unsigned long iobase = 0; 3266a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott unsigned int irq = 0; 3276a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 3286a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott struct pci_dev *pci_dev = NULL; 3296a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott int bus = 0, slot = 0; 3306a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif 3316a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott int share_irq = 0; 3326a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott int ret; 3336a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 3346a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, 3350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PC236_DRIVER_NAME); 3366a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 3376a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Allocate the private structure area. alloc_private() is a 3386a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * convenient macro defined in comedidev.h. 3396a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 340c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton ret = alloc_private(dev, sizeof(struct pc236_private)); 341c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (ret < 0) { 3426a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk(KERN_ERR "comedi%d: error! out of memory!\n", 3430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor); 3446a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return ret; 3456a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 3466a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* Process options. */ 3476a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott switch (thisboard->bustype) { 3486a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott case isa_bustype: 3496a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott iobase = it->options[0]; 3506a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott irq = it->options[1]; 3516a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott share_irq = 0; 3526a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott break; 3536a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 3546a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott case pci_bustype: 3556a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott bus = it->options[0]; 3566a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott slot = it->options[1]; 3576a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott share_irq = 1; 3586a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 359c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton ret = pc236_find_pci(dev, bus, slot, &pci_dev); 360c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (ret < 0) 3616a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return ret; 3626a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott devpriv->pci_dev = pci_dev; 3636a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott break; 3646a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif /* CONFIG_COMEDI_PCI */ 3656a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott default: 3666a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk(KERN_ERR 3670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "comedi%d: %s: BUG! cannot determine board type!\n", 3680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, PC236_DRIVER_NAME); 3696a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return -EINVAL; 3706a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott break; 3716a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 3726a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 3736a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 3746a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Initialize dev->board_name. 3756a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 3766a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott dev->board_name = thisboard->name; 3776a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 3786a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* Enable device and reserve I/O spaces. */ 3796a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 3806a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (pci_dev) { 381c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 382c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME); 383c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (ret < 0) { 3846a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk(KERN_ERR 3850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "comedi%d: error! cannot enable PCI device and request regions!\n", 3860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor); 3876a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return ret; 3886a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 3896a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott devpriv->lcr_iobase = pci_resource_start(pci_dev, 1); 3906a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott iobase = pci_resource_start(pci_dev, 2); 3916a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott irq = pci_dev->irq; 3926a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } else 3936a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif 3946a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott { 3956a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE); 3969f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi if (ret < 0) 3976a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return ret; 3986a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 3996a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott dev->iobase = iobase; 4006a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 4016a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 4026a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Allocate the subdevice structures. alloc_subdevice() is a 4036a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * convenient macro defined in comedidev.h. 4046a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 405c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton ret = alloc_subdevices(dev, 2); 406c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (ret < 0) { 4076a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk(KERN_ERR "comedi%d: error! out of memory!\n", 4080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor); 4096a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return ret; 4106a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 4116a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 4126a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott s = dev->subdevices + 0; 4136a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* digital i/o subdevice (8255) */ 414c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton ret = subdev_8255_init(dev, s, NULL, iobase); 415c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (ret < 0) { 4166a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk(KERN_ERR "comedi%d: error! out of memory!\n", 4170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor); 4186a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return ret; 4196a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 4206a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott s = dev->subdevices + 1; 4216a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott dev->read_subdev = s; 4226a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott s->type = COMEDI_SUBD_UNUSED; 4236a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott pc236_intr_disable(dev); 4246a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (irq) { 4256a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott unsigned long flags = share_irq ? IRQF_SHARED : 0; 4266a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 4275f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman if (request_irq(irq, pc236_interrupt, flags, 4286a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott PC236_DRIVER_NAME, dev) >= 0) { 4296a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott dev->irq = irq; 4306a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott s->type = COMEDI_SUBD_DI; 4316a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott s->subdev_flags = SDF_READABLE | SDF_CMD_READ; 4326a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott s->n_chan = 1; 4336a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott s->maxdata = 1; 4346a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott s->range_table = &range_digital; 4356a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott s->insn_bits = pc236_intr_insn; 4366a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott s->do_cmdtest = pc236_intr_cmdtest; 4376a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott s->do_cmd = pc236_intr_cmd; 4386a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott s->cancel = pc236_intr_cancel; 4396a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 4406a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 4416a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); 4426a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (thisboard->bustype == isa_bustype) { 4436a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk("(base %#lx) ", iobase); 4446a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } else { 4456a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 4466a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk("(pci %s) ", pci_name(pci_dev)); 4476a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif 4486a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 4499f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi if (irq) 4506a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); 4519f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi else 4526a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk("(no irq) "); 4536a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 4546a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk("attached\n"); 4556a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 4566a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return 1; 4576a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott} 4586a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 4596a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 4606a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * _detach is called to deconfigure a device. It should deallocate 4616a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * resources. 4626a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * This function is also called when _attach() fails, so it should be 4636a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * careful not to release resources that were not necessarily 4646a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * allocated by _attach(). dev->private and dev->subdevices are 4656a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * deallocated automatically by the core. 4666a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 467da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pc236_detach(struct comedi_device *dev) 4686a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott{ 4696a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, 4700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PC236_DRIVER_NAME); 4719f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi if (devpriv) 4726a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott pc236_intr_disable(dev); 4739f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi 4746a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (dev->irq) 4755f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 4769f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi if (dev->subdevices) 4776a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott subdev_8255_cleanup(dev, dev->subdevices + 0); 4786a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (devpriv) { 4796a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 4806a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (devpriv->pci_dev) { 4819f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi if (dev->iobase) 4826a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott comedi_pci_disable(devpriv->pci_dev); 4836a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott pci_dev_put(devpriv->pci_dev); 4846a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } else 4856a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif 4866a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott { 4879f7a344b69485dc1052534a4e1b2e5a8f7de086eBenjamin Adolphi if (dev->iobase) 4886a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott release_region(dev->iobase, PC236_IO_SIZE); 4896a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 4906a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 4916a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (dev->board_name) { 4926a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk(KERN_INFO "comedi%d: %s removed\n", 4930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->minor, dev->board_name); 4946a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 4956a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return 0; 4966a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott} 4976a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 4986a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 4996a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * This function checks and requests an I/O region, reporting an error 5006a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * if there is a conflict. 5016a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 5026a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbottstatic int pc236_request_region(unsigned minor, unsigned long from, 5030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned long extent) 5046a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott{ 5056a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (!from || !request_region(from, extent, PC236_DRIVER_NAME)) { 5066a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n", 5070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral minor, from, extent); 5086a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return -EIO; 5096a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 5106a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return 0; 5116a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott} 5126a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 5136a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 5146a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * This function is called to mark the interrupt as disabled (no command 5156a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * configured on subdevice 1) and to physically disable the interrupt 5166a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * (not possible on the PC36AT, except by removing the IRQ jumper!). 5176a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 518da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pc236_intr_disable(struct comedi_device *dev) 5196a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott{ 5206a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott unsigned long flags; 5216a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 5225f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 5236a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott devpriv->enable_irq = 0; 5246a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 5256a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (devpriv->lcr_iobase) 5266a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott outl(PCI236_INTR_DISABLE, devpriv->lcr_iobase + PLX9052_INTCSR); 5276a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif 5285f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 5296a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott} 5306a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 5316a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 5326a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * This function is called to mark the interrupt as enabled (a command 5336a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * configured on subdevice 1) and to physically enable the interrupt 5346a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * (not possible on the PC36AT, except by (re)connecting the IRQ jumper!). 5356a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 536da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pc236_intr_enable(struct comedi_device *dev) 5376a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott{ 5386a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott unsigned long flags; 5396a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 5405f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 5416a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott devpriv->enable_irq = 1; 5426a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 5436a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (devpriv->lcr_iobase) 5446a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott outl(PCI236_INTR_ENABLE, devpriv->lcr_iobase + PLX9052_INTCSR); 5456a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif 5465f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 5476a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott} 5486a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 5496a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 5506a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * This function is called when an interrupt occurs to check whether 5516a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * the interrupt has been marked as enabled and was generated by the 5526a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * board. If so, the function prepares the hardware for the next 5536a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * interrupt. 5546a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Returns 0 if the interrupt should be ignored. 5556a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 556da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pc236_intr_check(struct comedi_device *dev) 5576a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott{ 5586a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott int retval = 0; 5596a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott unsigned long flags; 5606a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 5615f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_lock_irqsave(&dev->spinlock, flags); 5626a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (devpriv->enable_irq) { 5636a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott retval = 1; 5646a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#ifdef CONFIG_COMEDI_PCI 5656a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (devpriv->lcr_iobase) { 5666a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if ((inl(devpriv->lcr_iobase + PLX9052_INTCSR) 5670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral & PLX9052_INTCSR_LI1STAT_MASK) 5680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral == PLX9052_INTCSR_LI1STAT_INACTIVE) { 5696a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott retval = 0; 5706a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } else { 5716a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* Clear interrupt and keep it enabled. */ 5726a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott outl(PCI236_INTR_ENABLE, 5730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral devpriv->lcr_iobase + PLX9052_INTCSR); 5746a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 5756a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 5766a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott#endif 5776a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 5785f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman spin_unlock_irqrestore(&dev->spinlock, flags); 5796a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 5806a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return retval; 5816a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott} 5826a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 5836a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 5846a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Input from subdevice 1. 5856a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Copied from the comedi_parport driver. 5866a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 5870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pc236_intr_insn(struct comedi_device *dev, 5880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_insn *insn, 5890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 5906a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott{ 5916a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott data[1] = 0; 5926a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return 2; 5936a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott} 5946a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 5956a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 5966a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Subdevice 1 command test. 5976a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Copied from the comedi_parport driver. 5986a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 5990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pc236_intr_cmdtest(struct comedi_device *dev, 6000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 6010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd) 6026a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott{ 6036a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott int err = 0; 6046a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott int tmp; 6056a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6066a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* step 1 */ 6076a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6086a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott tmp = cmd->start_src; 6096a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott cmd->start_src &= TRIG_NOW; 6106a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (!cmd->start_src || tmp != cmd->start_src) 6116a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott err++; 6126a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6136a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott tmp = cmd->scan_begin_src; 6146a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott cmd->scan_begin_src &= TRIG_EXT; 6156a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 6166a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott err++; 6176a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6186a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott tmp = cmd->convert_src; 6196a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott cmd->convert_src &= TRIG_FOLLOW; 6206a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (!cmd->convert_src || tmp != cmd->convert_src) 6216a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott err++; 6226a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6236a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott tmp = cmd->scan_end_src; 6246a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott cmd->scan_end_src &= TRIG_COUNT; 6256a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 6266a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott err++; 6276a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6286a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott tmp = cmd->stop_src; 6296a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott cmd->stop_src &= TRIG_NONE; 6306a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (!cmd->stop_src || tmp != cmd->stop_src) 6316a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott err++; 6326a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6336a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (err) 6346a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return 1; 6356a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6366a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* step 2: ignored */ 6376a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6386a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (err) 6396a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return 2; 6406a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6416a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* step 3: */ 6426a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6436a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (cmd->start_arg != 0) { 6446a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott cmd->start_arg = 0; 6456a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott err++; 6466a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 6476a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (cmd->scan_begin_arg != 0) { 6486a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott cmd->scan_begin_arg = 0; 6496a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott err++; 6506a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 6516a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (cmd->convert_arg != 0) { 6526a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott cmd->convert_arg = 0; 6536a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott err++; 6546a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 6556a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (cmd->scan_end_arg != 1) { 6566a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott cmd->scan_end_arg = 1; 6576a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott err++; 6586a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 6596a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (cmd->stop_arg != 0) { 6606a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott cmd->stop_arg = 0; 6616a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott err++; 6626a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 6636a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6646a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (err) 6656a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return 3; 6666a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6676a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott /* step 4: ignored */ 6686a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6696a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (err) 6706a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return 4; 6716a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6726a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return 0; 6736a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott} 6746a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6756a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 6766a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Subdevice 1 command. 6776a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 678da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pc236_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 6796a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott{ 6806a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott pc236_intr_enable(dev); 6816a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6826a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return 0; 6836a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott} 6846a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6856a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 6866a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Subdevice 1 cancel command. 6876a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 6880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pc236_intr_cancel(struct comedi_device *dev, 6890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 6906a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott{ 6916a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott pc236_intr_disable(dev); 6926a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6936a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return 0; 6946a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott} 6956a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 6966a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott/* 6976a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Interrupt service routine. 6986a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott * Based on the comedi_parport driver. 6996a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott */ 70070265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t pc236_interrupt(int irq, void *d) 7016a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott{ 70271b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton struct comedi_device *dev = d; 70334c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s = dev->subdevices + 1; 7046a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott int handled; 7056a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott 7066a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott handled = pc236_intr_check(dev); 7076a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott if (dev->attached && handled) { 7086a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott comedi_buf_put(s->async, 0); 7096a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; 7106a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott comedi_event(dev, s); 7116a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott } 7126a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott return IRQ_RETVAL(handled); 7136a5c8664766b82b36ec50bd2de9e72d3eae0dfbbIan Abbott} 71490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 71590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 71690f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 71790f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 718