summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/npcx/config_chip-npcx7.h2
-rw-r--r--chip/npcx/i2c.c427
-rw-r--r--chip/npcx/registers.h29
3 files changed, 378 insertions, 80 deletions
diff --git a/chip/npcx/config_chip-npcx7.h b/chip/npcx/config_chip-npcx7.h
index fe88bc3016..27d7920a3a 100644
--- a/chip/npcx/config_chip-npcx7.h
+++ b/chip/npcx/config_chip-npcx7.h
@@ -55,6 +55,8 @@
#define I2C_PORT_COUNT 11
#endif
+#define NPCX_I2C_FIFO_SUPPORT
+
/* Use SHI module version 2 supported by npcx7 family */
#define NPCX_SHI_V2
diff --git a/chip/npcx/i2c.c b/chip/npcx/i2c.c
index 81e69a3d64..bae14aa101 100644
--- a/chip/npcx/i2c.c
+++ b/chip/npcx/i2c.c
@@ -21,9 +21,11 @@
#if !(DEBUG_I2C)
#define CPUTS(...)
#define CPRINTS(...)
+#define CPRINTF(...)
#else
#define CPUTS(outstr) cputs(CC_I2C, outstr)
#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_I2C, format, ## args)
#endif
/* Timeout for device should be available after reset (SMBus spec. unit:ms) */
@@ -35,13 +37,40 @@
*/
#define I2C_MIN_TIMEOUT 25
+/*
+ * I2C module that supports FIFO mode has 32 bytes Tx FIFO and
+ * 32 bytes Rx FIFO.
+ */
+#define NPCX_I2C_FIFO_MAX_SIZE 32
+
/* Macro functions of I2C */
#define I2C_START(ctrl) SET_BIT(NPCX_SMBCTL1(ctrl), NPCX_SMBCTL1_START)
#define I2C_STOP(ctrl) SET_BIT(NPCX_SMBCTL1(ctrl), NPCX_SMBCTL1_STOP)
#define I2C_NACK(ctrl) SET_BIT(NPCX_SMBCTL1(ctrl), NPCX_SMBCTL1_ACK)
+/* I2C moudule automatically stall bus after sending slave address */
#define I2C_STALL(ctrl) SET_BIT(NPCX_SMBCTL1(ctrl), NPCX_SMBCTL1_STASTRE)
#define I2C_WRITE_BYTE(ctrl, data) (NPCX_SMBSDA(ctrl) = data)
#define I2C_READ_BYTE(ctrl, data) (data = NPCX_SMBSDA(ctrl))
+#define I2C_TX_FIFO_OCCUPIED(ctrl) (NPCX_SMBTXF_STS(ctrl) & 0x3F)
+#define I2C_TX_FIFO_AVAILABLE(ctrl) \
+ (NPCX_I2C_FIFO_MAX_SIZE - I2C_TX_FIFO_OCCUPIED(ctrl))
+
+#define I2C_RX_FIFO_OCCUPIED(ctrl) (NPCX_SMBRXF_STS(ctrl) & 0x3F)
+#define I2C_RX_FIFO_AVAILABLE(ctrl) \
+ (NPCX_I2C_FIFO_MAX_SIZE - I2C_RX_FIFO_OCCUPIED(ctrl))
+/* Drive the SCL signal to low */
+#define I2C_SCL_STALL(ctrl) \
+ (NPCX_SMBCTL3(ctrl) = \
+ (NPCX_SMBCTL3(ctrl) & ~BIT(NPCX_SMBCTL3_SCL_LVL)) | \
+ BIT(NPCX_SMBCTL3_SDA_LVL))
+/*
+ * Release the SCL signal to be pulled up to high level.
+ * Note: The SCL might be still driven low either by I2C module or external
+ * devices connected to ths bus.
+ */
+#define I2C_SCL_FREE(ctrl) \
+ (NPCX_SMBCTL3(ctrl) |= BIT(NPCX_SMBCTL3_SCL_LVL) | \
+ BIT(NPCX_SMBCTL3_SDA_LVL))
/* Error values that functions can return */
enum smb_error {
@@ -91,7 +120,7 @@ struct i2c_status {
uint32_t timeout_us;/* Transaction timeout */
};
/* I2C controller state data array */
-struct i2c_status i2c_stsobjs[I2C_CONTROLLER_COUNT];
+static struct i2c_status i2c_stsobjs[I2C_CONTROLLER_COUNT];
/* I2C timing setting */
struct i2c_timing {
@@ -123,6 +152,10 @@ BUILD_ASSERT(ARRAY_SIZE(i2c_irqs) == I2C_CONTROLLER_COUNT);
static void i2c_init_bus(int controller)
{
+ /* Enable FIFO mode */
+ if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT))
+ SET_BIT(NPCX_SMBFIF_CTL(controller), NPCX_SMBFIF_CTL_FIFO_EN);
+
/* Enable module - before configuring CTL1 */
SET_BIT(NPCX_SMBCTL2(controller), NPCX_SMBCTL2_ENABLE);
@@ -199,12 +232,47 @@ static int i2c_reset(int controller)
return 1;
}
+static void i2c_select_bank(int controller, int bank)
+{
+ if (bank)
+ SET_BIT(NPCX_SMBCTL3(controller), NPCX_SMBCTL3_BNK_SEL);
+ else
+ CLEAR_BIT(NPCX_SMBCTL3(controller), NPCX_SMBCTL3_BNK_SEL);
+}
+
+static void i2c_stall_bus(int controller, int stall)
+{
+ i2c_select_bank(controller, 0);
+ /*
+ * Enable the writing to SCL_LVL and SDA_LVL bit in
+ * SMBnCTL3 register. Then, firmware can set SCL_LVL to 0 to
+ * stall the bus when needed. Note: this register should be
+ * accessed when bank = 0.
+ */
+ SET_BIT(NPCX_SMBCTL4(controller), NPCX_SMBCTL4_LVL_WE);
+ if (stall)
+ I2C_SCL_STALL(controller);
+ else
+ I2C_SCL_FREE(controller);
+ /*
+ * Disable the writing to SCL_LVL and SDA_LVL bit in
+ * SMBnCTL3 register. It will prevent form changing the level of
+ * SCL/SDA when touching other bits in SMBnCTL3 register.
+ */
+ CLEAR_BIT(NPCX_SMBCTL4(controller), NPCX_SMBCTL4_LVL_WE);
+ i2c_select_bank(controller, 1);
+}
+
static void i2c_recovery(int controller, volatile struct i2c_status *p_status)
{
cprintf(CC_I2C,
"i2c %d recovery! error code is %d, current state is %d\n",
controller, p_status->err_code, p_status->oper_state);
+ /* Make sure the bus is not stalled before exit. */
+ if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT))
+ i2c_stall_bus(controller, 0);
+
/* Abort data, wait for STOP condition completed. */
i2c_abort_data(controller);
@@ -216,16 +284,52 @@ static void i2c_recovery(int controller, volatile struct i2c_status *p_status)
p_status->oper_state = SMB_IDLE;
}
+/*
+ * This function can be called in either single-byte mode or FIFO mode.
+ * In single-byte mode - it always write 1 byte to SMBSDA register at one time.
+ * In FIFO mode - write as many as available bytes in FIFO at one time.
+ */
+static void i2c_fifo_write_data(int controller)
+{
+ int len, fifo_avail, i;
+
+ volatile struct i2c_status *p_status = i2c_stsobjs + controller;
+
+ len = 1;
+ if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) {
+ len = p_status->sz_txbuf - p_status->idx_buf;
+ fifo_avail = I2C_TX_FIFO_AVAILABLE(controller);
+ len = MIN(len, fifo_avail);
+ }
+ for (i = 0; i < len; i++) {
+ I2C_WRITE_BYTE(controller,
+ p_status->tx_buf[p_status->idx_buf++]);
+ CPRINTF("%02x ",
+ p_status->tx_buf[p_status->idx_buf - 1]);
+ }
+ CPRINTF("\n");
+}
+
enum smb_error i2c_master_transaction(int controller)
{
/* Set i2c mode to object */
int events = 0;
volatile struct i2c_status *p_status = i2c_stsobjs + controller;
+ /* Switch to bank 1 to access I2C FIO registers */
+ if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT))
+ i2c_select_bank(controller, 1);
+
/* Assign current SMB status of controller */
if (p_status->oper_state == SMB_IDLE) {
/* New transaction */
p_status->oper_state = SMB_MASTER_START;
+ /* Clear FIFO and status bit */
+ if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) {
+ NPCX_SMBFIF_CTS(controller) =
+ BIT(NPCX_SMBFIF_CTS_RXF_TXE) |
+ BIT(NPCX_SMBFIF_CTS_CLR_FIFO);
+ }
} else if (p_status->oper_state == SMB_WRITE_SUSPEND) {
if (p_status->sz_txbuf == 0) {
/* Read bytes from next transaction */
@@ -234,34 +338,75 @@ enum smb_error i2c_master_transaction(int controller)
} else {
/* Continue to write the other bytes */
p_status->oper_state = SMB_WRITE_OPER;
- I2C_WRITE_BYTE(controller,
- p_status->tx_buf[p_status->idx_buf++]);
- CPRINTS("-W(%02x)",
- p_status->tx_buf[p_status->idx_buf-1]);
+ CPRINTS("-W");
+ /*
+ * This function can be called in either single-byte
+ * mode or FIFO mode.
+ */
+ i2c_fifo_write_data(controller);
}
} else if (p_status->oper_state == SMB_READ_SUSPEND) {
- /*
- * Do dummy read if read length is 1 and I2C_XFER_STOP is set
- * simultaneously.
- */
- if (p_status->sz_rxbuf == 1 &&
- (p_status->flags & I2C_XFER_STOP)) {
+ if (!IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) {
/*
- * Since SCL is released after reading last byte from
- * previous transaction, adding a dummy byte for next
- * transaction which let ec sets NACK bit in time is
- * necessary. Or i2c master cannot generate STOP
- * when the last byte is ACK during receiving.
+ * Do dummy read if read length is 1 and I2C_XFER_STOP
+ * is set simultaneously.
*/
- p_status->sz_rxbuf++;
- p_status->oper_state = SMB_DUMMY_READ_OPER;
- } else
- /* Need to read the other bytes from next transaction */
- p_status->oper_state = SMB_READ_OPER;
+ if (p_status->sz_rxbuf == 1 &&
+ (p_status->flags & I2C_XFER_STOP)) {
+ /*
+ * Since SCL is released after reading last
+ * byte from previous transaction, adding a
+ * dummy byte for next transaction which let
+ * ec sets NACK bit in time is necessary.
+ * Or i2c master cannot generate STOP
+ * when the last byte is ACK during receiving.
+ */
+ p_status->sz_rxbuf++;
+ p_status->oper_state = SMB_DUMMY_READ_OPER;
+ } else
+ /*
+ * Need to read the other bytes from
+ * next transaction
+ */
+ p_status->oper_state = SMB_READ_OPER;
+ }
} else
cprintf(CC_I2C, "Unexpected i2c state machine! %d\n",
p_status->oper_state);
+ if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT)) {
+ if (p_status->sz_rxbuf > 0) {
+ if (p_status->sz_rxbuf > NPCX_I2C_FIFO_MAX_SIZE) {
+ /* Set RX threshold = FIFO_MAX_SIZE */
+ SET_FIELD(NPCX_SMBRXF_CTL(controller),
+ NPCX_SMBRXF_CTL_RX_THR,
+ NPCX_I2C_FIFO_MAX_SIZE);
+ } else {
+ /*
+ * set RX threshold = remaining data bytes
+ * (it should be <= FIFO_MAX_SIZE)
+ */
+ SET_FIELD(NPCX_SMBRXF_CTL(controller),
+ NPCX_SMBRXF_CTL_RX_THR,
+ p_status->sz_rxbuf);
+ /*
+ * Set LAST bit generate the NACK at the
+ * last byte of the data group in FIFO
+ */
+ if (p_status->flags & I2C_XFER_STOP) {
+ SET_BIT(NPCX_SMBRXF_CTL(controller),
+ NPCX_SMBRXF_CTL_LAST);
+ }
+ }
+
+ /* Free the stalled SCL signal */
+ if (p_status->oper_state == SMB_READ_SUSPEND) {
+ p_status->oper_state = SMB_READ_OPER;
+ i2c_stall_bus(controller, 0);
+ }
+ }
+ }
+
/* Generate a START condition */
if (p_status->oper_state == SMB_MASTER_START ||
p_status->oper_state == SMB_REPEAT_START) {
@@ -280,6 +425,13 @@ enum smb_error i2c_master_transaction(int controller)
task_disable_irq(i2c_irqs[controller]);
/*
+ * Accessing FIFO register is only needed during transaction.
+ * Switch back to bank 0 at the end of transaction
+ */
+ if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT))
+ i2c_select_bank(controller, 0);
+
+ /*
* If Stall-After-Start mode is still enabled since NACK or BUS error
* occurs, disable it.
*/
@@ -318,6 +470,11 @@ void i2c_done(int controller)
/* Issue a STOP condition on the bus */
I2C_STOP(controller);
CPUTS("-SP");
+ /* Clear RXF_TXE bit (RX FIFO full/TX FIFO empty) */
+ if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT))
+ NPCX_SMBFIF_CTS(controller) =
+ BIT(NPCX_SMBFIF_CTS_RXF_TXE);
+
/* Clear SDAST by writing dummy byte */
I2C_WRITE_BYTE(controller, 0xFF);
}
@@ -341,10 +498,167 @@ void i2c_done(int controller)
CPUTS("-END");
}
+static void i2c_handle_receive(int controller)
+{
+ uint8_t data;
+ volatile struct i2c_status *p_status = i2c_stsobjs + controller;
+
+ /* last byte is about to be read - end of transaction */
+ if (p_status->idx_buf == (p_status->sz_rxbuf - 1)) {
+ /* need to STOP or not */
+ if (p_status->flags & I2C_XFER_STOP) {
+ /* Stop should set before reading last byte */
+ I2C_STOP(controller);
+ CPUTS("-SP");
+ } else {
+ /*
+ * Disable interrupt before i2c master read SDA
+ * reg (stall SCL) and forbid SDAST generate
+ * interrupt until starting other transactions
+ */
+ task_disable_irq(i2c_irqs[controller]);
+ }
+ }
+ /* Check if byte-before-last is about to be read */
+ else if (p_status->idx_buf == (p_status->sz_rxbuf - 2)) {
+ /*
+ * Set nack before reading byte-before-last,
+ * so that nack will be generated after receive
+ * of last byte
+ */
+ if (p_status->flags & I2C_XFER_STOP) {
+ I2C_NACK(controller);
+ CPUTS("-GNA");
+ }
+ }
+
+ /* Read data for SMBSDA */
+ I2C_READ_BYTE(controller, data);
+ CPRINTS("-R(%02x)", data);
+
+ /* Read to buf. Skip last byte if meet SMB_DUMMY_READ_OPER */
+ if (p_status->oper_state == SMB_DUMMY_READ_OPER &&
+ p_status->idx_buf == (p_status->sz_rxbuf - 1))
+ p_status->idx_buf++;
+ else
+ p_status->rx_buf[p_status->idx_buf++] = data;
+
+ /* last byte is read - end of transaction */
+ if (p_status->idx_buf == p_status->sz_rxbuf) {
+ /* Set current status */
+ p_status->oper_state = (p_status->flags & I2C_XFER_STOP)
+ ? SMB_IDLE : SMB_READ_SUSPEND;
+ /* Set error code */
+ p_status->err_code = SMB_OK;
+ /* Notify upper layer of missing data */
+ task_set_event(p_status->task_waiting,
+ TASK_EVENT_I2C_IDLE, 0);
+ CPUTS("-END");
+ }
+}
+
+static void i2c_fifo_read_data(int controller, uint8_t bytes_in_fifo)
+{
+ volatile struct i2c_status *p_status = i2c_stsobjs + controller;
+
+ while (bytes_in_fifo--) {
+ uint8_t data;
+
+ data = NPCX_SMBSDA(controller);
+ p_status->rx_buf[p_status->idx_buf++] = data;
+ CPRINTF("%02x ", data);
+ }
+ CPRINTF("\n");
+}
+
+static void i2c_fifo_handle_receive(int controller)
+{
+ uint8_t bytes_in_fifo, remaining_bytes;
+
+ volatile struct i2c_status *p_status = i2c_stsobjs + controller;
+
+ /*
+ * Clear RX_THST bit (RX-FIFO Threshold Status).
+ * It is set when RX_BYTES = RX_THR after being RX_BYTES < RX_THR
+ */
+ SET_BIT(NPCX_SMBRXF_STS(controller), NPCX_SMBRXF_STS_RX_THST);
+ SET_BIT(NPCX_SMBFIF_CTS(controller), NPCX_SMBFIF_CTS_RXF_TXE);
+
+ bytes_in_fifo = I2C_RX_FIFO_OCCUPIED(controller);
+ remaining_bytes = p_status->sz_rxbuf - p_status->idx_buf;
+ if (remaining_bytes - bytes_in_fifo <= 0) {
+ /*
+ * Last byte is about to be read - end of transaction.
+ * Stop should be set before reading last byte.
+ */
+ if (p_status->flags & I2C_XFER_STOP) {
+ I2C_STOP(controller);
+ CPUTS("-FSP");
+ } else {
+ task_disable_irq(i2c_irqs[controller]);
+ /*
+ * The I2C bus will be freed from stalled and continue
+ * to recevie data when reading data from FIFO.
+ * Pull SCL signal down to stall the bus manually.
+ * SCL signal will be freed when it gets a new I2C
+ * transaction call from common layer.
+ */
+ i2c_stall_bus(controller, 1);
+ }
+
+ CPRINTS("-LFR");
+ i2c_fifo_read_data(controller, remaining_bytes);
+ } else {
+ CPRINTS("-FR");
+ /*
+ * The I2C bus will be freed from stalled and continue to
+ * recevie data when reading data from FIFO.
+ * This may caue driver cannot set the new Rx threshold in time.
+ * Manually stall SCL signal until the new Rx threshold is set.
+ */
+ i2c_stall_bus(controller, 1);
+ i2c_fifo_read_data(controller, bytes_in_fifo);
+ remaining_bytes = p_status->sz_rxbuf - p_status->idx_buf;
+ if (remaining_bytes > 0) {
+ if (remaining_bytes > NPCX_I2C_FIFO_MAX_SIZE) {
+ SET_FIELD(NPCX_SMBRXF_CTL(controller),
+ NPCX_SMBRXF_CTL_RX_THR,
+ NPCX_I2C_FIFO_MAX_SIZE);
+ } else {
+ SET_FIELD(NPCX_SMBRXF_CTL(controller),
+ NPCX_SMBRXF_CTL_RX_THR,
+ remaining_bytes);
+ if (p_status->flags & I2C_XFER_STOP) {
+ SET_BIT(NPCX_SMBRXF_CTL(controller),
+ NPCX_SMBRXF_CTL_LAST);
+ CPRINTS("-FGNA");
+ }
+ }
+
+ }
+ i2c_stall_bus(controller, 0);
+
+ }
+ /* last byte is read - end of transaction */
+ if (p_status->idx_buf == p_status->sz_rxbuf) {
+ /* Set current status */
+ p_status->oper_state = (p_status->flags & I2C_XFER_STOP)
+ ? SMB_IDLE : SMB_READ_SUSPEND;
+ /* Set error code */
+ p_status->err_code = SMB_OK;
+ /* Notify upper layer of missing data */
+ task_set_event(p_status->task_waiting,
+ TASK_EVENT_I2C_IDLE, 0);
+ CPUTS("-END");
+ }
+
+}
+
static void i2c_handle_sda_irq(int controller)
{
volatile struct i2c_status *p_status = i2c_stsobjs + controller;
uint8_t addr_8bit = I2C_GET_ADDR(p_status->slave_addr_flags) << 1;
+
/* 1 Issue Start is successful ie. write address byte */
if (p_status->oper_state == SMB_MASTER_START
|| p_status->oper_state == SMB_REPEAT_START) {
@@ -361,12 +675,12 @@ static void i2c_handle_sda_irq(int controller)
/* Write the address to the bus R bit*/
I2C_WRITE_BYTE(controller, (addr_8bit | 0x1));
- CPRINTS("-ARR-0x%02x", addr);
+ CPRINTS("-ARR-0x%02x", addr_8bit);
} else {/* Transmit mode */
p_status->oper_state = SMB_WRITE_OPER;
/* Write the address to the bus W bit*/
I2C_WRITE_BYTE(controller, addr_8bit);
- CPRINTS("-ARW-0x%02x", addr);
+ CPRINTS("-ARW-0x%02x", addr_8bit);
}
/* Completed handling START condition */
return;
@@ -411,68 +725,21 @@ static void i2c_handle_sda_irq(int controller)
}
/* write next byte (not last byte and not slave address */
else {
- I2C_WRITE_BYTE(controller,
- p_status->tx_buf[p_status->idx_buf++]);
- CPRINTS("-W(%02x)",
- p_status->tx_buf[p_status->idx_buf-1]);
+ /*
+ * This function can be called in either single-byte
+ * mode or FIFO mode.
+ */
+ CPRINTS("-W");
+ i2c_fifo_write_data(controller);
}
}
/* 3 Handle master read operation (read or after a write operation) */
else if (p_status->oper_state == SMB_READ_OPER ||
p_status->oper_state == SMB_DUMMY_READ_OPER) {
- uint8_t data;
- /* last byte is about to be read - end of transaction */
- if (p_status->idx_buf == (p_status->sz_rxbuf - 1)) {
- /* need to STOP or not */
- if (p_status->flags & I2C_XFER_STOP) {
- /* Stop should set before reading last byte */
- I2C_STOP(controller);
- CPUTS("-SP");
- } else {
- /*
- * Disable interrupt before i2c master read SDA
- * reg (stall SCL) and forbid SDAST generate
- * interrupt until starting other transactions
- */
- task_disable_irq(i2c_irqs[controller]);
- }
- }
- /* Check if byte-before-last is about to be read */
- else if (p_status->idx_buf == (p_status->sz_rxbuf - 2)) {
- /*
- * Set nack before reading byte-before-last,
- * so that nack will be generated after receive
- * of last byte
- */
- if (p_status->flags & I2C_XFER_STOP) {
- I2C_NACK(controller);
- CPUTS("-GNA");
- }
- }
-
- /* Read data for SMBSDA */
- I2C_READ_BYTE(controller, data);
- CPRINTS("-R(%02x)", data);
-
- /* Read to buf. Skip last byte if meet SMB_DUMMY_READ_OPER */
- if (p_status->oper_state == SMB_DUMMY_READ_OPER &&
- p_status->idx_buf == (p_status->sz_rxbuf - 1))
- p_status->idx_buf++;
+ if (IS_ENABLED(NPCX_I2C_FIFO_SUPPORT))
+ i2c_fifo_handle_receive(controller);
else
- p_status->rx_buf[p_status->idx_buf++] = data;
-
- /* last byte is read - end of transaction */
- if (p_status->idx_buf == p_status->sz_rxbuf) {
- /* Set current status */
- p_status->oper_state = (p_status->flags & I2C_XFER_STOP)
- ? SMB_IDLE : SMB_READ_SUSPEND;
- /* Set error code */
- p_status->err_code = SMB_OK;
- /* Notify upper layer of missing data */
- task_set_event(p_status->task_waiting,
- TASK_EVENT_I2C_IDLE, 0);
- CPUTS("-END");
- }
+ i2c_handle_receive(controller);
}
}
@@ -774,7 +1041,7 @@ static void i2c_freq_changed(void)
int i2c_timing_used;
/* use Fast Mode */
- SET_BIT(NPCX_SMBCTL3(ctrl) , NPCX_SMBCTL3_400K);
+ SET_BIT(NPCX_SMBCTL3(ctrl), NPCX_SMBCTL3_400K);
/*
* Set SCLH(L)T and hold-time directly for best i2c
* timing condition for all source clocks. Please refer
diff --git a/chip/npcx/registers.h b/chip/npcx/registers.h
index 3716b18dfe..b69fc5f806 100644
--- a/chip/npcx/registers.h
+++ b/chip/npcx/registers.h
@@ -776,6 +776,7 @@ enum {
#define NPCX_SMBTMR_EN(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x00B)
#define NPCX_SMBADDR2(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x00C)
#define NPCX_SMBCTL3(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x00E)
+/* SMB Registers in bank 0 */
#define NPCX_SMBADDR3(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x010)
#define NPCX_SMBADDR7(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x011)
#define NPCX_SMBADDR4(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x012)
@@ -786,7 +787,20 @@ enum {
#define NPCX_SMBCST3(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x019)
#define NPCX_SMBCTL4(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01A)
#define NPCX_SMBSCLLT(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01C)
+#define NPCX_SMBFIF_CTL(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01D)
#define NPCX_SMBSCLHT(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01E)
+/* SMB Registers in bank 1 */
+#define NPCX_SMBFIF_CTS(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x010)
+#define NPCX_SMBTXF_CTL(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x012)
+#define NPCX_SMB_T_OUT(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x014)
+/*
+ * These two registers are the same as in bank 0
+ * #define NPCX_SMBCST2(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x018)
+ * #define NPCX_SMBCST3(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x019)
+ */
+#define NPCX_SMBTXF_STS(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01A)
+#define NPCX_SMBRXF_STS(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01C)
+#define NPCX_SMBRXF_CTL(n) REG8(NPCX_SMB_BASE_ADDR(n) + 0x01E)
/* SMBus register fields */
#define NPCX_SMBST_XMIT 0
@@ -829,9 +843,11 @@ enum {
#define NPCX_SMBCTL3_SCLFRQ2_FIELD FIELD(0, 2)
#define NPCX_SMBCTL3_IDL_START 3
#define NPCX_SMBCTL3_400K 4
+#define NPCX_SMBCTL3_BNK_SEL 5
#define NPCX_SMBCTL3_SDA_LVL 6
#define NPCX_SMBCTL3_SCL_LVL 7
#define NPCX_SMBCTL4_HLDT_FIELD FIELD(0, 6)
+#define NPCX_SMBCTL4_LVL_WE 7
#define NPCX_SMBADDR1_SAEN 7
#define NPCX_SMBADDR2_SAEN 7
#define NPCX_SMBADDR3_SAEN 7
@@ -847,6 +863,19 @@ enum {
#define NPCX_SMBSEL_SMB5SEL 5
#define NPCX_SMBSEL_SMB6SEL 6
#endif
+#define NPCX_SMBFIF_CTS_RXF_TXE 1
+#define NPCX_SMBFIF_CTS_CLR_FIFO 6
+
+#define NPCX_SMBFIF_CTL_FIFO_EN 4
+
+#define NPCX_SMBRXF_STS_RX_THST 6
+
+/* RX FIFO threshold */
+#define NPCX_SMBRXF_CTL_RX_THR FIELD(0, 6)
+/*
+ * In master receiving mode, last byte in FIFO should send ACK or NACK
+ */
+#define NPCX_SMBRXF_CTL_LAST 7
/*
* SMB enumeration
* I2C port definitions.