|
|
@ -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(); |
|
|
|