⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cb_pcimdas.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    comedi/drivers/cb_pcimdas.c    Comedi driver for Computer Boards PCIM-DAS1602/16    COMEDI - Linux Control and Measurement Device Interface    Copyright (C) 2000 David A. Schleef <ds@schleef.org>    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*//*Driver: cb_pcimdas.oDescription: Computer Boards PCI Migration series boardsDevices: (Computer Boards) PCIM-DAS1602/16 [cb_pcimdas]Author: Richard BythewayUpdated: Wed, 13 Nov 2002 12:34:56 +0000Status: experimentalWritten to support the PCIM-DAS1602/16 on a 2.4 series kernel.Configuration Options:    [0] - PCI bus number    [1] - PCI slot numberDeveloped from cb_pcidas and skel by Richard Bytheway (mocelet@sucs.org). Only supports DIO, AO and simple AI in it's present form.No interrupts, multi channel or FIFO AI, although the card looks like it could support this.See http://www.measurementcomputing.com/PDFManuals/pcim-das1602_16.pdf for more details.*/#include <linux/comedidev.h>#include <linux/pci.h>#include <linux/delay.h>#include "plx9052.h"//#define CBPCIMDAS_DEBUG#undef CBPCIMDAS_DEBUG/* Registers for the PCIM-DAS1602/16 */// sizes of io regions (bytes)#define BADR0_SIZE 2  //??#define BADR1_SIZE 4#define BADR2_SIZE 6#define BADR3_SIZE 16#define BADR4_SIZE 4//DAC Offsets#define ADC_TRIG 0#define DAC0_OFFSET 2#define DAC1_OFFSET 4//AI and Counter Constants#define MUX_LIMITS 0#define MAIN_CONN_DIO 1#define ADC_STAT 2#define ADC_CONV_STAT 3#define ADC_INT 4#define ADC_PACER 5#define BURST_MODE 6#define PROG_GAIN 7#define CLK8254_1_DATA 8#define CLK8254_2_DATA 9#define CLK8254_3_DATA 10#define CLK8254_CONTROL 11#define USER_COUNTER 12#define RESID_COUNT_H 13#define RESID_COUNT_L 14//DIO Offsets#define PORT_A 0#define PORT_B 1#define PORT_C 2#define DIO_CONFIG 3//DIO Constants#define ALL_OUTPUT 128#define PORT_A_IN 16#define PORT_B_IN 2#define PORT_CH_IN 8#define PORT_CL_IN 1#define PORT_A_MASK 0x0000ff#define PORT_B_MASK 0x00ff00#define PORT_C_MASK 0xff0000#define PORT_CL_MASK 0x0f0000#define PORT_CH_MASK 0xf00000/* Board description */typedef struct cb_pcimdas_board_struct{	char *name;	unsigned short device_id;	int ai_se_chans;	// Inputs in single-ended mode	int ai_diff_chans;	// Inputs in differential mode	int ai_bits;	// analog input resolution	int ai_speed;	// fastest conversion period in ns	int ao_nchan;	// number of analog out channels	int ao_bits;	// analogue output resolution	int has_ao_fifo;	// analog output has fifo	int ao_scan_speed;	// analog output speed for 1602 series (for a scan, not conversion)	int fifo_size;	// number of samples fifo can hold	int dio_bits;  // number of dio bits	int has_dio;	// has DIO	comedi_lrange *ranges;} cb_pcimdas_board;static cb_pcimdas_board cb_pcimdas_boards[] ={	{		name:		"PCIM-DAS1602/16",		device_id:	0x56,		ai_se_chans:	16,		ai_diff_chans:	8,		ai_bits:	16,		ai_speed:	10000, //??		ao_nchan: 	2,     		ao_bits:	12,		has_ao_fifo:	0,     //??		ao_scan_speed:	10000, //??		fifo_size:	1024,   		dio_bits:	24,		has_dio:	1,//		ranges:		&cb_pcimdas_ranges,	},};/* This is used by modprobe to translate PCI IDs to drivers.  Should * only be used for PCI and ISA-PnP devices */static struct pci_device_id cb_pcimdas_pci_table[] __devinitdata = {	{ PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	{ 0 }};MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table);#define N_BOARDS 1 // Max number of boards supported/* * Useful for shorthand access to the particular board structure */#define thisboard ((cb_pcimdas_board *)dev->board_ptr)/* this structure is for data unique to this hardware driver.  If   several hardware drivers keep similar information in this structure,   feel free to suggest moving the variable to the comedi_device struct.  */typedef struct{	int data;	// would be useful for a PCI device 	struct pci_dev *pci_dev;	//base addresses	unsigned int BADR0;	unsigned int BADR1;	unsigned int BADR2;	unsigned int BADR3;	unsigned int BADR4;	/* Used for AO readback */	lsampl_t ao_readback[2];	// Used for DIO	unsigned short int port_a;   // copy of BADR4+0	unsigned short int port_b;   // copy of BADR4+1	unsigned short int port_c;   // copy of BADR4+2	unsigned short int dio_mode; // copy of BADR4+3	}cb_pcimdas_private;/* * most drivers define the following macro to make it easy to * access the private structure. */#define devpriv ((cb_pcimdas_private *)dev->private)/* * The comedi_driver structure tells the Comedi core module * which functions to call to configure/deconfigure (attach/detach) * the board, and also about the kernel module that contains * the device code. */static int cb_pcimdas_attach(comedi_device *dev,comedi_devconfig *it);static int cb_pcimdas_detach(comedi_device *dev);static comedi_driver driver_cb_pcimdas={	driver_name:	"cb_pcimdas",	module:		THIS_MODULE,	attach:		cb_pcimdas_attach,	detach:		cb_pcimdas_detach,};static int cb_pcimdas_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);static int cb_pcimdas_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);static int cb_pcimdas_ao_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);static int cb_pcimdas_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data);static int cb_pcimdas_dio_insn_config(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn,lsampl_t *data);/* * Attach is called by the Comedi core to configure the driver * for a particular board.  If you specified a board_name array * in the driver structure, dev->board_ptr contains that * address. */static int cb_pcimdas_attach(comedi_device *dev,comedi_devconfig *it){	comedi_subdevice *s;	struct pci_dev* pcidev;	int index;	//unsigned long BADR0;	unsigned long BADR1, BADR2, BADR3, BADR4;	int err;	//int i;	printk("comedi%d: cb_pcimdas: ",dev->minor);	/* * Allocate the private structure area. */	if(alloc_private(dev,sizeof(cb_pcimdas_private))<0)		return -ENOMEM;/* * Probe the device to determine what device in the series it is. */	printk("\n");	pci_for_each_dev(pcidev)	{		// is it not a computer boards card?		if(pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)			continue;		// loop through cards supported by this driver		for(index = 0; index < N_BOARDS; index++)		{			if(cb_pcimdas_boards[index].device_id != pcidev->device)				continue;			// was a particular bus/slot requested?			if(it->options[0] || it->options[1])			{				// are we on the wrong bus/slot?				if(pcidev->bus->number != it->options[0] ||				   PCI_SLOT(pcidev->devfn) != it->options[1])				{					continue;				}			}			devpriv->pci_dev = pcidev;			dev->board_ptr = cb_pcimdas_boards + index;			goto found;		}	}	printk("No supported ComputerBoards/MeasurementComputing card found on "		"requested position\n");	return -EIO;found:	printk("Found %s on bus %i, slot %i\n", cb_pcimdas_boards[index].name,		devpriv->pci_dev->bus->number, PCI_SLOT(devpriv->pci_dev->devfn));	// Warn about non-tested features	switch(thisboard->device_id)	{		case 0x56:			break;		default:			printk( "THIS CARD IS UNSUPPORTED.\n"				"PLEASE REPORT USAGE TO <mocelet@sucs.org>\n");	};	if(pci_enable_device(devpriv->pci_dev))		return -EIO;// Since I don't know how large BADR0 is, lets not request it for now.// It doesn't appear to be needed for operation of the Board.////	BADR0 = pci_resource_start(devpriv->pci_dev, 0); 	BADR1 = pci_resource_start(devpriv->pci_dev, 1); 	BADR2 = pci_resource_start(devpriv->pci_dev, 2); 	BADR3 = pci_resource_start(devpriv->pci_dev, 3); 	BADR4 = pci_resource_start(devpriv->pci_dev, 4); 	// reserve io ports	err = 0;//	if(check_mem_region(BADR0, BADR0_SIZE) < 0)//		err+=1;	if(check_region(BADR1, BADR1_SIZE) < 0)		err+=2;	if(check_region(BADR2, BADR2_SIZE) < 0)		err+=4;	if(check_region(BADR3, BADR3_SIZE) < 0)		err+=8;	if(check_region(BADR4, BADR4_SIZE) < 0)		err+=16;	if(err)	{		printk(" I/O port conflict %d\n",err);		return -EIO;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -