diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2017-10-09 10:01:57 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-11-13 10:57:37 -0800 |
commit | 20d7149b1956f9b487cfc46f6adeac137dd779c5 (patch) | |
tree | e0e2bbf12f7d5a2e262df64961c50755adc4d4b4 | |
parent | d6c836b4dacdce0f3279ac56d92e7cfd92fdf967 (diff) | |
download | chrome-ec-20d7149b1956f9b487cfc46f6adeac137dd779c5.tar.gz |
Fizz: Switch power source to BJ at G3/S5
This patch allows Fizz to switch the power source from a type-c
charger to a barrel jack adapter if the system is in S5.
BUG=b:38321259
BRANCH=none
TEST=Verify the following with 45W and 60W type-c chargers:
1. Boot Fizz with a type-c charger
2. Go to S5 if not already.
3. Plug in a BJ adapter. Fizz boots to S0 using BJ power.
Also verified other boot modes are not affected:
1. Auto boot on BJ insert
2. Auto boot on Type-C insert
3. Recovery boot on BJ
4. Recovery boot on Type-C
5. Stay off if it's previously S5
Change-Id: I86aa0fe6e403bcbacfe396997d897111ffcf8e74
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/706251
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | board/fizz/board.c | 33 | ||||
-rw-r--r-- | board/fizz/usb_pd_policy.c | 8 | ||||
-rw-r--r-- | common/charge_manager.c | 5 | ||||
-rw-r--r-- | include/charge_manager.h | 7 |
4 files changed, 45 insertions, 8 deletions
diff --git a/board/fizz/board.c b/board/fizz/board.c index ce0ff98920..918d38892d 100644 --- a/board/fizz/board.c +++ b/board/fizz/board.c @@ -71,20 +71,38 @@ static void tcpc_alert_event(enum gpio_signal signal) */ static int adp_in_state = 1; +static void adp_in_deferred(void); +DECLARE_DEFERRED(adp_in_deferred); static void adp_in_deferred(void) { - /* TODO: Switch power source from USB-C to BJ only if we're in S5. */ - struct charge_port_info cpi; + struct charge_port_info pi = { 0 }; int level = gpio_get_level(GPIO_ADP_IN_L); /* Debounce */ if (level == adp_in_state) return; - /* High = unplugged. Low = plugged. TODO: Set appropriate voltage. */ - cpi.voltage = level ? 0 : 19000; - /* Set to 0 to ensure charge manager will ignore it. */ - cpi.current = 0; - charge_manager_update_charge(CHARGE_SUPPLIER_DEDICATED, 1, &cpi); + if (!level) { + /* BJ is inserted but the voltage isn't effective because PU3 + * is still disabled. */ + pi.voltage = 19000; + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) { + /* If type-c voltage is higher than BJ voltage, PU3 will + * shut down due to reverse current protection. So, we + * need to lower the voltage first. */ + if (charge_manager_get_charger_voltage() > pi.voltage) { + pd_set_external_voltage_limit( + CHARGE_PORT_TYPEC0, pi.voltage); + hook_call_deferred(&adp_in_deferred_data, + ADP_DEBOUNCE_MS * MSEC); + return; + } + if (gpio_get_level(GPIO_POWER_RATE)) + pi.current = 4620; + else + pi.current = 3330; + } + } + charge_manager_update_charge(CHARGE_SUPPLIER_DEDICATED, 1, &pi); /* * Explicitly notifies the host that BJ is plugged or unplugged * (when running on a type-c adapter). @@ -92,7 +110,6 @@ static void adp_in_deferred(void) pd_send_host_event(PD_EVENT_POWER_CHANGE); adp_in_state = level; } -DECLARE_DEFERRED(adp_in_deferred); /* IRQ for BJ plug/unplug. It shouldn't be called if BJ is the power source. */ void adp_in(enum gpio_signal signal) diff --git a/board/fizz/usb_pd_policy.c b/board/fizz/usb_pd_policy.c index 39e47dd895..5dc807cc82 100644 --- a/board/fizz/usb_pd_policy.c +++ b/board/fizz/usb_pd_policy.c @@ -289,6 +289,14 @@ int board_set_active_charge_port(int port) break; case CHARGE_PORT_BARRELJACK : gpio_set_level(GPIO_AC_JACK_CHARGE_L, 0); + /* If this is switching from type-c to BJ, we have to wait until + * PU3 comes up to keep the system continuously powered. + * NX20P5090 datasheet says turn-on time for 20V is 29 msec. */ + if (active_port == CHARGE_PORT_TYPEC0) + msleep(30); + /* We don't check type-c voltage here. If it's higher than + * BJ voltage, we'll brown out due to the reverse current + * protection of PU3. */ gpio_set_level(GPIO_USB_C0_CHARGE_L, 1); gpio_disable_interrupt(GPIO_ADP_IN_L); break; diff --git a/common/charge_manager.c b/common/charge_manager.c index a068897620..4a6808b50f 100644 --- a/common/charge_manager.c +++ b/common/charge_manager.c @@ -995,6 +995,11 @@ int charge_manager_get_charger_current(void) return charge_current; } +int charge_manager_get_charger_voltage(void) +{ + return charge_voltage; +} + int charge_manager_get_power_limit_uw(void) { int current_ma = charge_current; diff --git a/include/charge_manager.h b/include/charge_manager.h index 6d5bacc2df..0f2624129e 100644 --- a/include/charge_manager.h +++ b/include/charge_manager.h @@ -162,6 +162,13 @@ int charge_manager_get_power_limit_uw(void); */ int charge_manager_get_charger_current(void); +/** + * Get the charger voltage (mV) value. + * + * @return Charger voltage (mV) or CHARGE_VOLTAGE_UNINITIALIZED. + */ +int charge_manager_get_charger_voltage(void); + #ifdef CONFIG_USB_PD_LOGGING /* Save power state log entry for the given port */ void charge_manager_save_log(int port); |