rtlinux-3.2源码

源代码在线查看: poc.c

软件大小: 2711 K
上传用户: guozhongjiesg02
关键词: rtlinux 3.2 源码
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*				    comedi/drivers/poc.c				    Mini-drivers for POC (Piece of Crap) boards				    Copyright (C) 2000 Frank Mori Hess 				    Copyright (C) 2001 David A. Schleef 								    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: poc.o				Description: Generic driver for very simple devices				Device names: dac02				Author: ds				Devices: [Keithley Metrabyte] DAC-02 (dac02), [Advantech] PCL-733 (pcl733),				  PCL-734 (pcl734)				Updated: Sat, 16 Mar 2002 17:34:48 -0800				Status: unknown								This driver is indended to support very simple ISA-based devices,				including:				  dac02 - Keithley DAC-02 analog output board				  pcl733 - Advantech PCL-733				  pcl734 - Advantech PCL-734								Configuration options:				  [0] - I/O port base				*/								#include 								#include 								static int poc_attach(comedi_device *dev,comedi_devconfig *it);				static int poc_detach(comedi_device *dev);				static int readback_insn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);								static int dac02_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);				static int pcl733_insn_bits(comedi_device *dev,comedi_subdevice *s,					comedi_insn *insn,lsampl_t *data);				static int pcl734_insn_bits(comedi_device *dev,comedi_subdevice *s,					comedi_insn *insn,lsampl_t *data);								struct boarddef_struct{					char *name;					int iosize;					int (*setup)(comedi_device *);					int type;					int n_chan;					int n_bits;					int (*winsn)(comedi_device *,comedi_subdevice *,comedi_insn *,lsampl_t *);					int (*rinsn)(comedi_device *,comedi_subdevice *,comedi_insn *,lsampl_t *);					int (*insnbits)(comedi_device *,comedi_subdevice *,comedi_insn *,lsampl_t *);					comedi_lrange* range;				};				static struct boarddef_struct boards[]={					{					name:		"dac02",					iosize:		8,					//setup:		dac02_setup,					type:		COMEDI_SUBD_AO,					n_chan:		2,					n_bits:		12,					winsn:		dac02_ao_winsn,					rinsn:		readback_insn,					range:		&range_unknown,					},					{					name:		"pcl733",					iosize:		4,					type:		COMEDI_SUBD_DI,					n_chan:		32,					n_bits:		1,					insnbits:	pcl733_insn_bits,					range:		&range_digital,					},					{					name:		"pcl734",					iosize:		4,					type:		COMEDI_SUBD_DO,					n_chan:		32,					n_bits:		1,					insnbits:	pcl734_insn_bits,					range:		&range_digital,					},				};				#define n_boards (sizeof(boards)/sizeof(boards[0]))				#define this_board ((struct boarddef_struct *)dev->board_ptr)								static comedi_driver driver_poc=				{					driver_name:	"poc",					module:		THIS_MODULE,					attach:		poc_attach,					detach:		poc_detach,					board_name:	boards,					num_names:	n_boards,					offset:		sizeof(boards[0]),				};								static int poc_attach(comedi_device *dev, comedi_devconfig *it)				{					comedi_subdevice *s;					int iosize, iobase;									iobase = it->options[0];					printk("comedi%d: poc: using %s iobase 0x%x\n", dev->minor,						this_board->name, iobase);									dev->board_name = this_board->name;									if(iobase == 0)					{						printk("io base address required\n");						return -EINVAL;					}									iosize = this_board->iosize;					/* check if io addresses are available */					if(check_region(iobase, iosize) < 0)					{						printk("I/O port conflict: failed to allocate ports 0x%x to 0x%x\n",							iobase, iobase + iosize - 1);						return -EIO;					}					request_region(iobase, iosize, "dac02");					dev->iobase = iobase;									if(alloc_subdevices(dev, 1) < 0)						return -ENOMEM;					if(alloc_private(dev,sizeof(lsampl_t)*this_board->n_chan) < 0)						return -ENOMEM;									/* analog output subdevice */					s=dev->subdevices + 0;					s->type = this_board->type;					s->n_chan = this_board->n_chan;					s->maxdata = (1					s->range_table = this_board->range;					s->insn_write = this_board->winsn;					s->insn_read = this_board->rinsn;					s->insn_bits = this_board->insnbits;					if(s->type==COMEDI_SUBD_AO || s->type==COMEDI_SUBD_DO){						s->subdev_flags = SDF_WRITABLE;					}									return 0;				}								static int poc_detach(comedi_device *dev)				{					/* only free stuff if it has been allocated by _attach */					if(dev->iobase)						release_region(dev->iobase, this_board->iosize);									printk("comedi%d: dac02: remove\n", dev->minor);									return 0;				}								static int readback_insn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)				{					int chan;									chan = CR_CHAN(insn->chanspec);					data[0]=((lsampl_t *)dev->private)[chan];									return 1;				}								/* DAC-02 registers */				#define DAC02_LSB(a)	(2 * a)				#define DAC02_MSB(a)	(2 * a + 1)								static int dac02_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)				{					int temp;					int chan;					int output;									chan = CR_CHAN(insn->chanspec);					((lsampl_t *)dev->private)[chan] = data[0];					output = data[0];				#if wrong					// convert to complementary binary if range is bipolar					if((CR_RANGE(insn->chanspec) & 0x2) == 0)						output = ~output;				#endif					temp = (output 					outb(temp, dev->iobase + DAC02_LSB(chan));					temp = (output >> 4) & 0xff;					outb(temp, dev->iobase + DAC02_MSB(chan));									return 1;				}								static int pcl733_insn_bits(comedi_device *dev,comedi_subdevice *s,					comedi_insn *insn,lsampl_t *data)				{					if(insn->n!=2)return -EINVAL;										data[1] = inb(dev->iobase + 0);					data[1] |= (inb(dev->iobase + 1) 					data[1] |= (inb(dev->iobase + 2) 					data[1] |= (inb(dev->iobase + 3) 									return 2;				}								static int pcl734_insn_bits(comedi_device *dev,comedi_subdevice *s,					comedi_insn *insn,lsampl_t *data)				{					if(insn->n!=2)return -EINVAL;					if(data[0]){						s->state &= ~data[0];						s->state |= (data[0]&data[1]);						if((data[0]>>0)&0xff)							outb((s->state>>0)&0xff, dev->iobase + 0);						if((data[0]>>8)&0xff)							outb((s->state>>8)&0xff, dev->iobase + 1);						if((data[0]>>16)&0xff)							outb((s->state>>16)&0xff, dev->iobase + 2);						if((data[0]>>24)&0xff)							outb((s->state>>24)&0xff, dev->iobase + 3);					}					data[1] = s->state;									return 2;				}								COMEDI_INITCLEANUP(driver_poc);											

相关资源