Skip to content

Commit 75388a1

Browse files
LeoCX-Tsaiquinchou77
authored andcommitted
fwk: lotus: ensure charge mode change to avoid system damage
when switching EPR ports directly always make sure the charger has exited bypass mode to avoid transients being passed to the system BRANCH=fwk-tulip-29169 BUG=https://app.clickup.com/t/86euznxv4 TEST=follow clickup reproduce steps, 240w adp connect to top right port, 180w adp connect to middle right port unplug 240w adp check the screen won't flash Signed-off-by: LeoCX_Tsai <LeoCX_Tsai@compal.com>
1 parent 5bd3e6f commit 75388a1

5 files changed

Lines changed: 74 additions & 36 deletions

File tree

zephyr/program/framework/include/board_charger.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ enum ec_prochot_status {
5353
int update_charger_in_cutoff_mode(void);
5454

5555
#ifdef CONFIG_BOARD_LOTUS
56-
int charger_in_bypass_mode(void);
5756
void board_charger_lpm_control(int enable);
57+
void board_disable_bypass_oneshot(void);
5858
#endif
5959

6060
#ifdef CONFIG_CHARGER_DYNAMIC_ACOK_REFERENCE

zephyr/program/framework/lotus/src/charger.c

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -344,29 +344,62 @@ DECLARE_HOOK(HOOK_BATTERY_SOC_CHANGE, charger_update, HOOK_PRIO_DEFAULT);
344344

345345
static bool bypass_force_en;
346346
static bool bypass_force_disable;
347+
348+
static int bypass_force_disable_oneshot;
349+
void board_disable_bypass_oneshot(void)
350+
{
351+
bypass_force_disable_oneshot = 2;
352+
}
353+
347354
__override int board_should_charger_bypass(void)
348355
{
349356
int power_uw = charge_manager_get_power_limit_uw();
350357
int voltage_mv = charge_manager_get_charger_voltage();
351358
int curr_batt = battery_is_present();
359+
int ret;
360+
const char *reason = "";
352361

353-
if (bypass_force_en)
354-
return true;
362+
if (bypass_force_en) {
363+
ret = true;
364+
reason = "forcen";
365+
goto board_exit;
366+
}
355367

356-
if (bypass_force_disable)
357-
return false;
368+
if (bypass_force_disable) {
369+
ret = false;
370+
reason = "forcedis";
371+
goto board_exit;
372+
}
373+
374+
if (bypass_force_disable_oneshot) {
375+
bypass_force_disable_oneshot--;
376+
ret = false;
377+
reason = "oneshot";
378+
goto board_exit;
379+
}
358380

359381
if (curr_batt == BP_YES) {
360-
if (power_uw > 100000000)
361-
return true;
362-
else
363-
return false;
382+
if (power_uw > 100000000) {
383+
ret = true;
384+
reason = "power";
385+
goto board_exit;
386+
} else {
387+
ret = false;
388+
goto board_exit;
389+
}
364390
} else {
365-
if (voltage_mv > 20000)
366-
return true;
367-
else
368-
return false;
391+
if (voltage_mv > 20000) {
392+
ret = true;
393+
reason = "volt";
394+
goto board_exit;
395+
} else {
396+
ret = false;
397+
goto board_exit;
398+
}
369399
}
400+
board_exit:
401+
402+
return ret;
370403
}
371404

372405
int board_want_change_mode(void)
@@ -381,24 +414,6 @@ int board_want_change_mode(void)
381414
return false;
382415
}
383416

