summaryrefslogtreecommitdiff
path: root/common/led_pwm.c
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /common/led_pwm.c
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-release-R101-14588.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'common/led_pwm.c')
-rw-r--r--common/led_pwm.c311
1 files changed, 0 insertions, 311 deletions
diff --git a/common/led_pwm.c b/common/led_pwm.c
deleted file mode 100644
index cc946ba522..0000000000
--- a/common/led_pwm.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/* Copyright 2018 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* PWM LED control to conform to Chrome OS LED behaviour specification. */
-
-/*
- * This assumes that a single logical LED is shared between both power and
- * charging/battery status. If multiple logical LEDs are present, they all
- * follow the same patterns.
- */
-
-#include "battery.h"
-#include "charge_manager.h"
-#include "charge_state.h"
-#include "chipset.h"
-#include "common.h"
-#include "console.h"
-#include "ec_commands.h"
-#include "hooks.h"
-#include "led_common.h"
-#include "led_pwm.h"
-#include "pwm.h"
-#include "timer.h"
-#include "util.h"
-
-/* Battery percentage thresholds to blink at different rates. */
-#define CRITICAL_LOW_BATTERY_PERCENTAGE 3
-#define LOW_BATTERY_PERCENTAGE 10
-
-#define PULSE_TICK (250 * MSEC)
-
-static uint8_t led_is_pulsing;
-
-static int get_led_id_color(enum pwm_led_id id, int color)
-{
-#ifdef CONFIG_LED_PWM_ACTIVE_CHARGE_PORT_ONLY
- int active_chg_port = charge_manager_get_active_charge_port();
-
- /* We should always be able to turn off a LED. */
- if (color == -1)
- return -1;
-
- if (led_is_pulsing)
- return color;
-
- /* The inactive charge port LEDs should be off. */
- if ((int)id != active_chg_port)
- return -1;
-#endif /* CONFIG_LED_PWM_ACTIVE_CHARGE_PORT_ONLY */
- return color;
-}
-
-void set_pwm_led_color(enum pwm_led_id id, int color)
-{
- struct pwm_led duty = { 0 };
- const struct pwm_led *led = &pwm_leds[id];
-
- if ((id >= CONFIG_LED_PWM_COUNT) || (id < 0) ||
- (color >= EC_LED_COLOR_COUNT) || (color < -1))
- return;
-
- if (color != -1) {
- duty.ch0 = led_color_map[color].ch0;
- duty.ch1 = led_color_map[color].ch1;
- duty.ch2 = led_color_map[color].ch2;
- }
-
- if (led->ch0 != (enum pwm_channel)PWM_LED_NO_CHANNEL)
- led->set_duty(led->ch0, duty.ch0);
- if (led->ch1 != (enum pwm_channel)PWM_LED_NO_CHANNEL)
- led->set_duty(led->ch1, duty.ch1);
- if (led->ch2 != (enum pwm_channel)PWM_LED_NO_CHANNEL)
- led->set_duty(led->ch2, duty.ch2);
-}
-
-static void set_led_color(int color)
-{
- /*
- * We must check if auto control is enabled since the LEDs may be
- * controlled from the AP at anytime.
- */
- if ((led_auto_control_is_enabled(EC_LED_ID_POWER_LED)) ||
- (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)))
- set_pwm_led_color(PWM_LED0, get_led_id_color(PWM_LED0, color));
-
-#if CONFIG_LED_PWM_COUNT >= 2
- if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED))
- set_pwm_led_color(PWM_LED1, get_led_id_color(PWM_LED1, color));
-#endif /* CONFIG_LED_PWM_COUNT >= 2 */
-}
-
-static void set_pwm_led_enable(enum pwm_led_id id, int enable)
-{
- const struct pwm_led *led = &pwm_leds[id];
-
- if ((id >= CONFIG_LED_PWM_COUNT) || (id < 0))
- return;
-
- if (led->ch0 != (enum pwm_channel)PWM_LED_NO_CHANNEL)
- led->enable(led->ch0, enable);
- if (led->ch1 != (enum pwm_channel)PWM_LED_NO_CHANNEL)
- led->enable(led->ch1, enable);
- if (led->ch2 != (enum pwm_channel)PWM_LED_NO_CHANNEL)
- led->enable(led->ch2, enable);
-}
-
-static void init_leds_off(void)
-{
- /* Turn off LEDs such that they are in a known state with zero duty. */
- set_led_color(-1);
-
- /* Enable pwm modules for each channels of LEDs */
- set_pwm_led_enable(PWM_LED0, 1);
-
-#if CONFIG_LED_PWM_COUNT >= 2
- set_pwm_led_enable(PWM_LED1, 1);
-#endif /* CONFIG_LED_PWM_COUNT >= 2 */
-}
-DECLARE_HOOK(HOOK_INIT, init_leds_off, HOOK_PRIO_INIT_PWM + 1);
-
-static uint8_t pulse_period;
-static uint8_t pulse_ontime;
-static enum ec_led_colors pulse_color;
-static void update_leds(void);
-static void pulse_leds_deferred(void);
-DECLARE_DEFERRED(pulse_leds_deferred);
-static void pulse_leds_deferred(void)
-{
- static uint8_t tick_count;
-
- if (!led_is_pulsing) {
- tick_count = 0;
- /*
- * Since we're not pulsing anymore, turn the colors off in case
- * we were in the "on" time.
- */
- set_led_color(-1);
- /* Then show the desired state. */
- update_leds();
- return;
- }
-
- if (tick_count < pulse_ontime)
- set_led_color(pulse_color);
- else
- set_led_color(-1);
-
- tick_count = (tick_count + 1) % pulse_period;
- hook_call_deferred(&pulse_leds_deferred_data, PULSE_TICK);
-}
-
-static void pulse_leds(enum ec_led_colors color, int ontime, int period)
-{
- pulse_color = color;
- pulse_ontime = ontime;
- pulse_period = period;
- led_is_pulsing = 1;
- pulse_leds_deferred();
-}
-
-static int show_charge_state(void)
-{
- enum charge_state chg_st = charge_get_state();
-
- /*
- * The colors listed below are the default, but can be overridden.
- *
- * Solid Amber == Charging
- * Solid Green == Charging (near full)
- * Fast Flash Red == Charging error or battery not present
- */
- if (chg_st == PWR_STATE_CHARGE) {
- led_is_pulsing = 0;
- set_led_color(CONFIG_LED_PWM_CHARGE_COLOR);
- } else if (chg_st == PWR_STATE_CHARGE_NEAR_FULL ||
- chg_st == PWR_STATE_DISCHARGE_FULL) {
- led_is_pulsing = 0;
- set_led_color(CONFIG_LED_PWM_NEAR_FULL_COLOR);
- } else if ((battery_is_present() != BP_YES) ||
- (chg_st == PWR_STATE_ERROR)) {
- /* 500 ms period, 50% duty cycle. */
- pulse_leds(CONFIG_LED_PWM_CHARGE_ERROR_COLOR, 1, 2);
- } else {
- /* Discharging or not charging. */
-#ifdef CONFIG_LED_PWM_CHARGE_STATE_ONLY
- /*
- * If we only show the charge state, the only reason we
- * would pulse the LEDs is if we had an error. If it no longer
- * exists, stop pulsing the LEDs.
- */
- led_is_pulsing = 0;
-#endif /* CONFIG_LED_PWM_CHARGE_STATE_ONLY */
- return 0;
- }
- return 1;
-}
-
-#ifndef CONFIG_LED_PWM_CHARGE_STATE_ONLY
-static int show_battery_state(void)
-{
- int batt_percentage = charge_get_percent();
-
- /*
- * The colors listed below are the default, but can be overridden.
- *
- * Fast Flash Amber == Critical Battery
- * Slow Flash Amber == Low Battery
- */
- if (batt_percentage < CRITICAL_LOW_BATTERY_PERCENTAGE) {
- /* Flash amber faster (1 second period, 50% duty cycle) */
- pulse_leds(CONFIG_LED_PWM_LOW_BATT_COLOR, 2, 4);
- } else if (batt_percentage < LOW_BATTERY_PERCENTAGE) {
- /* Flash amber (4 second period, 50% duty cycle) */
- pulse_leds(CONFIG_LED_PWM_LOW_BATT_COLOR, 8, 16);
- } else {
- /* Sufficient charge, no need to show anything for this. */
- return 0;
- }
- return 1;
-}
-
-static int show_chipset_state(void)
-{
- /* Reflect the SoC state. */
- led_is_pulsing = 0;
- if (chipset_in_state(CHIPSET_STATE_ON)) {
- /* The LED must be on in the Active state. */
- set_led_color(CONFIG_LED_PWM_SOC_ON_COLOR);
- } else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) {
- /* The power LED must pulse in the suspend state. */
- pulse_leds(CONFIG_LED_PWM_SOC_SUSPEND_COLOR, 4, 16);
- } else {
- /* Chipset is off, no need to show anything for this. */
- return 0;
- }
- return 1;
-}
-#endif /* CONFIG_LED_PWM_CHARGE_STATE_ONLY */
-
-static void update_leds(void)
-{
- /* Reflecting the charge state is the highest priority. */
- if (show_charge_state())
- return;
-
-#ifndef CONFIG_LED_PWM_CHARGE_STATE_ONLY
- if (show_battery_state())
- return;
-
- if (show_chipset_state())
- return;
-#endif /* CONFIG_LED_PWM_CHARGE_STATE_ONLY */
-
- set_led_color(-1);
-}
-DECLARE_HOOK(HOOK_TICK, update_leds, HOOK_PRIO_DEFAULT);
-
-#ifdef CONFIG_CMD_LEDTEST
-int command_ledtest(int argc, char **argv)
-{
- int enable;
- int pwm_led_id;
- int led_id;
-
- if (argc < 2)
- return EC_ERROR_PARAM_COUNT;
-
- pwm_led_id = atoi(argv[1]);
- if ((pwm_led_id < 0) || (pwm_led_id >= CONFIG_LED_PWM_COUNT))
- return EC_ERROR_PARAM1;
- led_id = supported_led_ids[pwm_led_id];
-
- if (argc == 2) {
- ccprintf("PWM LED %d: led_id=%d, auto_control=%d\n",
- pwm_led_id, led_id,
- led_auto_control_is_enabled(led_id) != 0);
- return EC_SUCCESS;
- }
- if (!parse_bool(argv[2], &enable))
- return EC_ERROR_PARAM2;
-
- /* Inverted because this drives auto control. */
- led_auto_control(led_id, !enable);
-
- if (argc == 4) {
- /* Set the color. */
- if (!strncmp(argv[3], "red", 3))
- set_pwm_led_color(pwm_led_id, EC_LED_COLOR_RED);
- else if (!strncmp(argv[3], "green", 5))
- set_pwm_led_color(pwm_led_id, EC_LED_COLOR_GREEN);
- else if (!strncmp(argv[3], "amber", 5))
- set_pwm_led_color(pwm_led_id, EC_LED_COLOR_AMBER);
- else if (!strncmp(argv[3], "blue", 4))
- set_pwm_led_color(pwm_led_id, EC_LED_COLOR_BLUE);
- else if (!strncmp(argv[3], "white", 5))
- set_pwm_led_color(pwm_led_id, EC_LED_COLOR_WHITE);
- else if (!strncmp(argv[3], "yellow", 6))
- set_pwm_led_color(pwm_led_id, EC_LED_COLOR_YELLOW);
- else if (!strncmp(argv[3], "off", 3))
- set_pwm_led_color(pwm_led_id, -1);
- else
- return EC_ERROR_PARAM3;
- }
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(ledtest, command_ledtest,
- "<pwm led idx> <enable|disable> [color|off]", "");
-#endif /* defined(CONFIG_CMD_LEDTEST) */