adl_pci6208.c revision c1b31c44a38e2b5153193680e4bee4856b3307e1
18b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/* 28b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow comedi/drivers/adl_pci6208.c 38b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 48b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow Hardware driver for ADLink 6208 series cards: 58b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow card | voltage output | current output 68b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow -------------+-------------------+--------------- 78b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow PCI-6208V | 8 channels | - 88b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow PCI-6216V | 16 channels | - 98b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow PCI-6208A | 8 channels | 8 channels 108b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 118b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow COMEDI - Linux Control and Measurement Device Interface 128b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow Copyright (C) 2000 David A. Schleef <ds@schleef.org> 138b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 148b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow This program is free software; you can redistribute it and/or modify 158b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow it under the terms of the GNU General Public License as published by 168b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow the Free Software Foundation; either version 2 of the License, or 178b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow (at your option) any later version. 188b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 198b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow This program is distributed in the hope that it will be useful, 208b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow but WITHOUT ANY WARRANTY; without even the implied warranty of 218b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 228b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow GNU General Public License for more details. 238b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 248b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow You should have received a copy of the GNU General Public License 258b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow along with this program; if not, write to the Free Software 268b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 278b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow*/ 288b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/* 298b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowDriver: adl_pci6208 308b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowDescription: ADLink PCI-6208A 318b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowDevices: [ADLink] PCI-6208A (adl_pci6208) 328b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowAuthor: nsyeow <nsyeow@pd.jaring.my> 338b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowUpdated: Fri, 30 Jan 2004 14:44:27 +0800 348b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowStatus: untested 358b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 368b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowConfiguration Options: 378b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow none 388b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 398b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowReferences: 408b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow - ni_660x.c 418b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow - adl_pci9111.c copied the entire pci setup section 428b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow - adl_pci9118.c 438b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow*/ 448b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/* 458b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * These headers should be followed by a blank line, and any comments 468b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * you wish to say about the driver. The comment area is the place 478b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * to put any known bugs, limitations, unsupported features, supported 488b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * command triggers, whether or not commands are supported on particular 498b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * subdevices, etc. 508b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * 518b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * Somewhere in the comment should be information about configuration 528b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * options that are used with comedi_config. 538b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow */ 548b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow#include "../comedidev.h" 558b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow#include "comedi_pci.h" 568b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 578b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow#define PCI6208_DRIVER_NAME "adl_pci6208" 588b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 598b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/* Board descriptions */ 60c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pembertonstruct pci6208_board { 618b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow const char *name; 628b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow unsigned short dev_id; /* `lspci` will show you this */ 638b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow int ao_chans; 648b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //int ao_bits; 65c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pemberton}; 66c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pemberton 67c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pembertonstatic const struct pci6208_board pci6208_boards[] = { 688b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow /*{ 698b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow name : "pci6208v", 708b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow dev_id : 0x6208, //not sure 718b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow ao_chans: 8 728b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //, ao_bits : 16 738b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow }, 748b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow { 758b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow name : "pci6216v", 768b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow dev_id : 0x6208, //not sure 778b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow ao_chans: 16 788b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //, ao_bits : 16 798b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow }, */ 808b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow { 818b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow name: "pci6208a", 828b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow dev_id: 0x6208, 838b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow ao_chans:8 848b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //, ao_bits : 16 858b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow } 868b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow}; 878b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 888b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/* This is used by modprobe to translate PCI IDs to drivers. Should 898b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * only be used for PCI and ISA-PnP devices */ 908b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowstatic DEFINE_PCI_DEVICE_TABLE(pci6208_pci_table) = { 918b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //{ PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 928b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //{ PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 938b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow {PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 948b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow {0} 958b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow}; 968b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 978b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowMODULE_DEVICE_TABLE(pci, pci6208_pci_table); 988b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 998b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/* Will be initialized in pci6208_find device(). */ 100c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pemberton#define thisboard ((const struct pci6208_board *)dev->board_ptr) 1018b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1028b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowtypedef struct { 1038b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow int data; 1048b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow struct pci_dev *pci_dev; /* for a PCI device */ 105790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int ao_readback[2]; /* Used for AO readback */ 1068b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow} pci6208_private; 1078b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1088b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow#define devpriv ((pci6208_private *)dev->private) 1098b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1100707bb04be89b18ee83b5a997e36cc585f0b988dBill Pembertonstatic int pci6208_attach(struct comedi_device * dev, struct comedi_devconfig * it); 11171b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int pci6208_detach(struct comedi_device * dev); 1128b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1138b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow#define pci6208_board_nbr \ 114c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pemberton (sizeof(pci6208_boards) / sizeof(struct pci6208_board)) 1158b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 116139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_pci6208 = { 1178b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow driver_name:PCI6208_DRIVER_NAME, 1188b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow module:THIS_MODULE, 1198b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow attach:pci6208_attach, 1208b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow detach:pci6208_detach, 1218b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow}; 1228b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1238b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowCOMEDI_PCI_INITCLEANUP(driver_pci6208, pci6208_pci_table); 1248b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 12571b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int pci6208_find_device(struct comedi_device * dev, int bus, int slot); 1268b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowstatic int 1278b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowpci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr, 1288b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow int dev_minor); 1298b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1308b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/*read/write functions*/ 13134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int pci6208_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s, 13290035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton struct comedi_insn * insn, unsigned int * data); 13334c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int pci6208_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 13490035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton struct comedi_insn * insn, unsigned int * data); 13534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton//static int pci6208_dio_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, 13690035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton// struct comedi_insn *insn,unsigned int *data); 13734c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton//static int pci6208_dio_insn_config(struct comedi_device *dev,struct comedi_subdevice *s, 13890035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton// struct comedi_insn *insn,unsigned int *data); 1398b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1408b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/* 1418b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * Attach is called by the Comedi core to configure the driver 1428b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * for a particular board. If you specified a board_name array 1438b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * in the driver structure, dev->board_ptr contains that 1448b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * address. 1458b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow */ 1460707bb04be89b18ee83b5a997e36cc585f0b988dBill Pembertonstatic int pci6208_attach(struct comedi_device * dev, struct comedi_devconfig * it) 1478b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow{ 14834c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 1498b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow int retval; 1508b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow unsigned long io_base; 1518b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1528b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow printk("comedi%d: pci6208: ", dev->minor); 1538b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1548b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow retval = alloc_private(dev, sizeof(pci6208_private)); 1558b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow if (retval < 0) 1568b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow return retval; 1578b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1588b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow retval = pci6208_find_device(dev, it->options[0], it->options[1]); 1598b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow if (retval < 0) 1608b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow return retval; 1618b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1628b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow retval = pci6208_pci_setup(devpriv->pci_dev, &io_base, dev->minor); 1638b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow if (retval < 0) 1648b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow return retval; 1658b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1668b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow dev->iobase = io_base; 1678b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow dev->board_name = thisboard->name; 1688b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1698b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/* 1708b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * Allocate the subdevice structures. alloc_subdevice() is a 1718b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * convenient macro defined in comedidev.h. 1728b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow */ 1738b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow if (alloc_subdevices(dev, 2) < 0) 1748b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow return -ENOMEM; 1758b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1768b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow s = dev->subdevices + 0; 1778b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow /* analog output subdevice */ 1788b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow s->type = COMEDI_SUBD_AO; 1798b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow s->subdev_flags = SDF_WRITABLE; //anything else to add here?? 1808b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow s->n_chan = thisboard->ao_chans; 1818b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow s->maxdata = 0xffff; //16-bit DAC 1828b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow s->range_table = &range_bipolar10; //this needs to be checked. 1838b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow s->insn_write = pci6208_ao_winsn; 1848b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow s->insn_read = pci6208_ao_rinsn; 1858b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1868b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //s=dev->subdevices+1; 1878b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow /* digital i/o subdevice */ 1888b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //s->type=COMEDI_SUBD_DIO; 1898b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //s->subdev_flags=SDF_READABLE|SDF_WRITABLE; 1908b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //s->n_chan=16; 1918b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //s->maxdata=1; 1928b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //s->range_table=&range_digital; 1938b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //s->insn_bits = pci6208_dio_insn_bits; 1948b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //s->insn_config = pci6208_dio_insn_config; 1958b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1968b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow printk("attached\n"); 1978b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 1988b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow return 1; 1998b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow} 2008b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 2018b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/* 2028b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * _detach is called to deconfigure a device. It should deallocate 2038b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * resources. 2048b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * This function is also called when _attach() fails, so it should be 2058b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * careful not to release resources that were not necessarily 2068b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * allocated by _attach(). dev->private and dev->subdevices are 2078b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * deallocated automatically by the core. 2088b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow */ 20971b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int pci6208_detach(struct comedi_device * dev) 2108b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow{ 2118b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow printk("comedi%d: pci6208: remove\n", dev->minor); 2128b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 2138b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow if (devpriv && devpriv->pci_dev) { 2148b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow if (dev->iobase) { 2158b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow comedi_pci_disable(devpriv->pci_dev); 2168b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow } 2178b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow pci_dev_put(devpriv->pci_dev); 2188b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow } 2198b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 2208b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow return 0; 2218b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow} 2228b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 22334c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int pci6208_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s, 22490035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton struct comedi_insn * insn, unsigned int * data) 2258b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow{ 2268b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow int i = 0, Data_Read; 2278b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow unsigned short chan = CR_CHAN(insn->chanspec); 2288b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow unsigned long invert = 1 << (16 - 1); 2298b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow unsigned long out_value; 2308b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow /* Writing a list of values to an AO channel is probably not 2318b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * very useful, but that's how the interface is defined. */ 2328b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow for (i = 0; i < insn->n; i++) { 2338b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow out_value = data[i] ^ invert; 2348b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow /* a typical programming sequence */ 2358b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow do { 2368b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow Data_Read = (inw(dev->iobase) & 1); 2378b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow } while (Data_Read); 2388b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow outw(out_value, dev->iobase + (0x02 * chan)); 2398b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow devpriv->ao_readback[chan] = out_value; 2408b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow } 2418b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 2428b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow /* return the number of samples read/written */ 2438b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow return i; 2448b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow} 2458b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 2468b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/* AO subdevices should have a read insn as well as a write insn. 2478b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * Usually this means copying a value stored in devpriv. */ 24834c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int pci6208_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 24990035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton struct comedi_insn * insn, unsigned int * data) 2508b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow{ 2518b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow int i; 2528b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow int chan = CR_CHAN(insn->chanspec); 2538b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 2548b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow for (i = 0; i < insn->n; i++) 2558b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow data[i] = devpriv->ao_readback[chan]; 2568b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 2578b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow return i; 2588b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow} 2598b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 2608b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/* DIO devices are slightly special. Although it is possible to 2618b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * implement the insn_read/insn_write interface, it is much more 2628b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * useful to applications if you implement the insn_bits interface. 2638b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * This allows packed reading/writing of the DIO channels. The 2648b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * comedi core can convert between insn_bits and insn_read/write */ 26534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton//static int pci6208_dio_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, 26690035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton// struct comedi_insn *insn,unsigned int *data) 2678b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow//{ 2688b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow// if(insn->n!=2)return -EINVAL; 2698b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 2708b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow /* The insn data is a mask in data[0] and the new data 2718b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * in data[1], each channel cooresponding to a bit. */ 2728b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow// if(data[0]){ 2738b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow// s->state &= ~data[0]; 2748b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow// s->state |= data[0]&data[1]; 2758b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow /* Write out the new digital output lines */ 2768b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //outw(s->state,dev->iobase + SKEL_DIO); 2778b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow// } 2788b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 2798b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow /* on return, data[1] contains the value of the digital 2808b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * input and output lines. */ 2818b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //data[1]=inw(dev->iobase + SKEL_DIO); 2828b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow /* or we could just return the software copy of the output values if 2838b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * it was a purely digital output subdevice */ 2848b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //data[1]=s->state; 2858b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 2868b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow// return 2; 2878b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow//} 2888b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 28934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton//static int pci6208_dio_insn_config(struct comedi_device *dev,struct comedi_subdevice *s, 29090035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton// struct comedi_insn *insn,unsigned int *data) 2918b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow//{ 2928b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow// int chan=CR_CHAN(insn->chanspec); 2938b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 2948b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow /* The input or output configuration of each digital line is 2958b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * configured by a special insn_config instruction. chanspec 2968b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * contains the channel to be changed, and data[0] contains the 2978b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow * value COMEDI_INPUT or COMEDI_OUTPUT. */ 2988b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 2998b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow// if(data[0]==COMEDI_OUTPUT){ 3008b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow// s->io_bits |= 1<<chan; 3018b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow// }else{ 3028b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow// s->io_bits &= ~(1<<chan); 3038b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow// } 3048b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //outw(s->io_bits,dev->iobase + SKEL_DIO_CONFIG); 3058b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3068b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow// return 1; 3078b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow//} 3088b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 30971b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int pci6208_find_device(struct comedi_device * dev, int bus, int slot) 3108b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow{ 3118b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow struct pci_dev *pci_dev; 3128b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow int i; 3138b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3148b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow for (pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); 3158b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow pci_dev != NULL; 3168b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) { 3178b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow if (pci_dev->vendor == PCI_VENDOR_ID_ADLINK) { 3188b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow for (i = 0; i < pci6208_board_nbr; i++) { 3198b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow if (pci6208_boards[i].dev_id == pci_dev->device) { 3208b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow // was a particular bus/slot requested? 3218b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow if ((bus != 0) || (slot != 0)) { 3228b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow // are we on the wrong bus/slot? 3238b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow if (pci_dev->bus->number 3248b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow != bus || 3258b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow PCI_SLOT(pci_dev->devfn) 3268b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow != slot) { 3278b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow continue; 3288b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow } 3298b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow } 3308b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow dev->board_ptr = pci6208_boards + i; 3318b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow goto found; 3328b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow } 3338b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow } 3348b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow } 3358b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow } 3368b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3378b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", 3388b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow dev->minor, bus, slot); 3398b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow return -EIO; 3408b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3418b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow found: 3428b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n", 3438b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow dev->minor, 3448b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow pci6208_boards[i].name, 3458b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow pci_dev->bus->number, 3468b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow PCI_SLOT(pci_dev->devfn), 3478b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow PCI_FUNC(pci_dev->devfn), pci_dev->irq); 3488b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3498b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow // TODO: Warn about non-tested boards. 3508b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //switch(board->device_id) 3518b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //{ 3528b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //}; 3538b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3548b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow devpriv->pci_dev = pci_dev; 3558b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3568b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow return 0; 3578b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow} 3588b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3598b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowstatic int 3608b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowpci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr, 3618b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow int dev_minor) 3628b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow{ 3638b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow unsigned long io_base, io_range, lcr_io_base, lcr_io_range; 3648b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3658b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow // Enable PCI device and request regions 3668b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow if (comedi_pci_enable(pci_dev, PCI6208_DRIVER_NAME) < 0) { 3678b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow printk("comedi%d: Failed to enable PCI device and request regions\n", dev_minor); 3688b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow return -EIO; 3698b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow } 3708b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow // Read local configuration register base address [PCI_BASE_ADDRESS #1]. 3718b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow lcr_io_base = pci_resource_start(pci_dev, 1); 3728b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow lcr_io_range = pci_resource_len(pci_dev, 1); 3738b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3748b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow printk("comedi%d: local config registers at address 0x%4lx [0x%4lx]\n", 3758b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow dev_minor, lcr_io_base, lcr_io_range); 3768b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3778b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow // Read PCI6208 register base address [PCI_BASE_ADDRESS #2]. 3788b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow io_base = pci_resource_start(pci_dev, 2); 3798b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow io_range = pci_resource_end(pci_dev, 2) - io_base + 1; 3808b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3818b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow printk("comedi%d: 6208 registers at address 0x%4lx [0x%4lx]\n", 3828b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow dev_minor, io_base, io_range); 3838b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3848b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow *io_base_ptr = io_base; 3858b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //devpriv->io_range = io_range; 3868b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //devpriv->is_valid=0; 3878b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //devpriv->lcr_io_base=lcr_io_base; 3888b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow //devpriv->lcr_io_range=lcr_io_range; 3898b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow 3908b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow return 0; 3918b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow} 392