384-
int charger_in_bypass_mode(void)
385-
{
386-
int reg;
387-
int rv;
388-
389-
rv = i2c_read16(I2C_PORT_CHARGER, ISL9241_ADDR_FLAGS, ISL9241_REG_CONTROL0, &reg);
390-
391-
/* read register fail */
392-
if (rv)
393-
return 0;
394-
395-
/* charer not enter bypass mode */
396-
if ((reg & ISL9241_CONTROL0_EN_BYPASS_GATE) != ISL9241_CONTROL0_EN_BYPASS_GATE)
397-
return 0;
398-
399-
return 1;
400-
}
401-
402417
int board_discharge_on_ac(int enable)
403418
{
404419
int chgnum;

zephyr/program/framework/lotus/src/cpu_power.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include "throttle_ap.h"
2424
#include "util.h"
2525
#include "gpu.h"
26-
26+
#include "driver/charger/isl9241_public.h"
2727

2828
#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args)
2929
#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args)
@@ -347,7 +347,7 @@ void clear_prochot(enum clear_reasons reason)
347347
if (events & BIT(PD_PROGRESS_ENTER_EPR_MODE) && (cypd_get_ac_power() > 100000)) {
348348
/* wait charger to entry the bypass mode */
349349
#ifdef CONFIG_BOARD_LOTUS
350-
if (charger_in_bypass_mode())
350+
if (isl9241_is_in_bypass_mode(0))
351351
update_pmf_events(BIT(PD_PROGRESS_ENTER_EPR_MODE), 0);
352352
#else
353353
update_pmf_events(BIT(PD_PROGRESS_ENTER_EPR_MODE), 0);
@@ -468,7 +468,7 @@ void update_soc_power_limit(bool force_update, bool force_no_adapter)
468468
}
469469

470470
#ifdef CONFIG_BOARD_LOTUS
471-
if (force_update && charger_in_bypass_mode() && !get_gpu_gpio(GPIO_FUNC_ACDC))
471+
if (force_update && isl9241_is_in_bypass_mode(0) && !get_gpu_gpio(GPIO_FUNC_ACDC))
472472
set_gpu_gpio(GPIO_FUNC_ACDC, 1);
473473
#else
474474
if (force_update && !get_gpu_gpio(GPIO_FUNC_ACDC))

zephyr/program/framework/src/cypd_ccg8.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ void exit_epr_mode(void)
717717
CCG_PD_CONTROL_REG(PORT_TO_CONTROLLER_PORT(port_idx)),
718718
CCG_PD_CMD_INITIATE_EPR_EXIT);
719719

720-
hook_call_deferred(&epr_flow_pending_deferred_data, 500 * MSEC);
720+
hook_call_deferred(&epr_flow_pending_deferred_data, 1000 * MSEC);
721721
#endif
722722
}
723723
}

zephyr/program/framework/src/cypress_pd_common.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#ifdef CONFIG_PLATFORM_EC_FRAMEWORK_LAPTOP_16
3636
#include "gpu.h"
3737
#include "cpu_power.h"
38+
#include "board_charger.h"
3839
#endif
3940

4041
#include <zephyr/sys_clock.h>
@@ -1359,6 +1360,7 @@ void cypd_update_port_state(int controller, int port)
13591360
*/
13601361
cypd_ccd_mode_control();
13611362
#endif
1363+
charge_wakeup();
13621364
}
13631365

13641366
void cypd_set_power_state(int power_state, int controller)
@@ -1618,6 +1620,9 @@ int board_set_active_charge_port(int charge_port)
16181620
* so we need to turn on the vbus control again.
16191621
*/
16201622
cypd_cfet_vbus_control(charge_port, true, true);
1623+
#ifdef CONFIG_BOARD_LOTUS
1624+
board_disable_bypass_oneshot();
1625+
#endif
16211626
return EC_SUCCESS;
16221627
}
16231628

@@ -1626,6 +1631,19 @@ int board_set_active_charge_port(int charge_port)
16261631
prev_charge_port != charge_port) {
16271632
/* Turn off the previous charge port before turning on the next port */
16281633
cypd_cfet_vbus_control(prev_charge_port, false, true);
1634+
#ifdef CONFIG_BOARD_LOTUS
1635+
board_disable_bypass_oneshot();
1636+
1637+
if (isl9241_is_in_bypass_mode(0)) {
1638+
CPRINTS("Force exit bypass mode for port switch");
1639+
if (chg_chips[0].drv->enable_bypass_mode)
1640+
chg_chips[0].drv->enable_bypass_mode(0, false);
1641+
/* ACOK threshold has been lowered, give the charger some time to
1642+
* discharge the input caps before switching to the new port
1643+
*/
1644+
crec_usleep(8*MSEC);
1645+
}
1646+
#endif
16291647
}
16301648

16311649
for (i = 0; i < PD_PORT_COUNT; i++) {
@@ -1669,7 +1687,12 @@ int cypd_get_ac_power(void)
16691687

16701688
ac_power_mW = (pd_port_states[prev_charge_port].current
16711689
* pd_port_states[prev_charge_port].voltage);
1672-
1690+
#ifdef CONFIG_BOARD_LOTUS
1691+
if (!isl9241_is_in_bypass_mode(0)) {
1692+
/* limit to 100W if not in bypass mode */
1693+
ac_power_mW = MIN(100000000, ac_power_mW);
1694+
}
1695+
#endif
16731696
return (ac_power_mW / 1000);
16741697
}
16751698

0 commit comments

Comments
 (0)