diff options
author | Aseda Aboagye <aaboagye@google.com> | 2017-11-27 10:19:09 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-12-05 18:00:36 -0800 |
commit | 0a5e908467b5f5169a7197bbe7b327e06432d4cf (patch) | |
tree | a3927ccf65f15ca6095296a897ed4ebd5c800249 /driver | |
parent | 864b0b661642836f26e3b7426f701283bc0a069d (diff) | |
download | chrome-ec-0a5e908467b5f5169a7197bbe7b327e06432d4cf.tar.gz |
ppc: sn5s330: Add API to determine if FET is on.
It will be useful to determine if a FET is enabled or not. For example,
to determine if we are sourcing power to a downstream device. This
commit simply adds an API to check if a FET is enabled or not.
BUG=None
BRANCH=None
TEST=`make -j buildall`
Change-Id: I1f8198342cf225ce9a10d218607bcfbe6aef618c
Signed-off-by: Aseda Aboagye <aaboagye@google.com>
Reviewed-on: https://chromium-review.googlesource.com/791498
Commit-Ready: Aseda Aboagye <aaboagye@chromium.org>
Tested-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Edward Hill <ecgh@chromium.org>
Reviewed-by: Shawn N <shawnn@chromium.org>
Diffstat (limited to 'driver')
-rw-r--r-- | driver/ppc/sn5s330.c | 78 | ||||
-rw-r--r-- | driver/ppc/sn5s330.h | 16 |
2 files changed, 75 insertions, 19 deletions
diff --git a/driver/ppc/sn5s330.c b/driver/ppc/sn5s330.c index ddd8299678..9871209e76 100644 --- a/driver/ppc/sn5s330.c +++ b/driver/ppc/sn5s330.c @@ -22,6 +22,28 @@ #define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +static int read_reg(uint8_t chip_idx, int reg, int *regval) +{ + if (chip_idx >= sn5s330_cnt) + return EC_ERROR_INVAL; + + return i2c_read8(sn5s330_chips[chip_idx].i2c_port, + sn5s330_chips[chip_idx].i2c_addr, + reg, + regval); +} + +static int write_reg(uint8_t chip_idx, int reg, int regval) +{ + if (chip_idx >= sn5s330_cnt) + return EC_ERROR_INVAL; + + return i2c_write8(sn5s330_chips[chip_idx].i2c_port, + sn5s330_chips[chip_idx].i2c_addr, + reg, + regval); +} + #ifdef CONFIG_CMD_PPC_DUMP static int command_sn5s330_dump(int argc, char **argv) { @@ -99,13 +121,23 @@ DECLARE_CONSOLE_COMMAND(ppc_dump, command_sn5s330_dump, "<Type-C port>", "dump the SN5S330 regs"); #endif /* defined(CONFIG_CMD_PPC_DUMP) */ -int sn5s330_pp_fet_enable(uint8_t chip_idx, enum sn5s330_pp_idx pp, int enable) +static int get_func_set3(uint8_t chip_idx, int *regval) { - int regval; int status; + + status = read_reg(chip_idx, SN5S330_FUNC_SET3, regval); + if (status) + CPRINTS("Failed to read FUNC_SET3!"); + + return status; +} + +int sn5s330_is_pp_fet_enabled(uint8_t chip_idx, enum sn5s330_pp_idx pp, + int *is_enabled) +{ int pp_bit; - int port; - int addr; + int status; + int regval; if (pp == SN5S330_PP1) { pp_bit = SN5S330_PP1_EN; @@ -116,21 +148,38 @@ int sn5s330_pp_fet_enable(uint8_t chip_idx, enum sn5s330_pp_idx pp, int enable) return EC_ERROR_INVAL; } - port = sn5s330_chips[chip_idx].i2c_port; - addr = sn5s330_chips[chip_idx].i2c_addr; + status = get_func_set3(chip_idx, ®val); + if (status) + return status; - status = i2c_read8(port, addr, SN5S330_FUNC_SET3, ®val); - if (status) { - CPRINTS("Failed to read FUNC_SET3!"); + *is_enabled = !!(pp_bit & regval); + + return EC_SUCCESS; +} + +int sn5s330_pp_fet_enable(uint8_t chip_idx, enum sn5s330_pp_idx pp, int enable) +{ + int regval; + int status; + int pp_bit; + + if (pp == SN5S330_PP1) + pp_bit = SN5S330_PP1_EN; + else if (pp == SN5S330_PP2) + pp_bit = SN5S330_PP2_EN; + else + return EC_ERROR_INVAL; + + status = get_func_set3(chip_idx, ®val); + if (status) return status; - } if (enable) regval |= pp_bit; else regval &= ~pp_bit; - status = i2c_write8(port, addr, SN5S330_FUNC_SET3, regval); + status = write_reg(chip_idx, SN5S330_FUNC_SET3, regval); if (status) { CPRINTS("Failed to set FUNC_SET3!"); return status; @@ -208,7 +257,7 @@ static int init_sn5s330(int idx) return status; } - /* TODO(aaboagye): What about Vconn */ + /* TODO(aaboagye): What about Vconn? */ /* * Indicate we are using PP2 configuration 2 and enable OVP comparator @@ -293,7 +342,7 @@ static int init_sn5s330(int idx) * implemented in the PD stack. */ - regval = ~SN5S330_ILIM_PP1_RISE_MASK; + regval = ~SN5S330_ILIM_PP1_MASK; status = i2c_write8(i2c_port, i2c_addr, SN5S330_INT_MASK_RISE_REG1, regval); if (status) { @@ -301,7 +350,6 @@ static int init_sn5s330(int idx) return status; } - regval = ~SN5S330_ILIM_PP1_FALL_MASK; status = i2c_write8(i2c_port, i2c_addr, SN5S330_INT_MASK_FALL_REG1, regval); if (status) { @@ -390,4 +438,4 @@ static void sn5s330_init(void) CPRINTS("C%d: SN5S330 init failed! (%d)", i, rv); } } -DECLARE_HOOK(HOOK_INIT, sn5s330_init, HOOK_PRIO_LAST); +DECLARE_HOOK(HOOK_INIT, sn5s330_init, HOOK_PRIO_INIT_I2C + 1); diff --git a/driver/ppc/sn5s330.h b/driver/ppc/sn5s330.h index b3d6c45bee..f1bea3da46 100644 --- a/driver/ppc/sn5s330.h +++ b/driver/ppc/sn5s330.h @@ -107,17 +107,25 @@ enum sn5s330_pp_idx { #define SN5S330_VSAFE0V_MASK (1 << 3) /* - * INT_MASK_RISE_EDGE_1 + * INT_MASK_RISE/FALL_EDGE_1 * * The ILIM_PP1 bit indicates an overcurrent condition when sourcing on power * path 1. For rising edge registers, this indicates an overcurrent has * occured; similarly for falling edge, it means the overcurrent condition is no * longer present. */ -#define SN5S330_ILIM_PP1_RISE_MASK (1 << 4) +#define SN5S330_ILIM_PP1_MASK (1 << 4) -/* INT_MASK_FALL_EDGE_1 */ -#define SN5S330_ILIM_PP1_FALL_MASK (1 << 4) +/** + * Determine if a PP FET is enabled or not. + * + * @param chip_idx: The index into the sn5s330_chips[] table. + * @param pp: The power path index (PP1 or PP2). + * @param is_enabled: 1 to turn on the FET, 0 to turn off. + * @return EC_SUCCESS if i2c access worked, otherwise an error. + */ +int sn5s330_is_pp_fet_enabled(uint8_t chip_idx, enum sn5s330_pp_idx pp, + int *is_enabled); /** * Turn on/off the PP1 or PP2 FET. |