From 7367fa67896e60bf1038f58bcac042842b0861b3 Mon Sep 17 00:00:00 2001 From: Tim Van Patten Date: Mon, 31 Oct 2022 15:19:53 -0600 Subject: Add EC_CMD_SET_TABLET_MODE handler Add the EC_CMD_SET_TABLET_MODE host command handler. This will update the tablet mode status in the EC, based on the parameters of the EC_CMD_SET_TABLET_MODE command. BRANCH=none BUG=b:256015402 TEST=CQ TEST=./twister -v -i --coverage -p native_posix \ -p unit_testing -s zephyr/test/drivers/drivers.host_cmd https://luci-milo.appspot.com/ui/inv/u-timvp-2022-11-04-18-57-00-c115adba47827acf Change-Id: Ia7d8ad44a284742bb347004ba355a8419d047faa Signed-off-by: Tim Van Patten Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3994295 Reviewed-by: Diana Z Code-Coverage: Zoss Reviewed-by: Raul Rangel (cherry picked from commit 42d6df2a6bc0659b8f6b5b6837b1fa39bbb46c58) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4413756 Commit-Queue: Knox Chiou Tested-by: Mike Lee --- common/tablet_mode.c | 41 ++++++++- zephyr/test/drivers/host_cmd/CMakeLists.txt | 1 + zephyr/test/drivers/host_cmd/src/tablet_mode.c | 111 +++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 zephyr/test/drivers/host_cmd/src/tablet_mode.c diff --git a/common/tablet_mode.c b/common/tablet_mode.c index 576e80c0ef..1a86997eb4 100644 --- a/common/tablet_mode.c +++ b/common/tablet_mode.c @@ -28,6 +28,12 @@ static uint32_t tablet_mode; */ static bool tablet_mode_forced; +/* + * Console command can force the value of tablet_mode. If tablet_mode_force is + * false, use stored tablet mode value before it was (possibly) overridden. + */ +static uint32_t tablet_mode_store; + /* True if GMR sensor is reporting 360 degrees. */ static bool gmr_sensor_at_360; @@ -173,11 +179,42 @@ void gmr_tablet_switch_disable(void) } #endif +static enum ec_status tablet_mode_command(struct host_cmd_handler_args *args) +{ + const struct ec_params_set_tablet_mode *p = args->params; + + if (tablet_mode_forced == false) + tablet_mode_store = tablet_mode; + + switch (p->tablet_mode) { + case TABLET_MODE_DEFAULT: + tablet_mode = tablet_mode_store; + tablet_mode_forced = false; + break; + case TABLET_MODE_FORCE_TABLET: + tablet_mode = TABLET_TRIGGER_LID; + tablet_mode_forced = true; + break; + case TABLET_MODE_FORCE_CLAMSHELL: + tablet_mode = 0; + tablet_mode_forced = true; + break; + default: + CPRINTS("Invalid EC_CMD_SET_TABLET_MODE parameter: %d", + p->tablet_mode); + return EC_RES_INVALID_PARAM; + } + + notify_tablet_mode_change(); + + return EC_RES_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_SET_TABLET_MODE, tablet_mode_command, + EC_VER_MASK(0) | EC_VER_MASK(1)); + #ifdef CONFIG_TABLET_MODE static int command_settabletmode(int argc, const char **argv) { - static uint32_t tablet_mode_store; - if (argc == 1) { print_tablet_mode(); return EC_SUCCESS; diff --git a/zephyr/test/drivers/host_cmd/CMakeLists.txt b/zephyr/test/drivers/host_cmd/CMakeLists.txt index 286685089b..0bd6ac613a 100644 --- a/zephyr/test/drivers/host_cmd/CMakeLists.txt +++ b/zephyr/test/drivers/host_cmd/CMakeLists.txt @@ -14,6 +14,7 @@ target_sources(app PRIVATE src/pd_control.c src/pd_chip_info.c src/pd_log.c + src/tablet_mode.c src/usb_pd_control.c src/usb_pd_host_cmd.c ) diff --git a/zephyr/test/drivers/host_cmd/src/tablet_mode.c b/zephyr/test/drivers/host_cmd/src/tablet_mode.c new file mode 100644 index 0000000000..cb65899c4f --- /dev/null +++ b/zephyr/test/drivers/host_cmd/src/tablet_mode.c @@ -0,0 +1,111 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include +#include + +#include "hooks.h" +#include "host_command.h" +#include "tablet_mode.h" +#include "emul/emul_common_i2c.h" +#include "emul/emul_smart_battery.h" +#include "test/drivers/test_state.h" +#include "test/drivers/utils.h" + +struct host_cmd_tablet_mode_fixture { + const struct emul *emul; + struct i2c_common_emul_data *i2c_emul; +}; + +static void host_cmd_tablet_mode_before(void *f) +{ + ARG_UNUSED(f); + tablet_reset(); +} + +static void host_cmd_tablet_mode_after(void *f) +{ + ARG_UNUSED(f); + tablet_reset(); +} + +ZTEST_SUITE(host_cmd_tablet_mode, drivers_predicate_post_main, NULL, + host_cmd_tablet_mode_before, host_cmd_tablet_mode_after, NULL); + +/* Test tablet mode can be enabled with a host command. */ +ZTEST_USER_F(host_cmd_tablet_mode, test_tablet_mode_on) +{ + int rv; + struct ec_params_set_tablet_mode params = { + .tablet_mode = TABLET_MODE_FORCE_TABLET + }; + + struct host_cmd_handler_args args = BUILD_HOST_COMMAND_PARAMS( + EC_CMD_SET_TABLET_MODE, UINT8_C(0), params); + + rv = host_command_process(&args); + zassert_equal(EC_RES_SUCCESS, rv, "Expected EC_RES_SUCCESS, but got %d", + rv); + /* Return 1 if in tablet mode, 0 otherwise */ + rv = tablet_get_mode(); + zassert_equal(rv, 1, "unexpected tablet mode: %d", rv); +} + +/* Test tablet mode can be disabled with a host command. */ +ZTEST_USER_F(host_cmd_tablet_mode, test_tablet_mode_off) +{ + int rv; + struct ec_params_set_tablet_mode params = { + .tablet_mode = TABLET_MODE_FORCE_CLAMSHELL + }; + + struct host_cmd_handler_args args = BUILD_HOST_COMMAND_PARAMS( + EC_CMD_SET_TABLET_MODE, UINT8_C(0), params); + + rv = host_command_process(&args); + zassert_equal(EC_RES_SUCCESS, rv, "Expected EC_RES_SUCCESS, but got %d", + rv); + /* Return 1 if in tablet mode, 0 otherwise */ + rv = tablet_get_mode(); + zassert_equal(rv, 0, "unexpected tablet mode: %d", rv); +} + +/* Test tablet mode can be reset with a host command. */ +ZTEST_USER_F(host_cmd_tablet_mode, test_tablet_mode_reset) +{ + int rv; + struct ec_params_set_tablet_mode params = { + .tablet_mode = TABLET_MODE_DEFAULT + }; + + struct host_cmd_handler_args args = BUILD_HOST_COMMAND_PARAMS( + EC_CMD_SET_TABLET_MODE, UINT8_C(0), params); + + rv = host_command_process(&args); + zassert_equal(EC_RES_SUCCESS, rv, "Expected EC_RES_SUCCESS, but got %d", + rv); + /* Return 1 if in tablet mode, 0 otherwise */ + rv = tablet_get_mode(); + zassert_equal(rv, 0, "unexpected tablet mode: %d", rv); +} + +/* Test tablet mode can handle invalid host command parameters. */ +ZTEST_USER_F(host_cmd_tablet_mode, test_tablet_mode_invalid_parameter) +{ + int rv; + struct ec_params_set_tablet_mode params = { + .tablet_mode = 0xEE /* Sufficiently random, bad value.*/ + }; + + struct host_cmd_handler_args args = BUILD_HOST_COMMAND_PARAMS( + EC_CMD_SET_TABLET_MODE, UINT8_C(0), params); + + rv = host_command_process(&args); + zassert_equal(EC_RES_INVALID_PARAM, rv, + "Expected EC_RES_INVALID_PARAM, but got %d", rv); + /* Return 1 if in tablet mode, 0 otherwise */ + rv = tablet_get_mode(); + zassert_equal(rv, 0, "unexpected tablet mode: %d", rv); +} -- cgit v1.2.1