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

📄 iic.c

📁 优龙2410linux2.6.8内核源代码
💻 C
字号:
/* Minimal support functions to read configuration from IIC EEPROMS * on MPC8xx boards.  Originally written for RPGC RPX-Lite. * Dan Malek (dmalek@jlc.net). */#include <linux/types.h>#include <asm/uaccess.h>#include <asm/mpc8xx.h>#include <asm/commproc.h>/* IIC functions. * These are just the basic master read/write operations so we can * examine serial EEPROM. */void	iic_read(uint devaddr, u_char *buf, uint offset, uint count);static	int	iic_init_done;static voidiic_init(void){	volatile iic_t *iip;	volatile i2c8xx_t *i2c;	volatile cpm8xx_t	*cp;	volatile immap_t	*immap;	uint	dpaddr;	immap = (immap_t *)IMAP_ADDR;	cp = (cpm8xx_t *)&(immap->im_cpm);	/* Reset the CPM.  This is necessary on the 860 processors	 * that may have started the SCC1 ethernet without relocating	 * the IIC.	 * This also stops the Ethernet in case we were loaded by a	 * BOOTP rom monitor.	 */	cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);	/* Wait for it.	*/	while (cp->cp_cpcr & (CPM_CR_RST | CPM_CR_FLG));	/* Remove any microcode patches.  We will install our own	 * later.	 */	cp->cp_cpmcr1 = 0;	cp->cp_cpmcr2 = 0;	cp->cp_cpmcr3 = 0;	cp->cp_cpmcr4 = 0;	cp->cp_rccr = 0;	iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];	i2c = (i2c8xx_t *)&(immap->im_i2c);	/* Initialize Port B IIC pins.	*/	cp->cp_pbpar |= 0x00000030;	cp->cp_pbdir |= 0x00000030;	cp->cp_pbodr |= 0x00000030;	/* Initialize the parameter ram.	*/	/* Allocate space for a two transmit and one receive buffer	 * descriptor in the DP ram.	 * For now, this address seems OK, but it may have to	 * change with newer versions of the firmware.	 */	dpaddr = 0x0840;	/* Set up the IIC parameters in the parameter ram.	*/	iip->iic_tbase = dpaddr;	iip->iic_rbase = dpaddr + (2 * sizeof(cbd_t));	iip->iic_tfcr = SMC_EB;	iip->iic_rfcr = SMC_EB;	/* This should really be done by the reader/writer.	*/	iip->iic_mrblr = 128;	/* Initialize Tx/Rx parameters.	*/	cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;	while (cp->cp_cpcr & CPM_CR_FLG);	/* Select an arbitrary address.  Just make sure it is unique.	*/	i2c->i2c_i2add = 0x34;	/* Make clock run maximum slow.	*/	i2c->i2c_i2brg = 7;	/* Disable interrupts.	*/	i2c->i2c_i2cmr = 0;	i2c->i2c_i2cer = 0xff;	/* Enable SDMA.	*/	immap->im_siu_conf.sc_sdcr = 1;	iic_init_done = 1;}/* Read from IIC. * Caller provides device address, memory buffer, and byte count. */static	u_char	iitemp[32];voidiic_read(uint devaddr, u_char *buf, uint offset, uint count){	volatile iic_t		*iip;	volatile i2c8xx_t	*i2c;	volatile cbd_t		*tbdf, *rbdf;	volatile cpm8xx_t	*cp;	volatile immap_t	*immap;	u_char			*tb;	uint			temp;	/* If the interface has not been initialized, do that now.	*/	if (!iic_init_done)		iic_init();	immap = (immap_t *)IMAP_ADDR;	cp = (cpm8xx_t *)&(immap->im_cpm);	iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];	i2c = (i2c8xx_t *)&(immap->im_i2c);	tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];	rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];	/* Send a "dummy write" operation.  This is a write request with	 * only the offset sent, followed by another start condition.	 * This will ensure we start reading from the first location	 * of the EEPROM.	 */	tb = iitemp;	tb = (u_char *)(((uint)tb + 15) & ~15);	tbdf->cbd_bufaddr = (int)tb;	*tb = devaddr & 0xfe;	/* Device address */	*(tb+1) = offset;		/* Offset */	tbdf->cbd_datlen = 2;		/* Length */	tbdf->cbd_sc =	      BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;	i2c->i2c_i2mod = 1;	/* Enable */	i2c->i2c_i2cer = 0xff;	i2c->i2c_i2com = 0x81;	/* Start master */	/* Wait for IIC transfer.	*/#if 0	while ((i2c->i2c_i2cer & 3) == 0);	if (tbdf->cbd_sc & BD_SC_READY)		printf("IIC ra complete but tbuf ready\n");#else	temp = 10000000;	while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))		temp--;#if 0	/* We can't do this...there is no serial port yet!	*/	if (temp == 0) {		printf("Timeout reading EEPROM\n");		return;	}#endif#endif		/* Chip errata, clear enable.	*/	i2c->i2c_i2mod = 0;	/* To read, we need an empty buffer of the proper length.	 * All that is used is the first byte for address, the remainder	 * is just used for timing (and doesn't really have to exist).	 */	tbdf->cbd_bufaddr = (int)tb;	*tb = devaddr | 1;	/* Device address */	rbdf->cbd_bufaddr = (uint)buf;		/* Desination buffer */	tbdf->cbd_datlen = rbdf->cbd_datlen = count + 1;	/* Length */	tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;	rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;	/* Chip bug, set enable here.	*/	i2c->i2c_i2mod = 1;	/* Enable */	i2c->i2c_i2cer = 0xff;	i2c->i2c_i2com = 0x81;	/* Start master */	/* Wait for IIC transfer.	*/#if 0	while ((i2c->i2c_i2cer & 1) == 0);	if (rbdf->cbd_sc & BD_SC_EMPTY)		printf("IIC read complete but rbuf empty\n");#else	temp = 10000000;	while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))		temp--;#endif		/* Chip errata, clear enable.	*/	i2c->i2c_i2mod = 0;}

⌨️ 快捷键说明

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