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

📄 ii_pci20kc.c

📁 最新rtlinux内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	s->range_table_list = sdp->pci20006.ao_range_list;	return 0;}static int pci20006_insn_read(comedi_device * dev, comedi_subdevice * s,	comedi_insn *insn, lsampl_t *data){	pci20xxx_subdev_private *sdp = s->private;	data[0] = sdp->pci20006.last_data[CR_CHAN(insn->chanspec)];	return 1;}static int pci20006_insn_write(comedi_device * dev, comedi_subdevice * s,	comedi_insn *insn, lsampl_t *data){	pci20xxx_subdev_private *sdp = s->private;	int hi, lo;	unsigned int boarddata;	sdp->pci20006.last_data[CR_CHAN(insn->chanspec)] = data[0];	boarddata = (((unsigned int)data[0]+0x8000) & 0xffff);	/* comedi-data -> board-data */	lo = (boarddata & 0xff);	hi = ((boarddata >> 8) & 0xff);	switch ( CR_CHAN(insn->chanspec)) {	case 0:		writeb(lo, sdp->iobase + PCI20006_LCHAN0);		writeb(hi, sdp->iobase + PCI20006_LCHAN0 + 1);		writeb(0x00, sdp->iobase + PCI20006_STROBE0);		break;	case 1:		writeb(lo, sdp->iobase + PCI20006_LCHAN1);		writeb(hi, sdp->iobase + PCI20006_LCHAN1 + 1);		writeb(0x00, sdp->iobase + PCI20006_STROBE1);		break;	default:		printk(" comedi%d: pci20xxx: ao channel Error!\n", dev->minor);		return -EINVAL;	}	return 1;}/* PCI20341M */static int pci20341_insn_read(comedi_device * dev, comedi_subdevice * s,	comedi_insn *insn, lsampl_t *data);static int pci20341_timebase[] = { 0x00, 0x00, 0x00, 0x04 };static int pci20341_settling_time[] = { 0x58, 0x58, 0x93, 0x99 };static comedi_lrange range_bipolar0_5 = { 1, { BIP_RANGE(0.5) }};static comedi_lrange range_bipolar0_05 = { 1, { BIP_RANGE(0.05) }};static comedi_lrange range_bipolar0_025 = { 1, { BIP_RANGE(0.025) }};static comedi_lrange *pci20341_ranges[] = {	&range_bipolar5,	&range_bipolar0_5,	&range_bipolar0_05,	&range_bipolar0_025,	};static int pci20341_init(comedi_device * dev,comedi_subdevice *s,	int opt0,int opt1){	pci20xxx_subdev_private *sdp = s->private;	int option;		/* options handling */	if(opt0<0 || opt0>3)opt0=0;	sdp->pci20341.timebase = pci20341_timebase[opt0];	sdp->pci20341.settling_time = pci20341_settling_time[opt0];	/* ai subdevice */	s->type = COMEDI_SUBD_AI;	s->subdev_flags = SDF_READABLE;	s->n_chan = PCI20341_CHAN_NR;	s->len_chanlist = PCI20341_SCANLIST;	s->insn_read = pci20341_insn_read;	s->maxdata = 0xffff;	s->range_table = pci20341_ranges[opt0];	option = sdp->pci20341.timebase | PCI20341_REPMODE;	/* depends on gain, trigger, repetition mode */	writeb(PCI20341_INIT, sdp->iobase + PCI20341_CONFIG_REG);			/* initialize Module */	writeb(PCI20341_PACER, sdp->iobase + PCI20341_MOD_STATUS);			/* set Pacer */	writeb(option, sdp->iobase + PCI20341_OPT_REG);					/* option register */	writeb(sdp->pci20341.settling_time, sdp->iobase + PCI20341_SET_TIME_REG);	/* settling time counter */	/* trigger not implemented */	return 0;}static int pci20341_insn_read(comedi_device * dev, comedi_subdevice * s,	comedi_insn *insn, lsampl_t *data){	pci20xxx_subdev_private *sdp = s->private;	unsigned int i = 0, j = 0;	int lo, hi;	unsigned char eoc;		/* end of conversion */	unsigned int clb;		/* channel list byte */	unsigned int boarddata;	writeb(1, sdp->iobase + PCI20341_LCHAN_ADDR_REG);		/* write number of input channels */	clb	= PCI20341_DAISY_CHAIN		| PCI20341_MUX		| (sdp->pci20341.ai_gain << 3)		| CR_CHAN(insn->chanspec); 	writeb(clb, sdp->iobase + PCI20341_CHAN_LIST);	writeb(0x00, sdp->iobase + PCI20341_CC_RESET);		/* reset settling time counter and trigger delay counter */	writeb(0x00, sdp->iobase + PCI20341_CHAN_RESET);	/* generate Pacer */	for (i=0; i < insn->n; i++)	{ 		/* data polling isn't the niciest way to get the data, I know,		 * but there are only 6 cycles (mean) and it is easier than		 * the whole interrupt stuff 	 	 */		j=0;		readb(sdp->iobase + PCI20341_SOFT_PACER);	/* generate Pacer */				eoc = readb(sdp->iobase + PCI20341_STATUS_REG);				while ((eoc < 0x80) && j < 100) {	/* poll Interrupt Flag */			j++;			eoc = readb(sdp->iobase + PCI20341_STATUS_REG);		}		if (j >= 100) {			printk("comedi%d:  pci20xxx: AI interrupt channel %i polling exit !\n", dev->minor, i);			return -EINVAL;		}		lo = readb(sdp->iobase + PCI20341_LDATA);		hi = readb(sdp->iobase + PCI20341_LDATA + 1);		boarddata = lo + 0x100 *  hi;		data[i] = (sampl_t)((boarddata + 0x8000) & 0xffff);	/* board-data -> comedi-data */	}	return i;}/* native DIO */static void pci20xxx_dio_config(comedi_device * dev,comedi_subdevice *s);static int pci20xxx_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data);static int pci20xxx_dio_insn_config(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data);/* initialize pci20xxx_private */static int pci20xxx_dio_init(comedi_device * dev,comedi_subdevice *s){	s->type = COMEDI_SUBD_DIO;	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;	s->n_chan = 32;	s->insn_bits = pci20xxx_dio_insn_bits;	s->insn_config = pci20xxx_dio_insn_config;	s->maxdata = 1;	s->len_chanlist = 32;	s->range_table = &range_digital;	s->io_bits = 0;	/* digital I/O lines default to input on board reset. */	pci20xxx_dio_config(dev,s);	return 0;}static int pci20xxx_dio_insn_config(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data){	int mask,bits;	mask = 1<<CR_CHAN(insn->chanspec);	if(mask&0x000000ff){		bits = 0x000000ff;	}else if(mask & 0x0000ff00){		bits = 0x0000ff00;	}else if(mask & 0x00ff0000){		bits = 0x00ff0000;	}else {		bits = 0xff000000;	}	if(data[0]){		s->io_bits |= bits;	}else{		s->io_bits &= ~bits;	}	pci20xxx_dio_config(dev,s);	return 1;}static int pci20xxx_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,	comedi_insn *insn, lsampl_t *data){	unsigned int mask = data[0];	s->state &= ~mask;	s->state |= (mask&data[1]);	mask &= s->io_bits;	if(mask&0x000000ff)		writeb((s->state>>0)&0xff, dev->iobase + PCI20000_DIO_0 );	if(mask&0x0000ff00)		writeb((s->state>>8)&0xff, dev->iobase + PCI20000_DIO_1 );	if(mask&0x00ff0000)		writeb((s->state>>16)&0xff, dev->iobase + PCI20000_DIO_2 );	if(mask&0xff000000)		writeb((s->state>>24)&0xff, dev->iobase + PCI20000_DIO_3 );	data[1] = readb(dev->iobase + PCI20000_DIO_0 );	data[1] |= readb(dev->iobase + PCI20000_DIO_1 )<<8;	data[1] |= readb(dev->iobase + PCI20000_DIO_2 )<<16;	data[1] |= readb(dev->iobase + PCI20000_DIO_3 )<<24;	return 2;}static void pci20xxx_dio_config(comedi_device * dev,comedi_subdevice *s){	unsigned char control_01;	unsigned char control_23;	unsigned char buffer;	control_01 = readb(dev->iobase + PCI20000_DIO_CONTROL_01);	control_23 = readb(dev->iobase + PCI20000_DIO_CONTROL_23);		buffer = readb(dev->iobase + PCI20000_DIO_BUFFER);			if(s->io_bits & 0x000000ff ){		/* output port 0 */		control_01 &= PCI20000_DIO_EOC;		buffer = (buffer &(~(DIO_BE<<DIO_PS_0)))|(DIO_BO<<DIO_PS_0);	}else{		/* input port 0 */		control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_EIC;		buffer = (buffer &(~(DIO_BI<<DIO_PS_0)));	}	if(s->io_bits & 0x0000ff00 ){		/* output port 1 */		control_01 &= PCI20000_DIO_OOC;		buffer = (buffer &(~(DIO_BE<<DIO_PS_1)))|(DIO_BO<<DIO_PS_1);	}else{		/* input port 1 */		control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_OIC;				buffer = (buffer &(~(DIO_BI<<DIO_PS_1)));	}	if(s->io_bits & 0x00ff0000 ){		/* output port 2 */		control_23 &= PCI20000_DIO_EOC;		buffer = (buffer &(~(DIO_BE<<DIO_PS_2)))|(DIO_BO<<DIO_PS_2);	}else{		/* input port 2 */		control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_EIC;		buffer = (buffer &(~(DIO_BI<<DIO_PS_2)));	}	if(s->io_bits & 0xff000000 ){		/* output port 3 */		control_23 &= PCI20000_DIO_OOC;		buffer = (buffer &(~(DIO_BE<<DIO_PS_3)))|(DIO_BO<<DIO_PS_3);	}else{		/* input port 3 */		control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_OIC;		buffer = (buffer &(~(DIO_BI<<DIO_PS_3)));	}	writeb(control_01, dev->iobase + PCI20000_DIO_CONTROL_01);	writeb(control_23, dev->iobase + PCI20000_DIO_CONTROL_23);		writeb(buffer, dev->iobase + PCI20000_DIO_BUFFER);	}#if 0static void pci20xxx_do(comedi_device * dev, comedi_subdevice * s){	/* XXX if the channel is configured for input, does this	   do bad things? */	/* XXX it would be a good idea to only update the registers	   that _need_ to be updated.  This requires changes to	   comedi, however. */	writeb((s->state>>0)&0xff, dev->iobase + PCI20000_DIO_0 );	writeb((s->state>>8)&0xff, dev->iobase + PCI20000_DIO_1 );	writeb((s->state>>16)&0xff, dev->iobase + PCI20000_DIO_2 );	writeb((s->state>>24)&0xff, dev->iobase + PCI20000_DIO_3 );}static unsigned int pci20xxx_di(comedi_device * dev, comedi_subdevice * s){	/* XXX same note as above */	unsigned int bits;		bits = readb(dev->iobase + PCI20000_DIO_0 );	bits |= readb(dev->iobase + PCI20000_DIO_1 )<<8;	bits |= readb(dev->iobase + PCI20000_DIO_2 )<<16;	bits |= readb(dev->iobase + PCI20000_DIO_3 )<<24;	return bits;}#endifCOMEDI_INITCLEANUP(driver_pci20xxx);

⌨️ 快捷键说明

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