summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2021-05-28 10:48:14 -0700
committerCommit Bot <commit-bot@chromium.org>2021-08-20 08:09:33 +0000
commit25ad1dc47f68828d5b30240c21a1c2ab0747c1eb (patch)
tree30cf1dc986218e1f93c6b7d774d821ff3f56a2af
parent84b0f9330e78bc7bb5d077c10ea403f66617ea72 (diff)
downloadchrome-ec-25ad1dc47f68828d5b30240c21a1c2ab0747c1eb.tar.gz
Update EC_CMD_CHARGE_CONTROL to version 2
Version 2 of EC_CMD_CHARGE_CONTROL can control battery sustainer. It allows the host to set the upper and lower thresholds between which the EC tries to keep the battery state of charge. Version 2 of EC_CMD_CHARGE_CONTROL also supports 'GET' request. It allows the host to query the current charge control settings. localhost ~ # ectool chargecontrol Charge mode = NORMAL (0) Battery sustainer = off (-1% ~ -1%) localhost ~ # ectool chargecontrol normal 66 66 Charge state machine is in normal mode with sustainer enabled. localhost ~ # ectool chargecontrol Charge mode = NORMAL (0) Battery sustainer = on (66% ~ 66%) localhost ~ # ectool chargecontrol normal Charge state machine is in normal mode. BUG=b:188457962 BRANCH=none TEST=Atlas. See above. Change-Id: I81ec62172b4f159c46334fc0f940a2adae3f2b8a Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2929340 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3105737 Reviewed-by: caveh jalali <caveh@chromium.org>
-rw-r--r--common/charge_state_v2.c64
-rw-r--r--include/charge_state_v2.h5
-rw-r--r--include/ec_commands.h39
-rw-r--r--test/genvif/vif_output/exp_test_over_vif.xml91
-rw-r--r--test/genvif/vif_output/exp_test_vif.xml90
-rw-r--r--test/genvif/vif_output/test_over_vif.xml91
-rw-r--r--test/genvif/vif_output/test_vif.xml90
-rw-r--r--util/ectool.c91
8 files changed, 552 insertions, 9 deletions
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index bd4bb81558..6bdb4df533 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -23,6 +23,7 @@
#include "i2c.h"
#include "math_util.h"
#include "printf.h"
+#include "stdbool.h"
#include "system.h"
#include "task.h"
#include "throttle_ap.h"
@@ -87,6 +88,7 @@ static int manual_current; /* Manual current override (-1 = no override) */
static unsigned int user_current_limit = -1U;
test_export_static timestamp_t shutdown_warning_time;
static timestamp_t precharge_start_time;
+static struct sustain_soc sustain_soc;
#ifdef CONFIG_EC_EC_COMM_BATTERY_MASTER
static int base_connected;
@@ -178,6 +180,38 @@ static void problem(enum problem_type p, int v)
problems_exist = 1;
}
+static int battery_sustainer_set(int8_t lower, int8_t upper)
+{
+ if (lower == -1 || upper == -1) {
+ CPRINTS("Sustain mode disabled");
+ sustain_soc.lower = -1;
+ sustain_soc.upper = -1;
+ return EC_SUCCESS;
+ }
+
+ if (lower <= upper && 0 <= lower && upper <= 100) {
+ /* Currently sustainer requires discharge_on_ac. */
+ if (!IS_ENABLED(CONFIG_CHARGER_DISCHARGE_ON_AC))
+ return EC_RES_UNAVAILABLE;
+ sustain_soc.lower = lower;
+ sustain_soc.upper = upper;
+ return EC_SUCCESS;
+ }
+
+ CPRINTS("Invalid param: %s(%d, %d)", __func__, lower, upper);
+ return EC_ERROR_INVAL;
+}
+
+static void battery_sustainer_disable(void)
+{
+ battery_sustainer_set(-1, -1);
+}
+
+static bool battery_sustainer_enabled(void)
+{
+ return sustain_soc.lower != -1 && sustain_soc.upper != -1;
+}
+
#ifdef CONFIG_EC_EC_COMM_BATTERY_MASTER
/*
* Parameters for dual-battery policy.
@@ -1069,6 +1103,9 @@ static void dump_charge_state(void)
battery_seems_to_be_disconnected);
ccprintf("battery_was_removed = %d\n", battery_was_removed);
ccprintf("debug output = %s\n", debugging ? "on" : "off");
+ ccprintf("Battery sustainer = %s (%d%% ~ %d%%)\n",
+ battery_sustainer_enabled() ? "on" : "off",
+ sustain_soc.lower, sustain_soc.upper);
#undef DUMP
}
@@ -2229,8 +2266,33 @@ int charge_set_input_current_limit(int ma, int mv)
static int charge_command_charge_control(struct host_cmd_handler_args *args)
{
const struct ec_params_charge_control *p = args->params;
+ struct ec_response_charge_control *r = args->response;
int rv;
+ if (args->version >= 2) {
+ if (p->cmd == EC_CHARGE_CONTROL_CMD_SET) {
+ if (chg_ctl_mode == CHARGE_CONTROL_NORMAL) {
+ rv = battery_sustainer_set(
+ p->sustain_soc.lower,
+ p->sustain_soc.upper);
+ if (rv == EC_RES_UNAVAILABLE)
+ return EC_RES_UNAVAILABLE;
+ if (rv)
+ return EC_RES_INVALID_PARAM;
+ } else {
+ battery_sustainer_disable();
+ }
+ } else if (p->cmd == EC_CHARGE_CONTROL_CMD_GET) {
+ r->mode = chg_ctl_mode;
+ r->sustain_soc.lower = sustain_soc.lower;
+ r->sustain_soc.upper = sustain_soc.upper;
+ args->response_size = sizeof(*r);
+ return EC_RES_SUCCESS;
+ } else {
+ return EC_RES_INVALID_PARAM;
+ }
+ }
+
rv = set_chg_ctrl_mode(p->mode);
if (rv != EC_SUCCESS)
return EC_RES_ERROR;
@@ -2248,7 +2310,7 @@ static int charge_command_charge_control(struct host_cmd_handler_args *args)
return EC_RES_SUCCESS;
}
DECLARE_HOST_COMMAND(EC_CMD_CHARGE_CONTROL, charge_command_charge_control,
- EC_VER_MASK(1));
+ EC_VER_MASK(1) | EC_VER_MASK(2));
static void reset_current_limit(void)
{
diff --git a/include/charge_state_v2.h b/include/charge_state_v2.h
index e3a43d8bcf..a649fb9c2e 100644
--- a/include/charge_state_v2.h
+++ b/include/charge_state_v2.h
@@ -47,6 +47,11 @@ struct charge_state_data {
#endif
};
+struct sustain_soc {
+ int8_t lower;
+ int8_t upper;
+};
+
/**
* Set the output current limit and voltage. This is used to provide power from
* the charger chip ("OTG" mode).
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 12eb453ccb..cf45e682f8 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -3889,7 +3889,7 @@ struct ec_params_i2c_write {
* discharge the battery.
*/
#define EC_CMD_CHARGE_CONTROL 0x0096
-#define EC_VER_CHARGE_CONTROL 1
+#define EC_VER_CHARGE_CONTROL 2
enum ec_charge_control_mode {
CHARGE_CONTROL_NORMAL = 0,
@@ -3897,8 +3897,45 @@ enum ec_charge_control_mode {
CHARGE_CONTROL_DISCHARGE,
};
+#define EC_CHARGE_MODE_TEXT { \
+ [CHARGE_CONTROL_NORMAL] = "NORMAL", \
+ [CHARGE_CONTROL_IDLE] = "IDLE", \
+ [CHARGE_CONTROL_DISCHARGE] = "DISCHARGE", \
+ }
+
+enum ec_charge_control_cmd {
+ EC_CHARGE_CONTROL_CMD_SET = 0,
+ EC_CHARGE_CONTROL_CMD_GET,
+};
+
struct ec_params_charge_control {
uint32_t mode; /* enum charge_control_mode */
+
+ /* Below are the fields added in V2. */
+ uint8_t cmd; /* enum ec_charge_control_cmd. */
+ uint8_t reserved;
+ /*
+ * Lower and upper thresholds for battery sustainer. This struct isn't
+ * named to avoid tainting foreign projects' name spaces.
+ *
+ * If charge mode is explicitly set (e.g. DISCHARGE), battery sustainer
+ * will be disabled. To disable battery sustainer, set mode=NORMAL,
+ * lower=-1, upper=-1.
+ */
+ struct {
+ int8_t lower; /* Display SoC in percentage. */
+ int8_t upper; /* Display SoC in percentage. */
+ } sustain_soc;
+} __ec_align4;
+
+/* Added in v2 */
+struct ec_response_charge_control {
+ uint32_t mode; /* enum charge_control_mode */
+ struct { /* Battery sustainer thresholds */
+ int8_t lower;
+ int8_t upper;
+ } sustain_soc;
+ uint16_t reserved;
} __ec_align4;
/*****************************************************************************/
diff --git a/test/genvif/vif_output/exp_test_over_vif.xml b/test/genvif/vif_output/exp_test_over_vif.xml
new file mode 100644
index 0000000000..e15c68c1b0
--- /dev/null
+++ b/test/genvif/vif_output/exp_test_over_vif.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VIF xmlns="http://usb.org/VendorInfoFile.xsd">
+ <VIF_Specification>3.12</VIF_Specification>
+ <VIF_App>
+ <Vendor>Google</Vendor>
+ <Name>EC GENVIF</Name>
+ <Version>3.0.0.10</Version>
+ </VIF_App>
+ <Vendor_Name>Google</Vendor_Name>
+ <Model_Part_Number>SuperTestWithOverride</Model_Part_Number>
+ <Product_Revision>Final</Product_Revision>
+ <TID>12345</TID>
+ <VIF_Product_Type value="0">Port Product</VIF_Product_Type>
+ <Certification_Type value="0">End Product</Certification_Type>
+ <Product>
+ <Product_VID value="6353">18D1</Product_VID>
+ </Product>
+ <Component>
+ <Port_Label>0</Port_Label>
+ <Connector_Type value="2">Type-C®</Connector_Type>
+ <USB4_Supported value="false">NO</USB4_Supported>
+ <USB_PD_Support value="true">YES</USB_PD_Support>
+ <PD_Port_Type value="4">DRP</PD_Port_Type>
+ <Type_C_State_Machine value="2">DRP</Type_C_State_Machine>
+ <Captive_Cable value="false">NO</Captive_Cable>
+ <Port_Battery_Powered value="false">NO</Port_Battery_Powered>
+ <BC_1_2_Support value="0">None</BC_1_2_Support>
+ <PD_Spec_Revision_Major value="3" />
+ <PD_Spec_Revision_Minor value="0" />
+ <PD_Spec_Version_Major value="2" />
+ <PD_Spec_Version_Minor value="0" />
+ <PD_Specification_Revision value="2">Revision 3</PD_Specification_Revision>
+ <USB_Comms_Capable value="true">YES</USB_Comms_Capable>
+ <DR_Swap_To_DFP_Supported value="true">YES</DR_Swap_To_DFP_Supported>
+ <DR_Swap_To_UFP_Supported value="false">NO</DR_Swap_To_UFP_Supported>
+ <Unconstrained_Power value="false">NO</Unconstrained_Power>
+ <VCONN_Swap_To_On_Supported value="false">NO</VCONN_Swap_To_On_Supported>
+ <VCONN_Swap_To_Off_Supported value="false">NO</VCONN_Swap_To_Off_Supported>
+ <Responds_To_Discov_SOP_UFP value="false">NO</Responds_To_Discov_SOP_UFP>
+ <Responds_To_Discov_SOP_DFP value="false">NO</Responds_To_Discov_SOP_DFP>
+ <Attempts_Discov_SOP value="true">YES</Attempts_Discov_SOP>
+ <Chunking_Implemented_SOP value="false">NO</Chunking_Implemented_SOP>
+ <Unchunked_Extended_Messages_Supported value="false">NO</Unchunked_Extended_Messages_Supported>
+ <Manufacturer_Info_Supported_Port value="false">NO</Manufacturer_Info_Supported_Port>
+ <Security_Msgs_Supported_SOP value="false">NO</Security_Msgs_Supported_SOP>
+ <Num_Fixed_Batteries value="1" />
+ <Num_Swappable_Battery_Slots value="0" />
+ <ID_Header_Connector_Type_SOP value="2">USB Type-C® Receptacle</ID_Header_Connector_Type_SOP>
+ <SOP_Capable value="true">YES</SOP_Capable>
+ <SOP_P_Capable value="false">NO</SOP_P_Capable>
+ <SOP_PP_Capable value="false">NO</SOP_PP_Capable>
+ <SOP_P_Debug_Capable value="false">NO</SOP_P_Debug_Capable>
+ <SOP_PP_Debug_Capable value="false">NO</SOP_PP_Debug_Capable>
+ <Type_C_Implements_Try_SRC value="false">NO</Type_C_Implements_Try_SRC>
+ <Type_C_Implements_Try_SNK value="false">NO</Type_C_Implements_Try_SNK>
+ <RP_Value value="1">1.5A</RP_Value>
+ <Type_C_Is_VCONN_Powered_Accessory value="false">NO</Type_C_Is_VCONN_Powered_Accessory>
+ <Type_C_Is_Debug_Target_SRC value="true">YES</Type_C_Is_Debug_Target_SRC>
+ <Type_C_Is_Debug_Target_SNK value="true">YES</Type_C_Is_Debug_Target_SNK>
+ <Type_C_Can_Act_As_Host value="true">YES</Type_C_Can_Act_As_Host>
+ <Type_C_Is_Alt_Mode_Controller value="false">NO</Type_C_Is_Alt_Mode_Controller>
+ <Type_C_Can_Act_As_Device value="false">NO</Type_C_Can_Act_As_Device>
+ <Type_C_Power_Source value="1">UFP-powered</Type_C_Power_Source>
+ <Type_C_Port_On_Hub value="false">NO</Type_C_Port_On_Hub>
+ <Type_C_Supports_Audio_Accessory value="false">NO</Type_C_Supports_Audio_Accessory>
+ <Type_C_Sources_VCONN value="false">NO</Type_C_Sources_VCONN>
+ <Host_Supports_USB_Data value="true">YES</Host_Supports_USB_Data>
+ <Host_Speed value="1">USB 3.2 GEN 1x1</Host_Speed>
+ <Is_DFP_On_Hub value="false">NO</Is_DFP_On_Hub>
+ <Host_Contains_Captive_Retimer value="false">NO</Host_Contains_Captive_Retimer>
+ <Host_Is_Embedded value="false">NO</Host_Is_Embedded>
+ <PD_Power_As_Source value="15000">15000 mW</PD_Power_As_Source>
+ <USB_Suspend_May_Be_Cleared value="false">NO</USB_Suspend_May_Be_Cleared>
+ <FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="0">FR_Swap not supported</FR_Swap_Type_C_Current_Capability_As_Initial_Sink>
+ <Master_Port value="false">NO</Master_Port>
+ <Num_Src_PDOs value="1" />
+ <PD_OC_Protection value="false">NO</PD_OC_Protection>
+ <Product_Total_Source_Power_mW value="15000">15000 mW</Product_Total_Source_Power_mW>
+ <Port_Source_Power_Type value="0">Assured</Port_Source_Power_Type>
+ <SrcPdoList>
+ <SrcPDO>
+ <Src_PDO_Supply_Type value="0">Fixed</Src_PDO_Supply_Type>
+ <Src_PDO_Peak_Current value="0">100% IOC</Src_PDO_Peak_Current>
+ <Src_PDO_Voltage value="100">5000 mV</Src_PDO_Voltage>
+ <Src_PDO_Max_Current value="300">3000 mA</Src_PDO_Max_Current>
+ <Src_PD_OCP_OC_Debounce value="50">50 msec</Src_PD_OCP_OC_Debounce>
+ <Src_PD_OCP_OC_Threshold value="360">3600 mA</Src_PD_OCP_OC_Threshold>
+ </SrcPDO>
+ </SrcPdoList>
+ </Component>
+</VIF>
diff --git a/test/genvif/vif_output/exp_test_vif.xml b/test/genvif/vif_output/exp_test_vif.xml
new file mode 100644
index 0000000000..0f3b1a0fd1
--- /dev/null
+++ b/test/genvif/vif_output/exp_test_vif.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VIF xmlns="http://usb.org/VendorInfoFile.xsd">
+ <VIF_Specification>3.12</VIF_Specification>
+ <VIF_App>
+ <Vendor>Google</Vendor>
+ <Name>EC GENVIF</Name>
+ <Version>3.0.0.10</Version>
+ </VIF_App>
+ <Vendor_Name>Google</Vendor_Name>
+ <Model_Part_Number>test</Model_Part_Number>
+ <Product_Revision>FIX-ME</Product_Revision>
+ <TID>65535</TID>
+ <VIF_Product_Type value="0">Port Product</VIF_Product_Type>
+ <Certification_Type value="0">End Product</Certification_Type>
+ <Product>
+ <Product_VID value="6353">18D1</Product_VID>
+ </Product>
+ <Component>
+ <Port_Label>0</Port_Label>
+ <Connector_Type value="2">Type-C®</Connector_Type>
+ <USB4_Supported value="false">NO</USB4_Supported>
+ <USB_PD_Support value="true">YES</USB_PD_Support>
+ <PD_Port_Type value="4">DRP</PD_Port_Type>
+ <Type_C_State_Machine value="2">DRP</Type_C_State_Machine>
+ <Captive_Cable value="false">NO</Captive_Cable>
+ <Port_Battery_Powered value="false">NO</Port_Battery_Powered>
+ <BC_1_2_Support value="0">None</BC_1_2_Support>
+ <PD_Spec_Revision_Major value="3" />
+ <PD_Spec_Revision_Minor value="0" />
+ <PD_Spec_Version_Major value="2" />
+ <PD_Spec_Version_Minor value="0" />
+ <PD_Specification_Revision value="2">Revision 3</PD_Specification_Revision>
+ <USB_Comms_Capable value="true">YES</USB_Comms_Capable>
+ <DR_Swap_To_DFP_Supported value="true">YES</DR_Swap_To_DFP_Supported>
+ <DR_Swap_To_UFP_Supported value="false">NO</DR_Swap_To_UFP_Supported>
+ <Unconstrained_Power value="false">NO</Unconstrained_Power>
+ <VCONN_Swap_To_On_Supported value="false">NO</VCONN_Swap_To_On_Supported>
+ <VCONN_Swap_To_Off_Supported value="false">NO</VCONN_Swap_To_Off_Supported>
+ <Responds_To_Discov_SOP_UFP value="false">NO</Responds_To_Discov_SOP_UFP>
+ <Responds_To_Discov_SOP_DFP value="false">NO</Responds_To_Discov_SOP_DFP>
+ <Attempts_Discov_SOP value="true">YES</Attempts_Discov_SOP>
+ <Chunking_Implemented_SOP value="false">NO</Chunking_Implemented_SOP>
+ <Unchunked_Extended_Messages_Supported value="false">NO</Unchunked_Extended_Messages_Supported>
+ <Manufacturer_Info_Supported_Port value="false">NO</Manufacturer_Info_Supported_Port>
+ <Security_Msgs_Supported_SOP value="false">NO</Security_Msgs_Supported_SOP>
+ <Num_Fixed_Batteries value="1" />
+ <Num_Swappable_Battery_Slots value="0" />
+ <ID_Header_Connector_Type_SOP value="2">USB Type-C® Receptacle</ID_Header_Connector_Type_SOP>
+ <SOP_Capable value="true">YES</SOP_Capable>
+ <SOP_P_Capable value="false">NO</SOP_P_Capable>
+ <SOP_PP_Capable value="false">NO</SOP_PP_Capable>
+ <SOP_P_Debug_Capable value="false">NO</SOP_P_Debug_Capable>
+ <SOP_PP_Debug_Capable value="false">NO</SOP_PP_Debug_Capable>
+ <Type_C_Implements_Try_SRC value="false">NO</Type_C_Implements_Try_SRC>
+ <Type_C_Implements_Try_SNK value="false">NO</Type_C_Implements_Try_SNK>
+ <RP_Value value="1">1.5A</RP_Value>
+ <Type_C_Is_VCONN_Powered_Accessory value="false">NO</Type_C_Is_VCONN_Powered_Accessory>
+ <Type_C_Is_Debug_Target_SRC value="true">YES</Type_C_Is_Debug_Target_SRC>
+ <Type_C_Is_Debug_Target_SNK value="true">YES</Type_C_Is_Debug_Target_SNK>
+ <Type_C_Can_Act_As_Host value="true">YES</Type_C_Can_Act_As_Host>
+ <Type_C_Is_Alt_Mode_Controller value="false">NO</Type_C_Is_Alt_Mode_Controller>
+ <Type_C_Can_Act_As_Device value="false">NO</Type_C_Can_Act_As_Device>
+ <Type_C_Power_Source value="1">UFP-powered</Type_C_Power_Source>
+ <Type_C_Port_On_Hub value="false">NO</Type_C_Port_On_Hub>
+ <Type_C_Supports_Audio_Accessory value="false">NO</Type_C_Supports_Audio_Accessory>
+ <Type_C_Sources_VCONN value="false">NO</Type_C_Sources_VCONN>
+ <Host_Supports_USB_Data value="true">YES</Host_Supports_USB_Data>
+ <Host_Speed value="1">USB 3.2 GEN 1x1</Host_Speed>
+ <Is_DFP_On_Hub value="false">NO</Is_DFP_On_Hub>
+ <Host_Contains_Captive_Retimer value="false">NO</Host_Contains_Captive_Retimer>
+ <Host_Is_Embedded value="false">NO</Host_Is_Embedded>
+ <PD_Power_As_Source value="15000">15000 mW</PD_Power_As_Source>
+ <USB_Suspend_May_Be_Cleared value="false">NO</USB_Suspend_May_Be_Cleared>
+ <Sends_Pings value="false">NO</Sends_Pings>
+ <FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="0">FR_Swap not supported</FR_Swap_Type_C_Current_Capability_As_Initial_Sink>
+ <Master_Port value="false">NO</Master_Port>
+ <Num_Src_PDOs value="1" />
+ <PD_OC_Protection value="false">NO</PD_OC_Protection>
+ <Product_Total_Source_Power_mW value="15000">15000 mW</Product_Total_Source_Power_mW>
+ <Port_Source_Power_Type value="0">Assured</Port_Source_Power_Type>
+ <SrcPdoList>
+ <SrcPDO>
+ <Src_PDO_Supply_Type value="0">Fixed</Src_PDO_Supply_Type>
+ <Src_PDO_Peak_Current value="0">100% IOC</Src_PDO_Peak_Current>
+ <Src_PDO_Voltage value="100">5000 mV</Src_PDO_Voltage>
+ <Src_PDO_Max_Current value="300">3000 mA</Src_PDO_Max_Current>
+ </SrcPDO>
+ </SrcPdoList>
+ </Component>
+</VIF>
diff --git a/test/genvif/vif_output/test_over_vif.xml b/test/genvif/vif_output/test_over_vif.xml
new file mode 100644
index 0000000000..e15c68c1b0
--- /dev/null
+++ b/test/genvif/vif_output/test_over_vif.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VIF xmlns="http://usb.org/VendorInfoFile.xsd">
+ <VIF_Specification>3.12</VIF_Specification>
+ <VIF_App>
+ <Vendor>Google</Vendor>
+ <Name>EC GENVIF</Name>
+ <Version>3.0.0.10</Version>
+ </VIF_App>
+ <Vendor_Name>Google</Vendor_Name>
+ <Model_Part_Number>SuperTestWithOverride</Model_Part_Number>
+ <Product_Revision>Final</Product_Revision>
+ <TID>12345</TID>
+ <VIF_Product_Type value="0">Port Product</VIF_Product_Type>
+ <Certification_Type value="0">End Product</Certification_Type>
+ <Product>
+ <Product_VID value="6353">18D1</Product_VID>
+ </Product>
+ <Component>
+ <Port_Label>0</Port_Label>
+ <Connector_Type value="2">Type-C®</Connector_Type>
+ <USB4_Supported value="false">NO</USB4_Supported>
+ <USB_PD_Support value="true">YES</USB_PD_Support>
+ <PD_Port_Type value="4">DRP</PD_Port_Type>
+ <Type_C_State_Machine value="2">DRP</Type_C_State_Machine>
+ <Captive_Cable value="false">NO</Captive_Cable>
+ <Port_Battery_Powered value="false">NO</Port_Battery_Powered>
+ <BC_1_2_Support value="0">None</BC_1_2_Support>
+ <PD_Spec_Revision_Major value="3" />
+ <PD_Spec_Revision_Minor value="0" />
+ <PD_Spec_Version_Major value="2" />
+ <PD_Spec_Version_Minor value="0" />
+ <PD_Specification_Revision value="2">Revision 3</PD_Specification_Revision>
+ <USB_Comms_Capable value="true">YES</USB_Comms_Capable>
+ <DR_Swap_To_DFP_Supported value="true">YES</DR_Swap_To_DFP_Supported>
+ <DR_Swap_To_UFP_Supported value="false">NO</DR_Swap_To_UFP_Supported>
+ <Unconstrained_Power value="false">NO</Unconstrained_Power>
+ <VCONN_Swap_To_On_Supported value="false">NO</VCONN_Swap_To_On_Supported>
+ <VCONN_Swap_To_Off_Supported value="false">NO</VCONN_Swap_To_Off_Supported>
+ <Responds_To_Discov_SOP_UFP value="false">NO</Responds_To_Discov_SOP_UFP>
+ <Responds_To_Discov_SOP_DFP value="false">NO</Responds_To_Discov_SOP_DFP>
+ <Attempts_Discov_SOP value="true">YES</Attempts_Discov_SOP>
+ <Chunking_Implemented_SOP value="false">NO</Chunking_Implemented_SOP>
+ <Unchunked_Extended_Messages_Supported value="false">NO</Unchunked_Extended_Messages_Supported>
+ <Manufacturer_Info_Supported_Port value="false">NO</Manufacturer_Info_Supported_Port>
+ <Security_Msgs_Supported_SOP value="false">NO</Security_Msgs_Supported_SOP>
+ <Num_Fixed_Batteries value="1" />
+ <Num_Swappable_Battery_Slots value="0" />
+ <ID_Header_Connector_Type_SOP value="2">USB Type-C® Receptacle</ID_Header_Connector_Type_SOP>
+ <SOP_Capable value="true">YES</SOP_Capable>
+ <SOP_P_Capable value="false">NO</SOP_P_Capable>
+ <SOP_PP_Capable value="false">NO</SOP_PP_Capable>
+ <SOP_P_Debug_Capable value="false">NO</SOP_P_Debug_Capable>
+ <SOP_PP_Debug_Capable value="false">NO</SOP_PP_Debug_Capable>
+ <Type_C_Implements_Try_SRC value="false">NO</Type_C_Implements_Try_SRC>
+ <Type_C_Implements_Try_SNK value="false">NO</Type_C_Implements_Try_SNK>
+ <RP_Value value="1">1.5A</RP_Value>
+ <Type_C_Is_VCONN_Powered_Accessory value="false">NO</Type_C_Is_VCONN_Powered_Accessory>
+ <Type_C_Is_Debug_Target_SRC value="true">YES</Type_C_Is_Debug_Target_SRC>
+ <Type_C_Is_Debug_Target_SNK value="true">YES</Type_C_Is_Debug_Target_SNK>
+ <Type_C_Can_Act_As_Host value="true">YES</Type_C_Can_Act_As_Host>
+ <Type_C_Is_Alt_Mode_Controller value="false">NO</Type_C_Is_Alt_Mode_Controller>
+ <Type_C_Can_Act_As_Device value="false">NO</Type_C_Can_Act_As_Device>
+ <Type_C_Power_Source value="1">UFP-powered</Type_C_Power_Source>
+ <Type_C_Port_On_Hub value="false">NO</Type_C_Port_On_Hub>
+ <Type_C_Supports_Audio_Accessory value="false">NO</Type_C_Supports_Audio_Accessory>
+ <Type_C_Sources_VCONN value="false">NO</Type_C_Sources_VCONN>
+ <Host_Supports_USB_Data value="true">YES</Host_Supports_USB_Data>
+ <Host_Speed value="1">USB 3.2 GEN 1x1</Host_Speed>
+ <Is_DFP_On_Hub value="false">NO</Is_DFP_On_Hub>
+ <Host_Contains_Captive_Retimer value="false">NO</Host_Contains_Captive_Retimer>
+ <Host_Is_Embedded value="false">NO</Host_Is_Embedded>
+ <PD_Power_As_Source value="15000">15000 mW</PD_Power_As_Source>
+ <USB_Suspend_May_Be_Cleared value="false">NO</USB_Suspend_May_Be_Cleared>
+ <FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="0">FR_Swap not supported</FR_Swap_Type_C_Current_Capability_As_Initial_Sink>
+ <Master_Port value="false">NO</Master_Port>
+ <Num_Src_PDOs value="1" />
+ <PD_OC_Protection value="false">NO</PD_OC_Protection>
+ <Product_Total_Source_Power_mW value="15000">15000 mW</Product_Total_Source_Power_mW>
+ <Port_Source_Power_Type value="0">Assured</Port_Source_Power_Type>
+ <SrcPdoList>
+ <SrcPDO>
+ <Src_PDO_Supply_Type value="0">Fixed</Src_PDO_Supply_Type>
+ <Src_PDO_Peak_Current value="0">100% IOC</Src_PDO_Peak_Current>
+ <Src_PDO_Voltage value="100">5000 mV</Src_PDO_Voltage>
+ <Src_PDO_Max_Current value="300">3000 mA</Src_PDO_Max_Current>
+ <Src_PD_OCP_OC_Debounce value="50">50 msec</Src_PD_OCP_OC_Debounce>
+ <Src_PD_OCP_OC_Threshold value="360">3600 mA</Src_PD_OCP_OC_Threshold>
+ </SrcPDO>
+ </SrcPdoList>
+ </Component>
+</VIF>
diff --git a/test/genvif/vif_output/test_vif.xml b/test/genvif/vif_output/test_vif.xml
new file mode 100644
index 0000000000..0f3b1a0fd1
--- /dev/null
+++ b/test/genvif/vif_output/test_vif.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VIF xmlns="http://usb.org/VendorInfoFile.xsd">
+ <VIF_Specification>3.12</VIF_Specification>
+ <VIF_App>
+ <Vendor>Google</Vendor>
+ <Name>EC GENVIF</Name>
+ <Version>3.0.0.10</Version>
+ </VIF_App>
+ <Vendor_Name>Google</Vendor_Name>
+ <Model_Part_Number>test</Model_Part_Number>
+ <Product_Revision>FIX-ME</Product_Revision>
+ <TID>65535</TID>
+ <VIF_Product_Type value="0">Port Product</VIF_Product_Type>
+ <Certification_Type value="0">End Product</Certification_Type>
+ <Product>
+ <Product_VID value="6353">18D1</Product_VID>
+ </Product>
+ <Component>
+ <Port_Label>0</Port_Label>
+ <Connector_Type value="2">Type-C®</Connector_Type>
+ <USB4_Supported value="false">NO</USB4_Supported>
+ <USB_PD_Support value="true">YES</USB_PD_Support>
+ <PD_Port_Type value="4">DRP</PD_Port_Type>
+ <Type_C_State_Machine value="2">DRP</Type_C_State_Machine>
+ <Captive_Cable value="false">NO</Captive_Cable>
+ <Port_Battery_Powered value="false">NO</Port_Battery_Powered>
+ <BC_1_2_Support value="0">None</BC_1_2_Support>
+ <PD_Spec_Revision_Major value="3" />
+ <PD_Spec_Revision_Minor value="0" />
+ <PD_Spec_Version_Major value="2" />
+ <PD_Spec_Version_Minor value="0" />
+ <PD_Specification_Revision value="2">Revision 3</PD_Specification_Revision>
+ <USB_Comms_Capable value="true">YES</USB_Comms_Capable>
+ <DR_Swap_To_DFP_Supported value="true">YES</DR_Swap_To_DFP_Supported>
+ <DR_Swap_To_UFP_Supported value="false">NO</DR_Swap_To_UFP_Supported>
+ <Unconstrained_Power value="false">NO</Unconstrained_Power>
+ <VCONN_Swap_To_On_Supported value="false">NO</VCONN_Swap_To_On_Supported>
+ <VCONN_Swap_To_Off_Supported value="false">NO</VCONN_Swap_To_Off_Supported>
+ <Responds_To_Discov_SOP_UFP value="false">NO</Responds_To_Discov_SOP_UFP>
+ <Responds_To_Discov_SOP_DFP value="false">NO</Responds_To_Discov_SOP_DFP>
+ <Attempts_Discov_SOP value="true">YES</Attempts_Discov_SOP>
+ <Chunking_Implemented_SOP value="false">NO</Chunking_Implemented_SOP>
+ <Unchunked_Extended_Messages_Supported value="false">NO</Unchunked_Extended_Messages_Supported>
+ <Manufacturer_Info_Supported_Port value="false">NO</Manufacturer_Info_Supported_Port>
+ <Security_Msgs_Supported_SOP value="false">NO</Security_Msgs_Supported_SOP>
+ <Num_Fixed_Batteries value="1" />
+ <Num_Swappable_Battery_Slots value="0" />
+ <ID_Header_Connector_Type_SOP value="2">USB Type-C® Receptacle</ID_Header_Connector_Type_SOP>
+ <SOP_Capable value="true">YES</SOP_Capable>
+ <SOP_P_Capable value="false">NO</SOP_P_Capable>
+ <SOP_PP_Capable value="false">NO</SOP_PP_Capable>
+ <SOP_P_Debug_Capable value="false">NO</SOP_P_Debug_Capable>
+ <SOP_PP_Debug_Capable value="false">NO</SOP_PP_Debug_Capable>
+ <Type_C_Implements_Try_SRC value="false">NO</Type_C_Implements_Try_SRC>
+ <Type_C_Implements_Try_SNK value="false">NO</Type_C_Implements_Try_SNK>
+ <RP_Value value="1">1.5A</RP_Value>
+ <Type_C_Is_VCONN_Powered_Accessory value="false">NO</Type_C_Is_VCONN_Powered_Accessory>
+ <Type_C_Is_Debug_Target_SRC value="true">YES</Type_C_Is_Debug_Target_SRC>
+ <Type_C_Is_Debug_Target_SNK value="true">YES</Type_C_Is_Debug_Target_SNK>
+ <Type_C_Can_Act_As_Host value="true">YES</Type_C_Can_Act_As_Host>
+ <Type_C_Is_Alt_Mode_Controller value="false">NO</Type_C_Is_Alt_Mode_Controller>
+ <Type_C_Can_Act_As_Device value="false">NO</Type_C_Can_Act_As_Device>
+ <Type_C_Power_Source value="1">UFP-powered</Type_C_Power_Source>
+ <Type_C_Port_On_Hub value="false">NO</Type_C_Port_On_Hub>
+ <Type_C_Supports_Audio_Accessory value="false">NO</Type_C_Supports_Audio_Accessory>
+ <Type_C_Sources_VCONN value="false">NO</Type_C_Sources_VCONN>
+ <Host_Supports_USB_Data value="true">YES</Host_Supports_USB_Data>
+ <Host_Speed value="1">USB 3.2 GEN 1x1</Host_Speed>
+ <Is_DFP_On_Hub value="false">NO</Is_DFP_On_Hub>
+ <Host_Contains_Captive_Retimer value="false">NO</Host_Contains_Captive_Retimer>
+ <Host_Is_Embedded value="false">NO</Host_Is_Embedded>
+ <PD_Power_As_Source value="15000">15000 mW</PD_Power_As_Source>
+ <USB_Suspend_May_Be_Cleared value="false">NO</USB_Suspend_May_Be_Cleared>
+ <Sends_Pings value="false">NO</Sends_Pings>
+ <FR_Swap_Type_C_Current_Capability_As_Initial_Sink value="0">FR_Swap not supported</FR_Swap_Type_C_Current_Capability_As_Initial_Sink>
+ <Master_Port value="false">NO</Master_Port>
+ <Num_Src_PDOs value="1" />
+ <PD_OC_Protection value="false">NO</PD_OC_Protection>
+ <Product_Total_Source_Power_mW value="15000">15000 mW</Product_Total_Source_Power_mW>
+ <Port_Source_Power_Type value="0">Assured</Port_Source_Power_Type>
+ <SrcPdoList>
+ <SrcPDO>
+ <Src_PDO_Supply_Type value="0">Fixed</Src_PDO_Supply_Type>
+ <Src_PDO_Peak_Current value="0">100% IOC</Src_PDO_Peak_Current>
+ <Src_PDO_Voltage value="100">5000 mV</Src_PDO_Voltage>
+ <Src_PDO_Max_Current value="300">3000 mA</Src_PDO_Max_Current>
+ </SrcPDO>
+ </SrcPdoList>
+ </Component>
+</VIF>
diff --git a/util/ectool.c b/util/ectool.c
index 5ee4308514..9694a95ff6 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -6183,30 +6183,105 @@ int cmd_charge_current_limit(int argc, char *argv[])
return rv;
}
+static void cmd_charge_control_help(const char *cmd, const char *msg)
+{
+ if (msg)
+ fprintf(stderr, "ERROR: %s\n", msg);
+
+ fprintf(stderr,
+ "\n"
+ " Usage: %s\n"
+ " Get current settings.\n"
+ " Usage: %s normal|idle|discharge\n"
+ " Set charge mode (and disable battery sustainer).\n"
+ " Usage: %s normal <lower> <upper>\n"
+ " Enable battery sustainer. <lower> and <upper> are battery SoC\n"
+ " between which EC tries to keep the battery level.\n"
+ "\n",
+ cmd, cmd, cmd);
+}
int cmd_charge_control(int argc, char *argv[])
{
struct ec_params_charge_control p;
+ struct ec_response_charge_control r;
+ int version = 2;
+ const char * const charge_mode_text[] = EC_CHARGE_MODE_TEXT;
+ char *e;
int rv;
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <normal | idle | discharge>\n",
- argv[0]);
- return -1;
+ if (!ec_cmd_version_supported(EC_CMD_CHARGE_CONTROL, 2))
+ version = 1;
+
+ if (argc == 1) {
+ if (version < 2) {
+ cmd_charge_control_help(argv[0],
+ "Old EC doesn't support GET.");
+ return -1;
+ }
+ p.cmd = EC_CHARGE_CONTROL_CMD_GET;
+ rv = ec_command(EC_CMD_CHARGE_CONTROL, version,
+ &p, sizeof(p), &r, sizeof(r));
+ if (rv < 0) {
+ fprintf(stderr, "Command failed.\n");
+ return rv;
+ }
+ printf("Charge mode = %s (%d)\n",
+ r.mode < ARRAY_SIZE(charge_mode_text)
+ ? charge_mode_text[r.mode] : "UNDEFINED",
+ r.mode);
+ printf("Battery sustainer = %s (%d%% ~ %d%%)\n",
+ (r.sustain_soc.lower != -1 && r.sustain_soc.upper != -1)
+ ? "on" : "off",
+ r.sustain_soc.lower, r.sustain_soc.upper);
+ return 0;
}
if (!strcasecmp(argv[1], "normal")) {
p.mode = CHARGE_CONTROL_NORMAL;
+ if (argc == 2) {
+ p.sustain_soc.lower = -1;
+ p.sustain_soc.upper = -1;
+ } else if (argc == 4) {
+ if (version < 2) {
+ cmd_charge_control_help(argv[0],
+ "Old EC doesn't support sustainer.");
+ return -1;
+ }
+ p.sustain_soc.lower = strtol(argv[2], &e, 0);
+ if (e && *e) {
+ cmd_charge_control_help(argv[0],
+ "Bad character in <lower>");
+ return -1;
+ }
+ p.sustain_soc.upper = strtol(argv[3], &e, 0);
+ if (e && *e) {
+ cmd_charge_control_help(argv[0],
+ "Bad character in <upper>");
+ return -1;
+ }
+ } else {
+ cmd_charge_control_help(argv[0], "Bad arguments");
+ return -1;
+ }
} else if (!strcasecmp(argv[1], "idle")) {
+ if (argc != 2) {
+ cmd_charge_control_help(argv[0], "Bad arguments");
+ return -1;
+ }
p.mode = CHARGE_CONTROL_IDLE;
} else if (!strcasecmp(argv[1], "discharge")) {
+ if (argc != 2) {
+ cmd_charge_control_help(argv[0], "Bad arguments");
+ return -1;
+ }
p.mode = CHARGE_CONTROL_DISCHARGE;
} else {
- fprintf(stderr, "Bad value.\n");
+ cmd_charge_control_help(argv[0], "Bad sub-command");
return -1;
}
- rv = ec_command(EC_CMD_CHARGE_CONTROL, 1, &p, sizeof(p), NULL, 0);
+ rv = ec_command(EC_CMD_CHARGE_CONTROL, version, &p, sizeof(p), NULL, 0);
if (rv < 0) {
fprintf(stderr, "Is AC connected?\n");
return rv;
@@ -6214,7 +6289,9 @@ int cmd_charge_control(int argc, char *argv[])
switch (p.mode) {
case CHARGE_CONTROL_NORMAL:
- printf("Charge state machine normal mode.\n");
+ printf("Charge state machine is in normal mode%s.\n",
+ (p.sustain_soc.lower == -1 || p.sustain_soc.upper == -1)
+ ? "" : " with sustainer enabled");
break;
case CHARGE_CONTROL_IDLE:
printf("Charge state machine force idle.\n");