|
|
|
@ -218,7 +218,7 @@ void i2c_imx_stop(void) |
|
|
|
|
* Send start signal, chip address and |
|
|
|
|
* write register address |
|
|
|
|
*/ |
|
|
|
|
static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs, |
|
|
|
|
static int i2c_init_transfer_(struct mxc_i2c_regs *i2c_regs, |
|
|
|
|
uchar chip, uint addr, int alen) |
|
|
|
|
{ |
|
|
|
|
unsigned int temp; |
|
|
|
@ -235,7 +235,7 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs, |
|
|
|
|
writeb(0, &i2c_regs->i2sr); |
|
|
|
|
ret = wait_for_sr_state(i2c_regs, ST_BUS_IDLE); |
|
|
|
|
if (ret < 0) |
|
|
|
|
goto exit; |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
/* Start I2C transaction */ |
|
|
|
|
temp = readb(&i2c_regs->i2cr); |
|
|
|
@ -244,7 +244,7 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs, |
|
|
|
|
|
|
|
|
|
ret = wait_for_sr_state(i2c_regs, ST_BUS_BUSY); |
|
|
|
|
if (ret < 0) |
|
|
|
|
goto exit; |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
temp |= I2CR_MTX | I2CR_TX_NO_AK; |
|
|
|
|
writeb(temp, &i2c_regs->i2cr); |
|
|
|
@ -252,18 +252,36 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs, |
|
|
|
|
/* write slave address */ |
|
|
|
|
ret = tx_byte(i2c_regs, chip << 1); |
|
|
|
|
if (ret < 0) |
|
|
|
|
goto exit; |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
while (alen--) { |
|
|
|
|
ret = tx_byte(i2c_regs, (addr >> (alen * 8)) & 0xff); |
|
|
|
|
if (ret < 0) |
|
|
|
|
goto exit; |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
exit: |
|
|
|
|
i2c_imx_stop(); |
|
|
|
|
/* Disable I2C controller */ |
|
|
|
|
writeb(0, &i2c_regs->i2cr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs, |
|
|
|
|
uchar chip, uint addr, int alen) |
|
|
|
|
{ |
|
|
|
|
int retry; |
|
|
|
|
int ret; |
|
|
|
|
for (retry = 0; retry < 3; retry++) { |
|
|
|
|
ret = i2c_init_transfer_(i2c_regs, chip, addr, alen); |
|
|
|
|
if (ret >= 0) |
|
|
|
|
return 0; |
|
|
|
|
i2c_imx_stop(); |
|
|
|
|
if (ret == -ENODEV) |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
printf("%s: failed for chip 0x%x retry=%d\n", __func__, chip, |
|
|
|
|
retry); |
|
|
|
|
if (ret != -ERESTART) |
|
|
|
|
writeb(0, &i2c_regs->i2cr); /* Disable controller */ |
|
|
|
|
udelay(100); |
|
|
|
|
} |
|
|
|
|
printf("%s: give up i2c_regs=%p\n", __func__, i2c_regs); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|