summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMulin Chao <mlchao@nuvoton.com>2019-08-06 19:34:27 -0700
committerCommit Bot <commit-bot@chromium.org>2019-08-12 23:53:53 +0000
commitd09bc18d46c37070e3309b4f72a33d27134dea45 (patch)
tree90b23bd28e77e72905e76fbb4c43b289d800cfce
parentf21845b628b79c3ecbe460d900670757449225ab (diff)
downloadchrome-ec-d09bc18d46c37070e3309b4f72a33d27134dea45.tar.gz
npcx: i2c: adjust i2c bus frequency when it is set to 100kHz.
When npcx i2c module's bus frequency is set to 100KHz, it operates in normal mode and its bus frequency, fSCL, follows the formula listed below: fSCL = fCLK / (4*SCLFRQ), ie. SCLFRQ = fCLK / (4*fSCL) where fCLK is the source clock frequency of i2c module and SCLFRQ defines the SCL output period in SMBCTL2/3 registers. But integer division in this formula is equal to the floor of regular division if it isn't divisible. So far, all i2c modules' source clock frequency is 15MHz and if the desired i2c bus frequency is 100KHz, the SCLFRQ will be: SCLFRQ = fCLK/(4*fSCL) = 15MHz/(4*100kHz) = floor(37.5) = 37 And the actual i2c frequency is: fSCL = fCLK/(4*SCLFRQ) = 15MHz/(4*37) = 101.35KHz That's why we observe the i2c frequency is slightly higher than 100kHz. To fix this issue, this CL replaces integer division with the ceiling value of the formula to make sure bus frequency is lower than 100KHz and meet i2c spec when it operates in normal mode. BRANCH=none BUG=b:138350407 TEST=No build errors for npcx series. Measure the actual i2c bus which is configured to 100KHz after applying this CL. The actual frequency is 98.7 KHz on npcx5/7 evbs. Change-Id: I71e2c3090bc91c7b9945c01c04c9ac5ac656c893 Signed-off-by: Mulin Chao <mlchao@nuvoton.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1741566 Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Furquan Shaikh <furquan@chromium.org> Commit-Queue: Tim Wawrzynczak <twawrzynczak@chromium.org> Tested-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
-rw-r--r--chip/npcx/i2c.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/chip/npcx/i2c.c b/chip/npcx/i2c.c
index 151f786fbf..f98697da7b 100644
--- a/chip/npcx/i2c.c
+++ b/chip/npcx/i2c.c
@@ -758,9 +758,9 @@ static void i2c_freq_changed(void)
* Set SCL frequency by formula:
* tSCL = 4 * SCLFRQ * tCLK
* fSCL = fCLK / (4*SCLFRQ)
- * SCLFRQ = fSCL/(4*fSCL)
+ * SCLFRQ = ceil(fCLK/(4*fSCL))
*/
- scl_freq = (freq/1000) / (bus_freq*4); /* bus_freq is KHz */
+ scl_freq = DIV_ROUND_UP(freq, bus_freq*4000); /* Unit in bps */
/* Normal mode if i2c freq is under 100kHz */
if (bus_freq <= 100) {