summaryrefslogtreecommitdiff
path: root/board/shotzo/led.c
diff options
context:
space:
mode:
authorTom Hughes <tomhughes@chromium.org>2022-09-21 14:08:36 -0700
committerTom Hughes <tomhughes@chromium.org>2022-09-22 12:59:38 -0700
commitc453fd704268ef72de871b0c5ac7a989de662334 (patch)
treefcf6ce5810f9ff9e3c8cce434812dd75492269ed /board/shotzo/led.c
parent6c1587ca70f558b4f96b3f0b18ad8b027d3ba99d (diff)
parent28712dae9d7ed1e694f7622cc083afa71090d4d5 (diff)
downloadchrome-ec-firmware-fpmcu-dartmonkey-release.tar.gz
Merge remote-tracking branch cros/main into firmware-fpmcu-dartmonkey-releasefirmware-fpmcu-dartmonkey-release
Generated by: ./util/update_release_branch.py --board dartmonkey --relevant_paths_file ./util/fingerprint-relevant-paths.txt firmware-fpmcu-dartmonkey-release Relevant changes: git log --oneline 6c1587ca70..28712dae9d -- board/nocturne_fp board/dartmonkey common/fpsensor docs/fingerprint driver/fingerprint util/getversion.sh ded9307b79 util/getversion.sh: Fix version when not in a git repo 956055e692 board: change Google USB vendor info 71b2ef709d Update license boilerplate text in source code files 33e11afda0 Revert "fpsensor: Build fpsensor source file with C++" c8d0360723 fpsensor: Build fpsensor source file with C++ bc113abd53 fpsensor: Fix g++ compiler error 150a58a0dc fpsensor: Fix fp_set_sensor_mode return type b33b5ce85b fpsensor: Remove nested designators for C++ compatibility 2e864b2539 tree-wide: const-ify argv for console commands 56d8b360f9 test: Add test for get ikm failure when seed not set 3a3d6c3690 test: Add test for fpsensor trivial key failure 233e6bbd08 fpsensor_crypto: Abstract calls to hmac_SHA256 0a041b285b docs/fingerprint: Typo correction c03fab67e2 docs/fingerprint: Fix the path of fputils.py 0b5d4baf5a util/getversion.sh: Fix empty file list handling 6e128fe760 FPMCU dev board environment with Satlab 3eb29b6aa5 builtin: Move ssize_t to sys/types.h 345d62ebd1 docs/fingerprint: Update power numbers for latest dartmonkey release c25ffdb316 common: Conditionally support printf %l and %i modifiers 9a3c514b45 test: Add a test to check if the debugger is connected 54e603413f Move standard library tests to their own file 43fa6b4bf8 docs/fingerprint: Update power numbers for latest bloonchipper release 25536f9a84 driver/fingerprint/fpc/bep/fpc_sensor_spi.c: Format with clang-format 4face99efd driver/fingerprint/fpc/libfp/fpc_sensor_pal.h: Format with clang-format 738de2b575 trng: Rename rand to trng_rand 14b8270edd docs/fingerprint: Update dragonclaw power numbers 0b268f93d1 driver/fingerprint/fpc/libfp/fpc_private.c: Format with clang-format f80da163f2 driver/fingerprint/fpc/libfp/fpc_private.h: Format with clang-format a0751778f4 board/nocturne_fp/ro_workarounds.c: Format with clang-format 5e9c85c9b1 driver/fingerprint/fpc/libfp/fpc_sensor_pal.c: Format with clang-format c1f9dd3cf8 driver/fingerprint/fpc/libfp/fpc_bio_algorithm.h: Format with clang-format eb1e1bed8d driver/fingerprint/fpc/libfp/fpc1145_private.h: Format with clang-format 6e7b611821 driver/fingerprint/fpc/bep/fpc_bio_algorithm.h: Format with clang-format e0589cd5e2 driver/fingerprint/fpc/bep/fpc1035_private.h: Format with clang-format 58f0246dbe board/nocturne_fp/board_ro.c: Format with clang-format 7905e556a0 common/fpsensor/fpsensor_crypto.c: Format with clang-format 21289d170c driver/fingerprint/fpc/bep/fpc1025_private.h: Format with clang-format 98a20f937e common/fpsensor/fpsensor_state.c: Format with clang-format a2d255d8af common/fpsensor/fpsensor.c: Format with clang-format 84e53a65da board/nocturne_fp/board.h: Format with clang-format 73055eeb3f driver/fingerprint/fpc/bep/fpc_private.c: Format with clang-format 0f7b5cb509 common/fpsensor/fpsensor_private.h: Format with clang-format 1ceade6e65 driver/fingerprint/fpc/bep/fpc_private.h: Format with clang-format dca9d74321 Revert "trng: Rename rand to trng_rand" a6b0b3554f trng: Rename rand to trng_rand 28d0b75b70 third_party/boringssl: Remove unused header BRANCH=None BUG=b:244387210 b:242720240 b:215613183 b:242720910 b:236386294 BUG=b:234181908 b:244781166 b:234781655 b:234143158 b:234181908 BUG=b:237344361 b:236025198 b:234181908 b:180945056 chromium:1098010 BUG=b:246424843 b:234181908 b:131913998 TEST=`make -j buildall` TEST=./util/run_device_tests.py --board dartmonkey Test "aes": PASSED Test "cec": PASSED Test "cortexm_fpu": PASSED Test "crc": PASSED Test "flash_physical": PASSED Test "flash_write_protect": PASSED Test "fpsensor_hw": PASSED Test "fpsensor_spi_ro": PASSED Test "fpsensor_spi_rw": PASSED Test "fpsensor_uart_ro": PASSED Test "fpsensor_uart_rw": PASSED Test "mpu_ro": PASSED Test "mpu_rw": PASSED Test "mutex": PASSED Test "pingpong": PASSED Test "printf": PASSED Test "queue": PASSED Test "rollback_region0": PASSED Test "rollback_region1": PASSED Test "rollback_entropy": PASSED Test "rtc": PASSED Test "sha256": PASSED Test "sha256_unrolled": PASSED Test "static_if": PASSED Test "stdlib": PASSED Test "system_is_locked_wp_on": PASSED Test "system_is_locked_wp_off": PASSED Test "timer_dos": PASSED Test "utils": PASSED Test "utils_str": PASSED Test "panic_data_dartmonkey_v2.0.2887": PASSED Test "panic_data_nocturne_fp_v2.2.64": PASSED Test "panic_data_nami_fp_v2.2.144": PASSED Force-Relevant-Builds: all Signed-off-by: Tom Hughes <tomhughes@chromium.org> Change-Id: I2c312583a709fedae8fe11d92c22328c3b634bc7
Diffstat (limited to 'board/shotzo/led.c')
-rw-r--r--board/shotzo/led.c306
1 files changed, 172 insertions, 134 deletions
diff --git a/board/shotzo/led.c b/board/shotzo/led.c
index 761b4b4047..9ca9e7a498 100644
--- a/board/shotzo/led.c
+++ b/board/shotzo/led.c
@@ -1,58 +1,45 @@
-/* Copyright 2022 The ChromiumOS Authors.
+/* 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.
*/
-/* Shotzo specific LED settings. */
+/* Power LED control for Shotzo.
+ * Solid white - active power
+ * 25% duty cycle white, 1s on and 3s off- suspend
+ * Blinking quicky white, 0.5s on and 0.5s off - alert
+ * 2 long 2 short white, long for 1s, short for 0.5s and interval
+ * is 0.5s - critical
+ * Off - shut down
+ */
-#include "cbi_fw_config.h"
-#include "charge_state.h"
-#include "extpower.h"
+#include "chipset.h"
+#include "console.h"
#include "gpio.h"
#include "hooks.h"
#include "led_common.h"
+#include "timer.h"
+#include "util.h"
-#define BAT_LED_ON 0
-#define BAT_LED_OFF 1
+/*
+ * Due to the CSME-Lite processing, upon startup the CPU transitions through
+ * S0->S3->S5->S3->S0, causing the LED to turn on/off/on, so
+ * delay turning off the LED during suspend/shutdown.
+ */
+#define LED_CPU_DELAY_MS (2000 * MSEC)
#define POWER_LED_ON 0
#define POWER_LED_OFF 1
-const enum ec_led_id supported_led_ids[] = {
- EC_LED_ID_BATTERY_LED,
- EC_LED_ID_POWER_LED
-};
+const enum ec_led_id supported_led_ids[] = { EC_LED_ID_POWER_LED };
const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
enum led_color {
LED_OFF = 0,
- LED_AMBER,
LED_WHITE,
- LED_COLOR_COUNT /* Number of colors, not a color itself */
+ LED_COLOR_COUNT /* Number of colors, not a color itself */
};
-static int led_set_color_battery(enum led_color color)
-{
- switch (color) {
- case LED_OFF:
- gpio_set_level(GPIO_BAT_LED_WHITE_L, BAT_LED_OFF);
- gpio_set_level(GPIO_BAT_LED_AMBER_L, BAT_LED_OFF);
- break;
- case LED_WHITE:
- gpio_set_level(GPIO_BAT_LED_WHITE_L, BAT_LED_ON);
- gpio_set_level(GPIO_BAT_LED_AMBER_L, BAT_LED_OFF);
- break;
- case LED_AMBER:
- gpio_set_level(GPIO_BAT_LED_WHITE_L, BAT_LED_OFF);
- gpio_set_level(GPIO_BAT_LED_AMBER_L, BAT_LED_ON);
- break;
- default:
- return EC_ERROR_UNKNOWN;
- }
- return EC_SUCCESS;
-}
-
static int led_set_color_power(enum led_color color)
{
switch (color) {
@@ -68,29 +55,11 @@ static int led_set_color_power(enum led_color color)
return EC_SUCCESS;
}
-void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
-{
- switch (led_id) {
- case EC_LED_ID_BATTERY_LED:
- brightness_range[EC_LED_COLOR_WHITE] = 1;
- brightness_range[EC_LED_COLOR_AMBER] = 1;
- break;
- case EC_LED_ID_POWER_LED:
- brightness_range[EC_LED_COLOR_WHITE] = 1;
- break;
- default:
- break;
- }
-}
-
static int led_set_color(enum ec_led_id led_id, enum led_color color)
{
int rv;
switch (led_id) {
- case EC_LED_ID_BATTERY_LED:
- rv = led_set_color_battery(color);
- break;
case EC_LED_ID_POWER_LED:
rv = led_set_color_power(color);
break;
@@ -100,105 +69,174 @@ static int led_set_color(enum ec_led_id led_id, enum led_color color)
return rv;
}
-int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
+/* When blinking is enabled, led will blinking according to led_blinking_array.
+ * 1 means led on, 0 means led off, restart from head after reaching the tail.
+ * The interval is LED_BLINKING_MS.
+ */
+#define LED_BLINKING_MS (500 * MSEC)
+static int *led_blinking_array;
+static int led_blinking_count;
+static int led_blinking_index;
+static void led_blinking(void);
+DECLARE_DEFERRED(led_blinking);
+static void led_blinking(void)
{
- if (brightness[EC_LED_COLOR_WHITE] != 0)
- led_set_color(led_id, LED_WHITE);
- else if (brightness[EC_LED_COLOR_AMBER] != 0)
- led_set_color(led_id, LED_AMBER);
- else
- led_set_color(led_id, LED_OFF);
+ uint32_t elapsed;
+ uint32_t next = 0;
+ uint32_t start = get_time().le.lo;
+ int signal;
- return EC_SUCCESS;
+ if (led_blinking_array == NULL)
+ return;
+
+ if (led_blinking_index > (led_blinking_count - 1))
+ led_blinking_index = 0;
+
+ signal = *(led_blinking_array + led_blinking_index);
+
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED)) {
+ switch (signal) {
+ case 0:
+ led_set_color(EC_LED_ID_POWER_LED, LED_OFF);
+ led_blinking_index += 1;
+ break;
+ case 1:
+ led_set_color(EC_LED_ID_POWER_LED, LED_WHITE);
+ led_blinking_index += 1;
+ break;
+ default:
+ led_blinking_index = 0;
+ }
+ }
+
+ elapsed = get_time().le.lo - start;
+ next = elapsed < LED_BLINKING_MS ? LED_BLINKING_MS - elapsed : 0;
+ hook_call_deferred(&led_blinking_data, next);
}
-static void led_set_battery(void)
+static int led_suspend_array[] = { 1, 1, 0, 0, 0, 0, 0, 0 };
+const int led_suspend_count = ARRAY_SIZE(led_suspend_array);
+static void led_suspend(void)
{
- static int battery_ticks;
- static int power_ticks;
- uint32_t chflags = charge_get_flags();
-
- battery_ticks++;
-
- /*
- * Override battery LED for Drawlet/Drawman, Drawlet/Drawman
- * don't have power LED, blinking battery white LED to indicate
- * system suspend without charging.
- */
- if (get_cbi_fw_config_tablet_mode() == TABLET_MODE_ABSENT) {
- if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) &&
- charge_get_state() != PWR_STATE_CHARGE) {
- led_set_color_battery(power_ticks++ & 0x2 ?
- LED_WHITE : LED_OFF);
- return;
- }
+ led_blinking_array = led_suspend_array;
+ led_blinking_count = led_suspend_count;
+ led_blinking_index = 0;
+ led_blinking();
+}
+DECLARE_DEFERRED(led_suspend);
+
+static void led_shutdown(void)
+{
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
+ led_set_color(EC_LED_ID_POWER_LED, LED_OFF);
+}
+DECLARE_DEFERRED(led_shutdown);
+
+static void led_suspend_hook(void)
+{
+ hook_call_deferred(&led_blinking_data, -1);
+ hook_call_deferred(&led_shutdown_data, -1);
+ hook_call_deferred(&led_suspend_data, LED_CPU_DELAY_MS);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, led_suspend_hook, HOOK_PRIO_DEFAULT);
+
+static void led_shutdown_hook(void)
+{
+ hook_call_deferred(&led_blinking_data, -1);
+ hook_call_deferred(&led_suspend_data, -1);
+ hook_call_deferred(&led_shutdown_data, LED_CPU_DELAY_MS);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, led_shutdown_hook, HOOK_PRIO_DEFAULT);
+
+static void led_resume_hook(void)
+{
+ hook_call_deferred(&led_blinking_data, -1);
+ hook_call_deferred(&led_suspend_data, -1);
+ hook_call_deferred(&led_shutdown_data, -1);
+
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
+ led_set_color(EC_LED_ID_POWER_LED, LED_WHITE);
+}
+DECLARE_HOOK(HOOK_CHIPSET_RESUME, led_resume_hook, HOOK_PRIO_DEFAULT);
+
+static int led_alert_array[] = { 1, 0 };
+const int led_alert_count = ARRAY_SIZE(led_alert_array);
+void led_alert(int enable)
+{
+ if (enable) {
+ /* Overwrite the current signal */
+ hook_call_deferred(&led_blinking_data, -1);
+ led_blinking_array = led_alert_array;
+ led_blinking_count = led_alert_count;
+ led_blinking_index = 0;
+ led_blinking();
+ } else {
+ /* Restore the previous signal */
+ if (chipset_in_state(CHIPSET_STATE_ON))
+ led_resume_hook();
+ else if (chipset_in_state(CHIPSET_STATE_SUSPEND))
+ led_suspend_hook();
+ else if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
+ led_shutdown_hook();
}
+}
- power_ticks = 0;
+static int led_critical_array[] = { 1, 1, 0, 1, 1, 0, 1, 0, 1, 0 };
+const int led_critical_count = ARRAY_SIZE(led_critical_array);
+void show_critical_error(void)
+{
+ hook_call_deferred(&led_blinking_data, -1);
+ led_blinking_array = led_critical_array;
+ led_blinking_count = led_critical_count;
+ led_blinking_index = 0;
+ led_blinking();
+}
- switch (charge_get_state()) {
- case PWR_STATE_CHARGE:
- led_set_color_battery(LED_AMBER);
- break;
- case PWR_STATE_DISCHARGE_FULL:
- if (extpower_is_present()) {
- led_set_color_battery(LED_WHITE);
- break;
- }
- /* Intentional fall-through */
- case PWR_STATE_DISCHARGE:
- /*
- * Blink white light (1 sec on, 1 sec off)
- * when battery capacity is less than 10%
- */
- if (charge_get_percent() < 10)
- led_set_color_battery(
- (battery_ticks & 0x2) ? LED_WHITE : LED_OFF);
- else
- led_set_color_battery(LED_OFF);
- break;
- case PWR_STATE_ERROR:
- led_set_color_battery(
- (battery_ticks % 0x2) ? LED_WHITE : LED_OFF);
- break;
- case PWR_STATE_CHARGE_NEAR_FULL:
- led_set_color_battery(LED_WHITE);
- break;
- case PWR_STATE_IDLE: /* External power connected in IDLE */
- if (chflags & CHARGE_FLAG_FORCE_IDLE)
- led_set_color_battery(
- (battery_ticks & 0x2) ? LED_AMBER : LED_OFF);
- else
- led_set_color_battery(LED_WHITE);
+void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
+{
+ switch (led_id) {
+ case EC_LED_ID_POWER_LED:
+ brightness_range[EC_LED_COLOR_WHITE] = 1;
break;
default:
- /* Other states don't alter LED behavior */
break;
}
}
-static void led_set_power(void)
+int led_set_brightness(enum ec_led_id id, const uint8_t *brightness)
{
- static int power_tick;
-
- power_tick++;
-
- if (chipset_in_state(CHIPSET_STATE_ON))
- led_set_color_power(LED_WHITE);
- else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND))
- led_set_color_power(
- (power_tick & 0x2) ? LED_WHITE : LED_OFF);
+ if (brightness[EC_LED_COLOR_WHITE] != 0)
+ led_set_color(id, LED_WHITE);
else
- led_set_color_power(LED_OFF);
+ led_set_color(id, LED_OFF);
+
+ return EC_SUCCESS;
}
-/* Called by hook task every TICK */
-static void led_tick(void)
+static int command_led(int argc, const char **argv)
{
- if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
- led_set_power();
-
- if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED))
- led_set_battery();
+ enum ec_led_id id = EC_LED_ID_POWER_LED;
+
+ if (argc < 2)
+ return EC_ERROR_PARAM_COUNT;
+
+ if (!strcasecmp(argv[1], "debug")) {
+ led_auto_control(id, !led_auto_control_is_enabled(id));
+ ccprintf("o%s\n", led_auto_control_is_enabled(id) ? "ff" : "n");
+ } else if (!strcasecmp(argv[1], "off")) {
+ led_set_color(id, LED_OFF);
+ } else if (!strcasecmp(argv[1], "white")) {
+ led_set_color(id, LED_WHITE);
+ } else if (!strcasecmp(argv[1], "alert")) {
+ led_alert(1);
+ } else if (!strcasecmp(argv[1], "crit")) {
+ show_critical_error();
+ } else if (!strcasecmp(argv[1], "resume")) {
+ led_resume_hook();
+ } else {
+ return EC_ERROR_PARAM1;
+ }
+ return EC_SUCCESS;
}
-DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT);
+DECLARE_CONSOLE_COMMAND(led, command_led, "[debug|white|off|alert|crit|resume]",
+ "Turn on/off LED.");