driver: i2c: npcx: simplify smb bank registers with union
For NPCX SMB/I2C SMB modules in FIFO mode, the registers include: * Common registers, offset 0x00-0x0f, accessible regardless of the value of BNK_SEL * Bank 0 registers, offset 0x10-0x1e, accessible if BNK_SEL is set to 0 * Bank 1 registers, offset 0x10-0x1e, accessible if BNK_SEL is set to 1 In the current driver, it uses two structures, `smb_reg` and `smb_fifo_reg`, to access `Common + Bank 0` and `Common + Bank 1` registers. But It might be easy to misunderstand that they are two different modules. This CL tries to simplify this by the following steps: 1. Use `union` to combine `Bank 0/1` registers in the same structure. 2. Remove `smb_fifo_reg`. We needn't use two structures to present SMB registers. Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
This commit is contained in:
parent
1037348b7b
commit
b1214ead19
3 changed files with 91 additions and 120 deletions
|
@ -161,9 +161,6 @@ struct i2c_ctrl_data {
|
|||
#define HAL_I2C_INSTANCE(dev) \
|
||||
((struct smb_reg *)((const struct i2c_ctrl_config *)(dev)->config)->base)
|
||||
|
||||
#define HAL_I2C_FIFO_INSTANCE(dev) \
|
||||
((struct smb_fifo_reg *)((const struct i2c_ctrl_config *)(dev)->config)->base)
|
||||
|
||||
/* Recommended I2C timing values are based on 15 MHz */
|
||||
static const struct npcx_i2c_timing_cfg npcx_15m_speed_confs[] = {
|
||||
[NPCX_I2C_BUS_SPEED_100KHZ] = {.HLDT = 15, .k1 = 76, .k2 = 0},
|
||||
|
@ -180,23 +177,23 @@ static const struct npcx_i2c_timing_cfg npcx_20m_speed_confs[] = {
|
|||
/* I2C controller inline functions access shared registers */
|
||||
static inline void i2c_ctrl_start(const struct device *dev)
|
||||
{
|
||||
struct smb_fifo_reg *const inst_fifo = HAL_I2C_FIFO_INSTANCE(dev);
|
||||
struct smb_reg *const inst = HAL_I2C_INSTANCE(dev);
|
||||
|
||||
inst_fifo->SMBCTL1 |= BIT(NPCX_SMBCTL1_START);
|
||||
inst->SMBCTL1 |= BIT(NPCX_SMBCTL1_START);
|
||||
}
|
||||
|
||||
static inline void i2c_ctrl_stop(const struct device *dev)
|
||||
{
|
||||
struct smb_fifo_reg *const inst_fifo = HAL_I2C_FIFO_INSTANCE(dev);
|
||||
struct smb_reg *const inst = HAL_I2C_INSTANCE(dev);
|
||||
|
||||
inst_fifo->SMBCTL1 |= BIT(NPCX_SMBCTL1_STOP);
|
||||
inst->SMBCTL1 |= BIT(NPCX_SMBCTL1_STOP);
|
||||
}
|
||||
|
||||
static inline int i2c_ctrl_bus_busy(const struct device *dev)
|
||||
{
|
||||
struct smb_fifo_reg *const inst_fifo = HAL_I2C_FIFO_INSTANCE(dev);
|
||||
struct smb_reg *const inst = HAL_I2C_INSTANCE(dev);
|
||||
|
||||
return IS_BIT_SET(inst_fifo->SMBCST, NPCX_SMBCST_BB);
|
||||
return IS_BIT_SET(inst->SMBCST, NPCX_SMBCST_BB);
|
||||
}
|
||||
|
||||
static inline void i2c_ctrl_bank_sel(const struct device *dev, int bank)
|
||||
|
@ -282,54 +279,54 @@ static inline void i2c_ctrl_norm_free_sda(const struct device *dev)
|
|||
/* I2C controller inline functions access registers in 'FIFO' bank */
|
||||
static inline void i2c_ctrl_fifo_write(const struct device *dev, uint8_t data)
|
||||
{
|
||||
struct smb_fifo_reg *const inst_fifo = HAL_I2C_FIFO_INSTANCE(dev);
|
||||
struct smb_reg *const inst = HAL_I2C_INSTANCE(dev);
|
||||
|
||||
inst_fifo->SMBSDA = data;
|
||||
inst->SMBSDA = data;
|
||||
}
|
||||
|
||||
static inline uint8_t i2c_ctrl_fifo_read(const struct device *dev)
|
||||
{
|
||||
struct smb_fifo_reg *const inst_fifo = HAL_I2C_FIFO_INSTANCE(dev);
|
||||
struct smb_reg *const inst = HAL_I2C_INSTANCE(dev);
|
||||
|
||||
return inst_fifo->SMBSDA;
|
||||
return inst->SMBSDA;
|
||||
}
|
||||
|
||||
static inline int i2c_ctrl_fifo_tx_avail(const struct device *dev)
|
||||
{
|
||||
struct smb_fifo_reg *const inst_fifo = HAL_I2C_FIFO_INSTANCE(dev);
|
||||
struct smb_reg *const inst = HAL_I2C_INSTANCE(dev);
|
||||
|
||||
return NPCX_I2C_FIFO_MAX_SIZE - (inst_fifo->SMBTXF_STS & 0x3f);
|
||||
return NPCX_I2C_FIFO_MAX_SIZE - (inst->SMBTXF_STS & 0x3f);
|
||||
}
|
||||
|
||||
static inline int i2c_ctrl_fifo_rx_occupied(const struct device *dev)
|
||||
{
|
||||
struct smb_fifo_reg *const inst_fifo = HAL_I2C_FIFO_INSTANCE(dev);
|
||||
struct smb_reg *const inst = HAL_I2C_INSTANCE(dev);
|
||||
|
||||
return inst_fifo->SMBRXF_STS & 0x3f;
|
||||
return inst->SMBRXF_STS & 0x3f;
|
||||
}
|
||||
|
||||
static inline void i2c_ctrl_fifo_rx_setup_threshold_nack(
|
||||
const struct device *dev, int threshold, int last)
|
||||
{
|
||||
struct smb_fifo_reg *const inst_fifo = HAL_I2C_FIFO_INSTANCE(dev);
|
||||
struct smb_reg *const inst = HAL_I2C_INSTANCE(dev);
|
||||
uint8_t value = MIN(threshold, NPCX_I2C_FIFO_MAX_SIZE);
|
||||
|
||||
SET_FIELD(inst_fifo->SMBRXF_CTL, NPCX_SMBRXF_CTL_RX_THR, value);
|
||||
SET_FIELD(inst->SMBRXF_CTL, NPCX_SMBRXF_CTL_RX_THR, value);
|
||||
|
||||
/*
|
||||
* Is it last received transaction? If so, set LAST bit. Then the
|
||||
* hardware will generate NACK automatically when receiving last byte.
|
||||
*/
|
||||
if (last && (value == threshold)) {
|
||||
inst_fifo->SMBRXF_CTL |= BIT(NPCX_SMBRXF_CTL_LAST);
|
||||
inst->SMBRXF_CTL |= BIT(NPCX_SMBRXF_CTL_LAST);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void i2c_ctrl_fifo_clear_status(const struct device *dev)
|
||||
{
|
||||
struct smb_fifo_reg *const inst_fifo = HAL_I2C_FIFO_INSTANCE(dev);
|
||||
struct smb_reg *const inst = HAL_I2C_INSTANCE(dev);
|
||||
|
||||
inst_fifo->SMBFIF_CTS |= BIT(NPCX_SMBFIF_CTS_CLR_FIFO);
|
||||
inst->SMBFIF_CTS |= BIT(NPCX_SMBFIF_CTS_CLR_FIFO);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -407,7 +404,7 @@ static void i2c_ctrl_config_bus_freq(const struct device *dev,
|
|||
/* I2C controller local functions */
|
||||
static int i2c_ctrl_wait_stop_completed(const struct device *dev, int timeout)
|
||||
{
|
||||
struct smb_fifo_reg *const inst_fifo = HAL_I2C_FIFO_INSTANCE(dev);
|
||||
struct smb_reg *const inst = HAL_I2C_INSTANCE(dev);
|
||||
|
||||
if (timeout <= 0) {
|
||||
return -EINVAL;
|
||||
|
@ -418,7 +415,7 @@ static int i2c_ctrl_wait_stop_completed(const struct device *dev, int timeout)
|
|||
* Wait till i2c bus is idle. This bit is cleared to 0
|
||||
* automatically after the STOP condition is generated.
|
||||
*/
|
||||
if (!IS_BIT_SET(inst_fifo->SMBCTL1, NPCX_SMBCTL1_STOP))
|
||||
if (!IS_BIT_SET(inst->SMBCTL1, NPCX_SMBCTL1_STOP))
|
||||
break;
|
||||
k_msleep(1);
|
||||
} while (--timeout);
|
||||
|
@ -465,7 +462,7 @@ static int i2c_ctrl_wait_idle_completed(const struct device *dev, int timeout)
|
|||
|
||||
static int i2c_ctrl_recovery(const struct device *dev)
|
||||
{
|
||||
struct smb_fifo_reg *const inst_fifo = HAL_I2C_FIFO_INSTANCE(dev);
|
||||
struct smb_reg *const inst = HAL_I2C_INSTANCE(dev);
|
||||
struct i2c_ctrl_data *const data = dev->data;
|
||||
int ret;
|
||||
|
||||
|
@ -482,9 +479,9 @@ static int i2c_ctrl_recovery(const struct device *dev)
|
|||
* - Wait for STOP condition completed
|
||||
* - Then clear BB (BUS BUSY) bit
|
||||
*/
|
||||
inst_fifo->SMBST = BIT(NPCX_SMBST_BER) | BIT(NPCX_SMBST_NEGACK);
|
||||
inst->SMBST = BIT(NPCX_SMBST_BER) | BIT(NPCX_SMBST_NEGACK);
|
||||
ret = i2c_ctrl_wait_stop_completed(dev, I2C_MAX_TIMEOUT);
|
||||
inst_fifo->SMBCST |= BIT(NPCX_SMBCST_BB);
|
||||
inst->SMBCST |= BIT(NPCX_SMBCST_BB);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Abort i2c port%02x fail! Bus might be stalled.",
|
||||
data->port);
|
||||
|
@ -496,7 +493,7 @@ static int i2c_ctrl_recovery(const struct device *dev)
|
|||
* - Wait both SCL/SDA line are high
|
||||
* - Enable i2c module again
|
||||
*/
|
||||
inst_fifo->SMBCTL2 &= ~BIT(NPCX_SMBCTL2_ENABLE);
|
||||
inst->SMBCTL2 &= ~BIT(NPCX_SMBCTL2_ENABLE);
|
||||
ret = i2c_ctrl_wait_idle_completed(dev, I2C_MAX_TIMEOUT);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Reset i2c port%02x fail! Bus might be stalled.",
|
||||
|
@ -743,11 +740,11 @@ static int i2c_ctrl_proc_read_msg(const struct device *dev, struct i2c_msg *msg)
|
|||
/* I2C controller isr function */
|
||||
static void i2c_ctrl_isr(const struct device *dev)
|
||||
{
|
||||
struct smb_fifo_reg *const inst_fifo = HAL_I2C_FIFO_INSTANCE(dev);
|
||||
struct smb_reg *const inst = HAL_I2C_INSTANCE(dev);
|
||||
struct i2c_ctrl_data *const data = dev->data;
|
||||
uint8_t status, tmp;
|
||||
|
||||
status = inst_fifo->SMBST & NPCX_VALID_SMBST_MASK;
|
||||
status = inst->SMBST & NPCX_VALID_SMBST_MASK;
|
||||
LOG_DBG("status: %02x, %d", status, data->oper_state);
|
||||
|
||||
/* A 'Bus Error' has been identified */
|
||||
|
@ -756,7 +753,7 @@ static void i2c_ctrl_isr(const struct device *dev)
|
|||
i2c_ctrl_stop(dev);
|
||||
|
||||
/* Clear BER Bit */
|
||||
inst_fifo->SMBST = BIT(NPCX_SMBST_BER);
|
||||
inst->SMBST = BIT(NPCX_SMBST_BER);
|
||||
|
||||
/* Make sure slave doesn't hold bus by reading FIFO again */
|
||||
tmp = i2c_ctrl_fifo_read(dev);
|
||||
|
@ -775,7 +772,7 @@ static void i2c_ctrl_isr(const struct device *dev)
|
|||
i2c_ctrl_stop(dev);
|
||||
|
||||
/* Clear NEGACK Bit */
|
||||
inst_fifo->SMBST = BIT(NPCX_SMBST_NEGACK);
|
||||
inst->SMBST = BIT(NPCX_SMBST_NEGACK);
|
||||
|
||||
/* End transaction */
|
||||
data->oper_state = NPCX_I2C_WAIT_STOP;
|
||||
|
@ -795,7 +792,7 @@ static void i2c_ctrl_isr(const struct device *dev)
|
|||
|
||||
/* Clear unexpected status bits */
|
||||
if (status != 0) {
|
||||
inst_fifo->SMBST = status;
|
||||
inst->SMBST = status;
|
||||
LOG_ERR("Unexpected SMBST 0x%02x occurred on i2c port%02x!",
|
||||
status, data->port);
|
||||
}
|
||||
|
|
|
@ -1113,87 +1113,64 @@ struct smb_reg {
|
|||
volatile uint8_t SMBCTL3;
|
||||
/* 0x00F: SMB Bus Timeout */
|
||||
volatile uint8_t SMBT_OUT;
|
||||
/* 0x010: SMB Own Address 3 */
|
||||
volatile uint8_t SMBADDR3;
|
||||
/* 0x011: SMB Own Address 7 */
|
||||
volatile uint8_t SMBADDR7;
|
||||
/* 0x012: SMB Own Address 4 */
|
||||
volatile uint8_t SMBADDR4;
|
||||
/* 0x013: SMB Own Address 8 */
|
||||
volatile uint8_t SMBADDR8;
|
||||
/* 0x014: SMB Own Address 5 */
|
||||
volatile uint8_t SMBADDR5;
|
||||
volatile uint8_t reserved8;
|
||||
/* 0x016: SMB Own Address 6 */
|
||||
volatile uint8_t SMBADDR6;
|
||||
volatile uint8_t reserved9;
|
||||
/* 0x018: SMB Control Status 2 */
|
||||
volatile uint8_t SMBCST2;
|
||||
/* 0x019: SMB Control Status 3 */
|
||||
volatile uint8_t SMBCST3;
|
||||
/* 0x01A: SMB Control 4 */
|
||||
volatile uint8_t SMBCTL4;
|
||||
volatile uint8_t reserved10;
|
||||
/* 0x01C: SMB SCL Low Time */
|
||||
volatile uint8_t SMBSCLLT;
|
||||
/* 0x01D: SMB FIFO Control */
|
||||
volatile uint8_t SMBFIF_CTL;
|
||||
/* 0x01E: SMB SCL High Time */
|
||||
volatile uint8_t SMBSCLHT;
|
||||
volatile uint8_t reserved11;
|
||||
};
|
||||
|
||||
/*
|
||||
* SMBUS (SMB) FIFO device registers
|
||||
*/
|
||||
struct smb_fifo_reg {
|
||||
/* 0x000: SMB Serial Data */
|
||||
volatile uint8_t SMBSDA;
|
||||
volatile uint8_t reserved1;
|
||||
/* 0x002: SMB Status */
|
||||
volatile uint8_t SMBST;
|
||||
volatile uint8_t reserved2;
|
||||
/* 0x004: SMB Control Status */
|
||||
volatile uint8_t SMBCST;
|
||||
volatile uint8_t reserved3;
|
||||
/* 0x006: SMB Control 1 */
|
||||
volatile uint8_t SMBCTL1;
|
||||
volatile uint8_t reserved4;
|
||||
/* 0x008: SMB Own Address */
|
||||
volatile uint8_t SMBADDR1;
|
||||
volatile uint8_t reserved5;
|
||||
/* 0x00A: SMB Control 2 */
|
||||
volatile uint8_t SMBCTL2;
|
||||
volatile uint8_t reserved6;
|
||||
/* 0x00C: SMB Own Address */
|
||||
volatile uint8_t SMBADDR2;
|
||||
volatile uint8_t reserved7;
|
||||
/* 0x00E: SMB Control 3 */
|
||||
volatile uint8_t SMBCTL3;
|
||||
/* 0x00F: SMB Bus Timeout */
|
||||
volatile uint8_t SMBT_OUT;
|
||||
/* 0x010: SMB FIFO Control */
|
||||
volatile uint8_t SMBFIF_CTS;
|
||||
volatile uint8_t reserved8;
|
||||
/* 0x012: SMB Tx-FIFO Control */
|
||||
volatile uint8_t SMBTXF_CTL;
|
||||
volatile uint8_t reserved9;
|
||||
/* 0x014: SMB Bus Timeout */
|
||||
volatile uint8_t SMB_T_OUT;
|
||||
volatile uint8_t reserved10[3];
|
||||
/* 0x018: SMB Control Status 2 */
|
||||
volatile uint8_t SMBCST2;
|
||||
/* 0x019: SMB Control Status 3 */
|
||||
volatile uint8_t SMBCST3;
|
||||
/* 0x01A: SMB Tx-FIFO Status */
|
||||
volatile uint8_t SMBTXF_STS;
|
||||
volatile uint8_t reserved11;
|
||||
/* 0x01C: SMB Rx-FIFO Status */
|
||||
volatile uint8_t SMBRXF_STS;
|
||||
volatile uint8_t reserved12;
|
||||
/* 0x01E: SMB Rx-FIFO Control */
|
||||
volatile uint8_t SMBRXF_CTL;
|
||||
volatile uint8_t reserved13;
|
||||
union {
|
||||
/* Bank 0 */
|
||||
struct {
|
||||
/* 0x010: SMB Own Address 3 */
|
||||
volatile uint8_t SMBADDR3;
|
||||
/* 0x011: SMB Own Address 7 */
|
||||
volatile uint8_t SMBADDR7;
|
||||
/* 0x012: SMB Own Address 4 */
|
||||
volatile uint8_t SMBADDR4;
|
||||
/* 0x013: SMB Own Address 8 */
|
||||
volatile uint8_t SMBADDR8;
|
||||
/* 0x014: SMB Own Address 5 */
|
||||
volatile uint8_t SMBADDR5;
|
||||
volatile uint8_t reserved8;
|
||||
/* 0x016: SMB Own Address 6 */
|
||||
volatile uint8_t SMBADDR6;
|
||||
volatile uint8_t reserved9;
|
||||
/* 0x018: SMB Control Status 2 */
|
||||
volatile uint8_t SMBCST2;
|
||||
/* 0x019: SMB Control Status 3 */
|
||||
volatile uint8_t SMBCST3;
|
||||
/* 0x01A: SMB Control 4 */
|
||||
volatile uint8_t SMBCTL4;
|
||||
volatile uint8_t reserved10;
|
||||
/* 0x01C: SMB SCL Low Time */
|
||||
volatile uint8_t SMBSCLLT;
|
||||
/* 0x01D: SMB FIFO Control */
|
||||
volatile uint8_t SMBFIF_CTL;
|
||||
/* 0x01E: SMB SCL High Time */
|
||||
volatile uint8_t SMBSCLHT;
|
||||
volatile uint8_t reserved11;
|
||||
};
|
||||
/* Bank 1 */
|
||||
struct {
|
||||
/* 0x010: SMB FIFO Control */
|
||||
volatile uint8_t SMBFIF_CTS;
|
||||
volatile uint8_t reserved12;
|
||||
/* 0x012: SMB Tx-FIFO Control */
|
||||
volatile uint8_t SMBTXF_CTL;
|
||||
volatile uint8_t reserved13;
|
||||
/* 0x014: SMB Bus Timeout */
|
||||
volatile uint8_t SMB_T_OUT;
|
||||
volatile uint8_t reserved14[3];
|
||||
/* 0x018: SMB Control Status 2 (FIFO) */
|
||||
volatile uint8_t SMBCST2_FIFO;
|
||||
/* 0x019: SMB Control Status 3 (FIFO) */
|
||||
volatile uint8_t SMBCST3_FIFO;
|
||||
/* 0x01A: SMB Tx-FIFO Status */
|
||||
volatile uint8_t SMBTXF_STS;
|
||||
volatile uint8_t reserved15;
|
||||
/* 0x01C: SMB Rx-FIFO Status */
|
||||
volatile uint8_t SMBRXF_STS;
|
||||
volatile uint8_t reserved16;
|
||||
/* 0x01E: SMB Rx-FIFO Control */
|
||||
volatile uint8_t SMBRXF_CTL;
|
||||
volatile uint8_t reserved17[1];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* SMB register fields */
|
||||
|
|
|
@ -121,13 +121,10 @@ NPCX_REG_SIZE_CHECK(smb_reg, 0x020);
|
|||
NPCX_REG_OFFSET_CHECK(smb_reg, SMBCTL1, 0x006);
|
||||
NPCX_REG_OFFSET_CHECK(smb_reg, SMBT_OUT, 0x00f);
|
||||
NPCX_REG_OFFSET_CHECK(smb_reg, SMBADDR6, 0x016);
|
||||
NPCX_REG_OFFSET_CHECK(smb_reg, SMBCST2, 0x018);
|
||||
NPCX_REG_OFFSET_CHECK(smb_reg, SMBTXF_STS, 0x01a);
|
||||
NPCX_REG_OFFSET_CHECK(smb_reg, SMBSCLHT, 0x01e);
|
||||
|
||||
NPCX_REG_SIZE_CHECK(smb_fifo_reg, 0x020);
|
||||
NPCX_REG_OFFSET_CHECK(smb_fifo_reg, SMBT_OUT, 0x00f);
|
||||
NPCX_REG_OFFSET_CHECK(smb_fifo_reg, SMBCST2, 0x018);
|
||||
NPCX_REG_OFFSET_CHECK(smb_fifo_reg, SMBTXF_STS, 0x01a);
|
||||
NPCX_REG_OFFSET_CHECK(smb_fifo_reg, SMBRXF_CTL, 0x01e);
|
||||
NPCX_REG_OFFSET_CHECK(smb_reg, SMBRXF_CTL, 0x01e);
|
||||
|
||||
/* ITIM register structure check */
|
||||
NPCX_REG_SIZE_CHECK(itim32_reg, 0x00c);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue