diff options
author | Ting Shen <phoenixshen@google.com> | 2019-12-03 10:36:05 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-12-09 10:17:14 +0000 |
commit | 4fcabe7ac114ca097893746f3154b90e91e7c31f (patch) | |
tree | d76c87e09106a5bfe3c4168538dd83ee70ba5cee /driver/tcpm | |
parent | 7ab6523fe5a8badb379e93fe9bb07c85df40eac6 (diff) | |
download | chrome-ec-4fcabe7ac114ca097893746f3154b90e91e7c31f.tar.gz |
fusb302: implement vbus measurement using tcpc
Jacuzzi measure vbus using fusb302, add a config option
CONFIG_USB_PD_VBUS_MEASURE_TCPC and related implementation.
BUG=b:145376409
TEST=`ectool usbpdpower`
BRANCH=none
Change-Id: I84019a75338121f777a344a4b92710e2117a6bda
Signed-off-by: Ting Shen <phoenixshen@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1947507
Reviewed-by: Eric Yilun Lin <yllin@chromium.org>
Commit-Queue: Ting Shen <phoenixshen@chromium.org>
Tested-by: Ting Shen <phoenixshen@chromium.org>
Diffstat (limited to 'driver/tcpm')
-rw-r--r-- | driver/tcpm/fusb302.c | 61 | ||||
-rw-r--r-- | driver/tcpm/fusb302.h | 1 |
2 files changed, 62 insertions, 0 deletions
diff --git a/driver/tcpm/fusb302.c b/driver/tcpm/fusb302.c index bbb6015e56..c6465cd162 100644 --- a/driver/tcpm/fusb302.c +++ b/driver/tcpm/fusb302.c @@ -36,6 +36,8 @@ static struct fusb302_chip_state { uint8_t mdac_rd; } state[CONFIG_USB_PD_PORT_MAX_COUNT]; +static struct mutex measure_lock; + /* * Bring the FUSB302 out of reset after Hard Reset signaling. This will * automatically flush both the Rx and Tx FIFOs. @@ -112,6 +114,8 @@ static int measure_cc_pin_source(int port, int cc_measure) int reg; int cc_lvl; + mutex_lock(&measure_lock); + /* Read status register */ tcpc_read(port, TCPC_REG_SWITCHES0, ®); /* Save current value */ @@ -159,6 +163,8 @@ static int measure_cc_pin_source(int port, int cc_measure) /* Restore SWITCHES0 register to its value prior */ tcpc_write(port, TCPC_REG_SWITCHES0, switches0_reg); + mutex_unlock(&measure_lock); + return cc_lvl; } @@ -194,6 +200,8 @@ static void detect_cc_pin_sink(int port, enum tcpc_cc_voltage_status *cc1, int bc_lvl_cc1; int bc_lvl_cc2; + mutex_lock(&measure_lock); + /* * Measure CC1 first. */ @@ -264,6 +272,8 @@ static void detect_cc_pin_sink(int port, enum tcpc_cc_voltage_status *cc1, reg &= ~TCPC_REG_SWITCHES0_MEAS_CC2; tcpc_write(port, TCPC_REG_SWITCHES0, reg); + + mutex_unlock(&measure_lock); } /* Parse header bytes for the size of packet */ @@ -1077,6 +1087,57 @@ static int fusb302_tcpm_enter_low_power_mode(int port) } #endif +/* + * Compare VBUS voltage with given mdac reference voltage. + * returns non-zero if VBUS voltage >= (mdac + 1) * 420 mV + */ +static int fusb302_compare_mdac(int port, int mdac) +{ + int orig_reg, status0; + + mutex_lock(&measure_lock); + + /* backup REG_MEASURE */ + tcpc_read(port, TCPC_REG_MEASURE, &orig_reg); + /* set reg_measure bit 0~5 to mdac, and bit6 to 1(measure vbus) */ + tcpc_write(port, TCPC_REG_MEASURE, + (mdac & TCPC_REG_MEASURE_MDAC_MASK) | TCPC_REG_MEASURE_VBUS); + + /* Wait on measurement */ + usleep(350); + + /* + * Read status register, if STATUS0_COMP=1 then vbus is higher than + * (mdac + 1) * 0.42V + */ + tcpc_read(port, TCPC_REG_STATUS0, &status0); + /* write back original value */ + tcpc_write(port, TCPC_REG_MEASURE, orig_reg); + + mutex_unlock(&measure_lock); + + return status0 & TCPC_REG_STATUS0_COMP; +} + +int tcpc_get_vbus_voltage(int port) +{ + int mdac = 0, i; + + /* + * Implement by comparing VBUS with MDAC reference voltage, and binary + * search the value of MDAC. + * + * MDAC register has 6 bits, so we can simply search 1 bit per + * iteration, from MSB to LSB. + */ + for (i = 5; i >= 0; i--) { + if (fusb302_compare_mdac(port, mdac | BIT(i))) + mdac |= BIT(i); + } + + return (mdac + 1) * 420; +} + const struct tcpm_drv fusb302_tcpm_drv = { .init = &fusb302_tcpm_init, .release = &fusb302_tcpm_release, diff --git a/driver/tcpm/fusb302.h b/driver/tcpm/fusb302.h index b4a8599ea8..fee246aeb2 100644 --- a/driver/tcpm/fusb302.h +++ b/driver/tcpm/fusb302.h @@ -49,6 +49,7 @@ #define TCPC_REG_SWITCHES1_TXCC1_EN (1<<0) #define TCPC_REG_MEASURE 0x04 +#define TCPC_REG_MEASURE_MDAC_MASK 0x3F #define TCPC_REG_MEASURE_VBUS (1<<6) /* * MDAC reference voltage step size is 42 mV. Round our thresholds to reduce |