summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaveh Jalali <caveh@chromium.org>2021-09-22 00:55:50 -0700
committerCommit Bot <commit-bot@chromium.org>2021-09-25 23:06:25 +0000
commitc3a408d48055937f131a948734346989fbbe5307 (patch)
treebb6c073b1b1f3c80e753cb5ba5427f62378b14e2
parente26717471ae91e845deea05737e246176d851c7d (diff)
downloadchrome-ec-c3a408d48055937f131a948734346989fbbe5307.tar.gz
npcx/i2c: Track configured I2C port speed
This adds code to the npcx I2C driver to keep track of the speed setting used to configure the port. This can be used to determine the current speed setting without decoding chip registers. BRANCH=none BUG=b:201039003 TEST=with follow-on patches, switched I2C bus speed between 400 kHz and 1 MHz. Change-Id: Ib7a61e23ec406deff80afead2e2aa6b64578ea1d Signed-off-by: Caveh Jalali <caveh@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3181502 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r--chip/npcx/i2c.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/chip/npcx/i2c.c b/chip/npcx/i2c.c
index d9f0be9233..c821b6d066 100644
--- a/chip/npcx/i2c.c
+++ b/chip/npcx/i2c.c
@@ -119,6 +119,7 @@ struct i2c_status {
enum smb_error err_code; /* Error code */
int task_waiting; /* Task waiting on controller */
uint32_t timeout_us;/* Transaction timeout */
+ uint16_t kbps; /* Speed */
};
/* I2C controller state data array */
static struct i2c_status i2c_stsobjs[I2C_CONTROLLER_COUNT];
@@ -212,6 +213,7 @@ static void i2c_abort_data(int controller)
static int i2c_reset(int controller)
{
uint16_t timeout = I2C_MAX_TIMEOUT;
+
/* Disable the SMB module */
CLEAR_BIT(NPCX_SMBCTL2(controller), NPCX_SMBCTL2_ENABLE);
@@ -1040,6 +1042,9 @@ static void i2c_port_set_freq(const int ctrl, const int bus_freq_kbps)
freq = (ctrl < 2) ? clock_get_freq() : clock_get_apb2_freq();
#endif
+ if (bus_freq_kbps == i2c_stsobjs[ctrl].kbps)
+ return;
+
/*
* Set SCL frequency by formula:
* tSCL = 4 * SCLFRQ * tCLK
@@ -1050,6 +1055,7 @@ static void i2c_port_set_freq(const int ctrl, const int bus_freq_kbps)
/* Normal mode if I2C freq is under 100kHz */
if (bus_freq_kbps <= 100) {
+ i2c_stsobjs[ctrl].kbps = bus_freq_kbps;
/* Set divider value of SCL */
SET_FIELD(NPCX_SMBCTL2(ctrl), NPCX_SMBCTL2_SCLFRQ7_FIELD,
(scl_freq & 0x7F));
@@ -1072,6 +1078,7 @@ static void i2c_port_set_freq(const int ctrl, const int bus_freq_kbps)
pTiming = i2c_1m_timings;
i2c_timing_used = i2c_1m_timing_used;
} else {
+ i2c_stsobjs[ctrl].kbps = bus_freq_kbps;
/* Set value from formula */
NPCX_SMBSCLLT(ctrl) = scl_freq;
NPCX_SMBSCLHT(ctrl) = scl_freq;
@@ -1083,6 +1090,7 @@ static void i2c_port_set_freq(const int ctrl, const int bus_freq_kbps)
for (j = 0; j < i2c_timing_used; j++, pTiming++) {
if (pTiming->clock == (freq/SECOND)) {
+ i2c_stsobjs[ctrl].kbps = bus_freq_kbps;
/* Set SCLH(L)T and hold-time */
NPCX_SMBSCLLT(ctrl) = pTiming->k1/2;
NPCX_SMBSCLHT(ctrl) = pTiming->k2/2;
@@ -1102,6 +1110,11 @@ static void i2c_freq_changed(void)
{
int i;
+ for (i = 0; i < I2C_CONTROLLER_COUNT; ++i) {
+ /* No bus speed configured */
+ i2c_stsobjs[i].kbps = 0;
+ }
+
for (i = 0; i < i2c_ports_used; i++) {
const struct i2c_port_t *p;
int ctrl;