Browse Source

ls2k i2c add bus conflict process.

Change-Id: Id490ff6587bfac147b922c40a4016e4f00a020cf
Signed-off-by: Chong Qiao <qiaochong@loongson.cn>
master
Chong Qiao 3 years ago
parent
commit
5229d86373
  1. 36
      Targets/LS2K/dev/i2c.c

36
Targets/LS2K/dev/i2c.c

@ -47,6 +47,12 @@ struct i2c_msg {
#define ls2k_i2c_debug(fmt, args...) //printf(fmt, ##args)
#define pr_info printf
static void ls2k_i2c_reinit()
{
ls2k_i2c_writeb(0, LS2K_I2C_CTR_REG);
ls2k_i2c_writeb(0x80, LS2K_I2C_CTR_REG);
ls2k_i2c_writeb(CR_IACK, LS2K_I2C_CR_REG);
}
static void ls2k_i2c_stop(void)
{
@ -59,18 +65,24 @@ again:
static int ls2k_i2c_start(int dev_addr, int flags)
{
int retry = 5;
int retry = 5, sr;
unsigned char addr = (dev_addr & 0x7f) << 1;
addr |= (flags & I2C_M_RD)? 1:0;
start:
delay(1000);
ls2k_i2c_writeb(addr, LS2K_I2C_TXR_REG);
ls2k_i2c_debug("%s <line%d>: i2c device address: 0x%x\n",
__func__, __LINE__, addr);
ls2k_i2c_writeb((CR_START | CR_WRITE), LS2K_I2C_CR_REG);
while (ls2k_i2c_readb(LS2K_I2C_SR_REG) & SR_TIP) ;
while (((sr = ls2k_i2c_readb(LS2K_I2C_SR_REG)) & (SR_TIP|SR_AL)) == SR_TIP);
if(sr & SR_AL) {
ls2k_i2c_reinit();
ls2k_i2c_stop();
goto start;
}
if (ls2k_i2c_readb(LS2K_I2C_SR_REG) & SR_NOACK) {
if (sr & SR_NOACK) {
ls2k_i2c_stop();
while (retry--)
goto start;
@ -82,13 +94,17 @@ start:
static int ls2k_i2c_read(unsigned char *buf, int count)
{
int i;
int i, sr;
for (i = 0; i < count; i++) {
ls2k_i2c_writeb((i == count - 1)?
(CR_READ | CR_ACK) : CR_READ,
LS2K_I2C_CR_REG);
while (ls2k_i2c_readb(LS2K_I2C_SR_REG) & SR_TIP) ;
while (((sr = ls2k_i2c_readb(LS2K_I2C_SR_REG)) & (SR_TIP|SR_AL)) == SR_TIP);
if(sr & SR_AL) {
ls2k_i2c_reinit();
break;
}
buf[i] = ls2k_i2c_readb(LS2K_I2C_RXR_REG);
ls2k_i2c_debug("%s <line%d>: read buf[%d] <= %02x\n",
__func__, __LINE__, i, buf[i]);
@ -99,16 +115,20 @@ static int ls2k_i2c_read(unsigned char *buf, int count)
static int ls2k_i2c_write(unsigned char *buf, int count)
{
int i;
int i, sr;
for (i = 0; i < count; i++) {
ls2k_i2c_writeb(buf[i], LS2K_I2C_TXR_REG);
ls2k_i2c_debug("%s <line%d>: write buf[%d] => %02x\n",
__func__, __LINE__, i, buf[i]);
ls2k_i2c_writeb(CR_WRITE, LS2K_I2C_CR_REG);
while (ls2k_i2c_readb(LS2K_I2C_SR_REG) & SR_TIP) ;
while (((sr = ls2k_i2c_readb(LS2K_I2C_SR_REG)) & (SR_TIP|SR_AL)) == SR_TIP);
if (sr & SR_AL) {
ls2k_i2c_reinit();
break;
}
if (ls2k_i2c_readb(LS2K_I2C_SR_REG) & SR_NOACK) {
if (sr & SR_NOACK) {
ls2k_i2c_debug("%s <line%d>: device no ack\n",
__func__, __LINE__);
ls2k_i2c_stop();

Loading…
Cancel
Save