diff options
author | Aseda Aboagye <aaboagye@google.com> | 2017-11-14 12:54:06 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-12-05 18:00:35 -0800 |
commit | 864b0b661642836f26e3b7426f701283bc0a069d (patch) | |
tree | feda6279842790f534148998058b6fe85a72f83c /driver/ppc | |
parent | 39efbc3ada5545f6784e7d09b7c358684cb124fa (diff) | |
download | chrome-ec-864b0b661642836f26e3b7426f701283bc0a069d.tar.gz |
sn5s330: Clear interrupts and setup masks at init.
When the SN5S330 is powered initially, there will be certain events set
that will assert its interrupt line. As part of the initialization for
this part, we should clear all the pending interrupts and setup the
masks for the events that we care about.
This commit clears all interrupts at init time and masks all interrupts
except for overcurrent condition for PP1.
BUG=b:69139844
BRANCH=None
TEST=Flash zoombini; With nothing plugged in, verify that the interrupt
line is deasserted at boot.
TEST=Repeat the above test with a charger plugged in.
Change-Id: I7acc030184b76d6c38a729cb64658f71e376c819
Signed-off-by: Aseda Aboagye <aaboagye@google.com>
Reviewed-on: https://chromium-review.googlesource.com/783510
Commit-Ready: Aseda Aboagye <aaboagye@chromium.org>
Tested-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Shawn N <shawnn@chromium.org>
Diffstat (limited to 'driver/ppc')
-rw-r--r-- | driver/ppc/sn5s330.c | 92 | ||||
-rw-r--r-- | driver/ppc/sn5s330.h | 16 |
2 files changed, 106 insertions, 2 deletions
diff --git a/driver/ppc/sn5s330.c b/driver/ppc/sn5s330.c index 81efb290b8..ddd8299678 100644 --- a/driver/ppc/sn5s330.c +++ b/driver/ppc/sn5s330.c @@ -146,6 +146,7 @@ static int init_sn5s330(int idx) int retries; int i2c_port; int i2c_addr; + int reg; i2c_port = sn5s330_chips[idx].i2c_port; i2c_addr = sn5s330_chips[idx].i2c_addr; @@ -261,11 +262,98 @@ static int init_sn5s330(int idx) CPRINTS("Failed to turn off PP1 FET!"); } - /* Don't touch the PP2 FET yet if we're sysjumping. */ + /* + * Don't proceed with the rest of initialization if we're sysjumping. + * We would have already done this before. + */ if (system_jumped_to_this_image()) return EC_SUCCESS; - /* For PP2, check to see if we booted in dead battery mode. */ + /* Clear the digital reset bit. */ + status = i2c_read8(i2c_port, i2c_addr, SN5S330_INT_STATUS_REG4, + ®val); + if (status) { + CPRINTS("Failed to read INT_STATUS_REG4!"); + return status; + } + regval |= SN5S330_DIG_RES; + status = i2c_write8(i2c_port, i2c_addr, SN5S330_INT_STATUS_REG4, + regval); + if (status) { + CPRINTS("Failed to write INT_STATUS_REG4!"); + return status; + } + + /* + * Before turning on the PP2 FET, let's mask off all interrupts except + * for the PP1 overcurrent condition and then clear all pending + * interrupts. + * + * TODO(aaboagye): Unmask fast-role swap events once fast-role swap is + * implemented in the PD stack. + */ + + regval = ~SN5S330_ILIM_PP1_RISE_MASK; + status = i2c_write8(i2c_port, i2c_addr, SN5S330_INT_MASK_RISE_REG1, + regval); + if (status) { + CPRINTS("Failed to write INT_MASK_RISE1!"); + return status; + } + + regval = ~SN5S330_ILIM_PP1_FALL_MASK; + status = i2c_write8(i2c_port, i2c_addr, SN5S330_INT_MASK_FALL_REG1, + regval); + if (status) { + CPRINTS("Failed to write INT_MASK_FALL1!"); + return status; + } + + /* Now mask all the other interrupts. */ + status = i2c_write8(i2c_port, i2c_addr, SN5S330_INT_MASK_RISE_REG2, + 0xFF); + if (status) { + CPRINTS("Failed to write INT_MASK_RISE2!"); + return status; + } + + status = i2c_write8(i2c_port, i2c_addr, SN5S330_INT_MASK_FALL_REG2, + 0xFF); + if (status) { + CPRINTS("Failed to write INT_MASK_FALL2!"); + return status; + } + + status = i2c_write8(i2c_port, i2c_addr, SN5S330_INT_MASK_RISE_REG3, + 0xFF); + if (status) { + CPRINTS("Failed to write INT_MASK_RISE3!"); + return status; + } + + status = i2c_write8(i2c_port, i2c_addr, SN5S330_INT_MASK_FALL_REG3, + 0xFF); + if (status) { + CPRINTS("Failed to write INT_MASK_FALL3!"); + return status; + } + + /* Now clear any pending interrupts. */ + for (reg = SN5S330_INT_TRIP_RISE_REG1; + reg <= SN5S330_INT_TRIP_FALL_REG3; + reg++) { + status = i2c_write8(i2c_port, i2c_addr, reg, 0xFF); + if (status) { + CPRINTS("Failed to write reg 0x%2x!"); + return status; + } + } + + + /* + * For PP2, check to see if we booted in dead battery mode. If we + * booted in dead battery mode, the PP2 FET will already be enabled. + */ status = i2c_read8(i2c_port, i2c_addr, SN5S330_INT_STATUS_REG4, ®val); if (status) { diff --git a/driver/ppc/sn5s330.h b/driver/ppc/sn5s330.h index c4aa5fb81b..b3d6c45bee 100644 --- a/driver/ppc/sn5s330.h +++ b/driver/ppc/sn5s330.h @@ -101,7 +101,23 @@ enum sn5s330_pp_idx { #define SN5S330_OVP_EN_CC (1 << 4) /* INT_STATUS_REG4 */ +#define SN5S330_DIG_RES (1 << 0) #define SN5S330_DB_BOOT (1 << 1) +#define SN5S330_VSAFE0V_STAT (1 << 2) +#define SN5S330_VSAFE0V_MASK (1 << 3) + +/* + * INT_MASK_RISE_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) + +/* INT_MASK_FALL_EDGE_1 */ +#define SN5S330_ILIM_PP1_FALL_MASK (1 << 4) /** * Turn on/off the PP1 or PP2 FET. |