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

📄 i2c-algo-pcf.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			       "error - no ack.\n", i2c_adap->name);			return -EREMOTEIO; /* got a better one ?? */		}#endif	}	i2c_stop(adap);	return (wrcount);}static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count){	int rdcount=0, i, status, timeout, dummy=1;	struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;    	for (i=0; i<count; ++i) {		buf[rdcount] = i2c_inb(adap);		if (dummy) {			dummy = 0;		} else {			rdcount++;		}		timeout = wait_for_pin(adap, &status);		if (timeout) {			i2c_stop(adap);			printk("i2c-algo-pcf.o: i2c_read: "			       "i2c_inb timed out.\n");			return (-1);		}#ifndef STUB_I2C		if (status & I2C_PCF_LRB) {			i2c_stop(adap);			printk("i2c-algo-pcf.o: i2c_read: i2c_inb, No ack.\n");			return (-1);		}#endif	}	set_pcf(adap, 1, I2C_PCF_ESO);	buf[rdcount] = i2c_inb(adap);	if (dummy) {		dummy = 0;	} else {		rdcount++;	}	timeout = wait_for_pin(adap, &status);	if (timeout) {		i2c_stop(adap);		printk("i2c-algo-pcf.o: i2c_read: i2c_inb timed out.\n");		return (-1);	}    	i2c_stop(adap);	/* Read final byte from S0 register */	buf[rdcount++] = i2c_inb(adap);	return (rdcount);}static inline int pcf_doAddress(struct i2c_algo_pcf_data *adap,                                struct i2c_msg *msg, int retries) {	unsigned short flags = msg->flags;	unsigned char addr;	int ret;	if ( (flags & I2C_M_TEN)  ) { 		/* a ten bit address */		addr = 0xf0 | (( msg->addr >> 7) & 0x03);		DEB2(printk("addr0: %d\n",addr));		/* try extended address code...*/		ret = try_address(adap, addr, retries);		if (ret!=1) {			printk("died at extended address code.\n");			return -EREMOTEIO;		}		/* the remaining 8 bit address */		i2c_outb(adap,msg->addr & 0x7f);/* Status check comes here */		if (ret != 1) {			printk("died at 2nd address code.\n");			return -EREMOTEIO;		}		if ( flags & I2C_M_RD ) {			i2c_repstart(adap);			/* okay, now switch into reading mode */			addr |= 0x01;			ret = try_address(adap, addr, retries);			if (ret!=1) {				printk("died at extended address code.\n");				return -EREMOTEIO;			}		}	} else {		/* normal 7bit address	*/		addr = ( msg->addr << 1 );		if (flags & I2C_M_RD )			addr |= 1;		if (flags & I2C_M_REV_DIR_ADDR )			addr ^= 1;		i2c_outb(adap, addr);	}	return 0;}static int pcf_xfer(struct i2c_adapter *i2c_adap,		    struct i2c_msg msgs[], 		    int num){	struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;	struct i2c_msg *pmsg;	int i = 0;	int ret, timeout, status;    	pmsg = &msgs[i];    	/* Send address here if Read */	if (pmsg->flags & I2C_M_RD) {		ret = pcf_doAddress(adap, pmsg, i2c_adap->retries);	}    	/* Check for bus busy */	timeout = wait_for_bb(adap);	if (timeout) {		DEB2(printk("i2c-algo-pcf.o: "		            "Timeout waiting for BB in pcf_xfer\n");)		return -EIO;	}    	/* Send address here if Write */	if (!(pmsg->flags & I2C_M_RD)) {		ret = pcf_doAddress(adap, pmsg, i2c_adap->retries);	}	/* Send START */	i2c_start(adap);    	/* Wait for PIN (pending interrupt NOT) */	timeout = wait_for_pin(adap, &status);	if (timeout) {		i2c_stop(adap);		DEB2(printk("i2c-algo-pcf.o: Timeout waiting "		            "for PIN(1) in pcf_xfer\n");)		return (-EREMOTEIO);	}    #ifndef STUB_I2C	/* Check LRB (last rcvd bit - slave ack) */	if (status & I2C_PCF_LRB) {		i2c_stop(adap);		DEB2(printk("i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)		return (-EREMOTEIO);	}#endif    	DEB3(printk("i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",	            i, msgs[i].addr, msgs[i].flags, msgs[i].len);)    	/* Read */	if (pmsg->flags & I2C_M_RD) {        		/* read bytes into buffer*/		ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len);        		if (ret != pmsg->len) {			DEB2(printk("i2c-algo-pcf.o: fail: "			            "only read %d bytes.\n",ret));		} else {			DEB2(printk("i2c-algo-pcf.o: read %d bytes.\n",ret));		}	} else { /* Write */                /* Write bytes from buffer */		ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len);        		if (ret != pmsg->len) {			DEB2(printk("i2c-algo-pcf.o: fail: "			            "only wrote %d bytes.\n",ret));		} else {			DEB2(printk("i2c-algo-pcf.o: wrote %d bytes.\n",ret));		}	}	return (num);}static int algo_control(struct i2c_adapter *adapter, 	unsigned int cmd, unsigned long arg){	return 0;}static u32 pcf_func(struct i2c_adapter *adap){	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 	       I2C_FUNC_PROTOCOL_MANGLING; }/* -----exported algorithm data: -------------------------------------	*/static struct i2c_algorithm pcf_algo = {	"PCF8584 algorithm",	I2C_ALGO_PCF,	pcf_xfer,	NULL,	NULL,				/* slave_xmit		*/	NULL,				/* slave_recv		*/	algo_control,			/* ioctl		*/	pcf_func,			/* functionality	*/};/*  * registering functions to load algorithms at runtime  */int i2c_pcf_add_bus(struct i2c_adapter *adap){	int i, status;	struct i2c_algo_pcf_data *pcf_adap = adap->algo_data;	if (pcf_test) {		int ret = test_bus(pcf_adap, adap->name);		if (ret<0)			return -ENODEV;	}	DEB2(printk("i2c-algo-pcf.o: hw routines for %s registered.\n",	            adap->name));	/* register new adapter to i2c module... */	adap->id |= pcf_algo.id;	adap->algo = &pcf_algo;	adap->timeout = 100;	/* default values, should	*/	adap->retries = 3;		/* be replaced by defines	*/#ifdef MODULE	MOD_INC_USE_COUNT;#endif	i2c_add_adapter(adap);	pcf_init_8584(pcf_adap);	/* scan bus */	if (pcf_scan) {		printk(KERN_INFO " i2c-algo-pcf.o: scanning bus %s.\n",		       adap->name);		for (i = 0x00; i < 0xff; i+=2) {			i2c_outb(pcf_adap, i);			i2c_start(pcf_adap);			if ((wait_for_pin(pcf_adap, &status) >= 0) && 			    ((status & I2C_PCF_LRB) == 0)) { 				printk("(%02x)",i>>1); 			} else {				printk("."); 			}			i2c_stop(pcf_adap);			udelay(pcf_adap->udelay);		}		printk("\n");	}	return 0;}int i2c_pcf_del_bus(struct i2c_adapter *adap){	int res;	if ((res = i2c_del_adapter(adap)) < 0)		return res;	DEB2(printk("i2c-algo-pcf.o: adapter unregistered: %s\n",adap->name));#ifdef MODULE	MOD_DEC_USE_COUNT;#endif	return 0;}int __init i2c_algo_pcf_init (void){	printk("i2c-algo-pcf.o: i2c pcf8584 algorithm module\n");	return 0;}EXPORT_SYMBOL(i2c_pcf_add_bus);EXPORT_SYMBOL(i2c_pcf_del_bus);#ifdef MODULEMODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");MODULE_PARM(pcf_test, "i");MODULE_PARM(pcf_scan, "i");MODULE_PARM(i2c_debug,"i");MODULE_PARM_DESC(pcf_test, "Test if the I2C bus is available");MODULE_PARM_DESC(pcf_scan, "Scan for active chips on the bus");MODULE_PARM_DESC(i2c_debug,        "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");int init_module(void) {	return i2c_algo_pcf_init();}void cleanup_module(void) {}#endif

⌨️ 快捷键说明

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