summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/battery.c82
-rw-r--r--include/config.h6
-rw-r--r--zephyr/Kconfig.battery10
-rw-r--r--zephyr/shim/include/config_chip.h7
4 files changed, 105 insertions, 0 deletions
diff --git a/common/battery.c b/common/battery.c
index eefb662eef..7200786f50 100644
--- a/common/battery.c
+++ b/common/battery.c
@@ -6,6 +6,7 @@
*/
#include "battery.h"
+#include "charge_manager.h"
#include "charge_state.h"
#include "common.h"
#include "console.h"
@@ -15,6 +16,7 @@
#include "hooks.h"
#include "host_command.h"
#include "timer.h"
+#include "usb_pd.h"
#include "util.h"
#include "watchdog.h"
@@ -670,3 +672,83 @@ int battery_manufacturer_name(char *dest, int size)
{
return get_battery_manufacturer_name(dest, size);
}
+
+#ifdef CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV
+
+#if CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV < 5000 || \
+ CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV >= PD_MAX_VOLTAGE_MV
+ #error "Voltage limit must be between 5000 and PD_MAX_VOLTAGE_MV"
+#endif
+
+#if !((defined(CONFIG_USB_PD_TCPMV1) && defined(CONFIG_USB_PD_DUAL_ROLE)) || \
+ (defined(CONFIG_USB_PD_TCPMV2) && defined(CONFIG_USB_PE_SM)))
+ #error "Voltage reducing requires TCPM with Policy Engine"
+#endif
+
+/*
+ * Returns true if input voltage should be reduced (chipset is in S5/G3) and
+ * battery is full, otherwise returns false
+ */
+static bool board_wants_reduced_input_voltage(void) {
+ struct batt_params batt;
+
+ /* Chipset not in S5/G3, so we don't want to reduce voltage */
+ if (!chipset_in_or_transitioning_to_state(CHIPSET_STATE_ANY_OFF))
+ return false;
+
+ battery_get_params(&batt);
+
+ /* Battery needs charge, so we don't want to reduce voltage */
+ if (batt.flags & BATT_FLAG_WANT_CHARGE)
+ return false;
+
+ return true;
+}
+
+static void reduce_input_voltage_when_full(void)
+{
+ static int saved_input_voltage = -1;
+ int max_pd_voltage_mv = pd_get_max_voltage();
+ int port;
+
+ port = charge_manager_get_active_charge_port();
+ if (port < 0 || port >= board_get_usb_pd_port_count())
+ return;
+
+ if (board_wants_reduced_input_voltage()) {
+ /*
+ * Board wants voltage to be reduced. Apply limit if current
+ * voltage is different. Save current voltage, it will be
+ * restored when board wants to stop reducing input voltage.
+ */
+ if (max_pd_voltage_mv !=
+ CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV) {
+ saved_input_voltage = max_pd_voltage_mv;
+ max_pd_voltage_mv =
+ CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV;
+ }
+ } else if (saved_input_voltage != -1) {
+ /*
+ * Board doesn't want to reduce input voltage. If current
+ * voltage is reduced we will restore previously saved voltage.
+ * If current voltage is different we will respect newer value.
+ */
+ if (max_pd_voltage_mv ==
+ CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV)
+ max_pd_voltage_mv = saved_input_voltage;
+
+ saved_input_voltage = -1;
+ }
+
+ if (pd_get_max_voltage() != max_pd_voltage_mv)
+ pd_set_external_voltage_limit(port, max_pd_voltage_mv);
+}
+DECLARE_HOOK(HOOK_AC_CHANGE, reduce_input_voltage_when_full,
+ HOOK_PRIO_DEFAULT);
+DECLARE_HOOK(HOOK_BATTERY_SOC_CHANGE, reduce_input_voltage_when_full,
+ HOOK_PRIO_DEFAULT);
+DECLARE_HOOK(HOOK_CHIPSET_STARTUP, reduce_input_voltage_when_full,
+ HOOK_PRIO_DEFAULT);
+DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, reduce_input_voltage_when_full,
+ HOOK_PRIO_DEFAULT);
+#endif
diff --git a/include/config.h b/include/config.h
index 7e0e277c78..ef029f2b45 100644
--- a/include/config.h
+++ b/include/config.h
@@ -619,6 +619,12 @@
#undef CONFIG_BATTERY_MEASURE_IMBALANCE
/*
+ * Some boards needs to lower input voltage when battery is full and chipset
+ * is in S5/G3. This should be defined to integer value in mV.
+ */
+#undef CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV
+
+/*
* If remaining capacity is x% of full capacity, remaining capacity is set
* equal to full capacity.
*
diff --git a/zephyr/Kconfig.battery b/zephyr/Kconfig.battery
index e474afd5ff..b972ed40e0 100644
--- a/zephyr/Kconfig.battery
+++ b/zephyr/Kconfig.battery
@@ -248,4 +248,14 @@ config PLATFORM_EC_BATTERY_REVIVE_DISCONNECT
this state by force-applying a charge current. Once defined,
a battery_get_disconnect_state() function has to be provided.
+config PLATFORM_EC_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV
+ int "Voltage limit in mV when battery is full and AP is off"
+ depends on PLATFORM_EC_USB_PE_SM && PLATFORM_EC_CHARGE_MANAGER
+ default -1
+ help
+ If set to a non-negative value, input voltage will be reduced to given
+ value when chipset is in S5/G3 state and battery is fully charged.
+ This condition is checked on chipset shutdown and startup, AC change
+ and battery SOC change.
+
endif # PLATFORM_EC_BATTERY
diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h
index d2aa0d8e5b..4ee6fb6773 100644
--- a/zephyr/shim/include/config_chip.h
+++ b/zephyr/shim/include/config_chip.h
@@ -176,6 +176,13 @@
#define CONFIG_BATTERY_REVIVE_DISCONNECT
#endif
+#undef CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV
+#if defined(CONFIG_PLATFORM_EC_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV) && \
+ (CONFIG_PLATFORM_EC_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV > 0)
+#define CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV \
+ CONFIG_PLATFORM_EC_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV
+#endif
+
#undef CONFIG_BOARD_RESET_AFTER_POWER_ON
#ifdef CONFIG_PLATFORM_EC_BOARD_RESET_AFTER_POWER_ON
#define CONFIG_BOARD_RESET_AFTER_POWER_ON