diff options
| -rw-r--r-- | README | 7 | ||||
| -rw-r--r-- | cpu/mpc5xxx/i2c.c | 49 | ||||
| -rw-r--r-- | include/configs/galaxy5200.h | 1 | 
3 files changed, 57 insertions, 0 deletions
@@ -1366,6 +1366,13 @@ The following options need to be configured:  		therefore be cleared to 0 (See, eg, MPC823e User's Manual  		p.16-473). So, set CONFIG_SYS_I2C_SLAVE to 0. +		CONFIG_SYS_I2C_INIT_MPC5XXX + +		When a board is reset during an i2c bus transfer +		chips might think that the current transfer is still +		in progress.  Reset the slave devices by sending start +		commands until the slave device responds. +  		That's all that's required for CONFIG_HARD_I2C.  		If you use the software i2c interface (CONFIG_SOFT_I2C) diff --git a/cpu/mpc5xxx/i2c.c b/cpu/mpc5xxx/i2c.c index 23419324b..4f7f71632 100644 --- a/cpu/mpc5xxx/i2c.c +++ b/cpu/mpc5xxx/i2c.c @@ -207,6 +207,52 @@ static int receive_bytes(uchar chip, char *buf, int len)  	return 0;  } +#if defined(CONFIG_SYS_I2C_INIT_MPC5XXX) + +#define FDR510(x) (u8) (((x & 0x20) >> 3) | (x & 0x3)) +#define FDR432(x) (u8) ((x & 0x1C) >> 2) +/* + * Reset any i2c devices that may have been interrupted during a system reset. + * Normally this would be accomplished by clocking the line until SCL and SDA + * are released and then sending a start condtiion (From an Atmel datasheet). + * There is no direct access to the i2c pins so instead create start commands + * through the i2c interface.  Send a start command then delay for the SDA Hold + * time, repeat this by disabling/enabling the bus a total of 9 times. + */ +static void send_reset(void) +{ +	struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE; +	int i; +	u32 delay; +	u8 fdr; +	int SDA_Tap[] = { 3, 3, 4, 4, 1, 1, 2, 2}; +	struct mpc5xxx_i2c_tap scltap[] = { +		{4, 1}, +		{4, 2}, +		{6, 4}, +		{6, 8}, +		{14, 16}, +		{30, 32}, +		{62, 64}, +		{126, 128} +	}; + +	fdr = (u8)mpc_reg_in(®s->mfdr); + +	delay = scltap[FDR432(fdr)].scl2tap + ((SDA_Tap[FDR510(fdr)] - 1) * \ +		scltap[FDR432(fdr)].tap2tap) + 3; + +	for (i = 0; i < 9; i++) { +		mpc_reg_out(®s->mcr, I2C_EN|I2C_STA|I2C_TX, I2C_INIT_MASK); +		udelay(delay); +		mpc_reg_out(®s->mcr, 0, I2C_INIT_MASK); +		udelay(delay); +	} + +	mpc_reg_out(®s->mcr, I2C_EN, I2C_INIT_MASK); +} +#endif /* CONFIG_SYS_I2c_INIT_MPC5XXX */ +  /**************** I2C API ****************/  void i2c_init(int speed, int saddr) @@ -225,6 +271,9 @@ void i2c_init(int speed, int saddr)  	mpc_reg_out(®s->mcr, I2C_EN, I2C_INIT_MASK);  	mpc_reg_out(®s->msr, 0, I2C_IF); +#if defined(CONFIG_SYS_I2C_INIT_MPC5XXX) +	send_reset(); +#endif  	return;  } diff --git a/include/configs/galaxy5200.h b/include/configs/galaxy5200.h index a5b5a03a9..f4b520d39 100644 --- a/include/configs/galaxy5200.h +++ b/include/configs/galaxy5200.h @@ -110,6 +110,7 @@  #define CONFIG_SYS_I2C_MODULE 2		/* Select I2C module #1 or #2 */  #define CONFIG_SYS_I2C_SPEED 100000	/* 100 kHz */  #define CONFIG_SYS_I2C_SLAVE 0x7F +#define CONFIG_SYS_I2C_INIT_MPC5XXX	/* Reset devices on i2c bus */  /*   * EEPROM CAT24WC32 configuration  |