i2c: octeon: Introduce helper functions for register access
Add helper functions for control, data and status register access. This simplifies the code and makes the purpose of the register access clearer. Signed-off-by: Jan Glauber <jglauber@cavium.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
This commit is contained in:
Родитель
9cb9480e47
Коммит
c57db7098b
|
@ -97,6 +97,11 @@ static void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8 data)
|
|||
} while ((tmp & SW_TWSI_V) != 0);
|
||||
}
|
||||
|
||||
#define octeon_i2c_ctl_write(i2c, val) \
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CTL, val)
|
||||
#define octeon_i2c_data_write(i2c, val) \
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_DATA, val)
|
||||
|
||||
/**
|
||||
* octeon_i2c_reg_read - read lower bits of an I2C core register
|
||||
* @i2c: The struct octeon_i2c
|
||||
|
@ -118,6 +123,13 @@ static u8 octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg)
|
|||
return tmp & 0xFF;
|
||||
}
|
||||
|
||||
#define octeon_i2c_ctl_read(i2c) \
|
||||
octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL)
|
||||
#define octeon_i2c_data_read(i2c) \
|
||||
octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA)
|
||||
#define octeon_i2c_stat_read(i2c) \
|
||||
octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT)
|
||||
|
||||
/**
|
||||
* octeon_i2c_write_int - write the TWSI_INT register
|
||||
* @i2c: The struct octeon_i2c
|
||||
|
@ -189,7 +201,7 @@ static irqreturn_t octeon_i2c_isr(int irq, void *dev_id)
|
|||
|
||||
static int octeon_i2c_test_iflg(struct octeon_i2c *i2c)
|
||||
{
|
||||
return (octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL) & TWSI_CTL_IFLG) != 0;
|
||||
return (octeon_i2c_ctl_read(i2c) & TWSI_CTL_IFLG) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -262,14 +274,14 @@ static int octeon_i2c_init_lowlevel(struct octeon_i2c *i2c)
|
|||
int tries;
|
||||
|
||||
/* disable high level controller, enable bus access */
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB);
|
||||
octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
|
||||
|
||||
/* reset controller */
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_RST, 0);
|
||||
|
||||
for (tries = 10; tries; tries--) {
|
||||
udelay(1);
|
||||
status = octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT);
|
||||
status = octeon_i2c_stat_read(i2c);
|
||||
if (status == STAT_IDLE)
|
||||
return 0;
|
||||
}
|
||||
|
@ -288,27 +300,25 @@ static int octeon_i2c_start(struct octeon_i2c *i2c)
|
|||
int result;
|
||||
u8 data;
|
||||
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CTL,
|
||||
TWSI_CTL_ENAB | TWSI_CTL_STA);
|
||||
octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB | TWSI_CTL_STA);
|
||||
|
||||
result = octeon_i2c_wait(i2c);
|
||||
if (result) {
|
||||
if (octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT) == STAT_IDLE) {
|
||||
if (octeon_i2c_stat_read(i2c) == STAT_IDLE) {
|
||||
/*
|
||||
* Controller refused to send start flag May
|
||||
* be a client is holding SDA low - let's try
|
||||
* to free it.
|
||||
*/
|
||||
octeon_i2c_unblock(i2c);
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CTL,
|
||||
TWSI_CTL_ENAB | TWSI_CTL_STA);
|
||||
octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB | TWSI_CTL_STA);
|
||||
result = octeon_i2c_wait(i2c);
|
||||
}
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
data = octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT);
|
||||
data = octeon_i2c_stat_read(i2c);
|
||||
if ((data != STAT_START) && (data != STAT_RSTART)) {
|
||||
dev_err(i2c->dev, "%s: bad status (0x%x)\n", __func__, data);
|
||||
return -EIO;
|
||||
|
@ -320,8 +330,7 @@ static int octeon_i2c_start(struct octeon_i2c *i2c)
|
|||
/* send STOP to the bus */
|
||||
static void octeon_i2c_stop(struct octeon_i2c *i2c)
|
||||
{
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CTL,
|
||||
TWSI_CTL_ENAB | TWSI_CTL_STP);
|
||||
octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB | TWSI_CTL_STP);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -345,15 +354,15 @@ static int octeon_i2c_write(struct octeon_i2c *i2c, int target,
|
|||
if (result)
|
||||
return result;
|
||||
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_DATA, target << 1);
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB);
|
||||
octeon_i2c_data_write(i2c, target << 1);
|
||||
octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
|
||||
|
||||
result = octeon_i2c_wait(i2c);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
tmp = octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT);
|
||||
tmp = octeon_i2c_stat_read(i2c);
|
||||
|
||||
if ((tmp != STAT_TXADDR_ACK) && (tmp != STAT_TXDATA_ACK)) {
|
||||
dev_err(i2c->dev,
|
||||
|
@ -362,8 +371,8 @@ static int octeon_i2c_write(struct octeon_i2c *i2c, int target,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_DATA, data[i]);
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB);
|
||||
octeon_i2c_data_write(i2c, data[i]);
|
||||
octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
|
||||
|
||||
result = octeon_i2c_wait(i2c);
|
||||
if (result)
|
||||
|
@ -398,16 +407,15 @@ static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
|
|||
if (result)
|
||||
return result;
|
||||
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_DATA, (target << 1) | 1);
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB);
|
||||
octeon_i2c_data_write(i2c, (target << 1) | 1);
|
||||
octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
|
||||
|
||||
result = octeon_i2c_wait(i2c);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
tmp = octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT);
|
||||
|
||||
tmp = octeon_i2c_stat_read(i2c);
|
||||
if ((tmp != STAT_RXDATA_ACK) && (tmp != STAT_RXADDR_ACK)) {
|
||||
dev_err(i2c->dev,
|
||||
"%s: bad status before read (0x%x)\n",
|
||||
|
@ -416,17 +424,15 @@ static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
|
|||
}
|
||||
|
||||
if (i + 1 < length)
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CTL,
|
||||
TWSI_CTL_ENAB | TWSI_CTL_AAK);
|
||||
octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB | TWSI_CTL_AAK);
|
||||
else
|
||||
octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CTL,
|
||||
TWSI_CTL_ENAB);
|
||||
octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
|
||||
|
||||
result = octeon_i2c_wait(i2c);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
data[i] = octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA);
|
||||
data[i] = octeon_i2c_data_read(i2c);
|
||||
if (recv_len && i == 0) {
|
||||
if (data[i] > I2C_SMBUS_BLOCK_MAX + 1) {
|
||||
dev_err(i2c->dev,
|
||||
|
|
Загрузка…
Ссылка в новой задаче