137 lines
3.2 KiB
C
137 lines
3.2 KiB
C
|
/* Copyright 2017 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.
|
||
|
*
|
||
|
* Power and battery LED control.
|
||
|
*/
|
||
|
|
||
|
#include "battery.h"
|
||
|
#include "charge_manager.h"
|
||
|
#include "charge_state.h"
|
||
|
#include "chipset.h"
|
||
|
#include "ec_commands.h"
|
||
|
#include "gpio.h"
|
||
|
#include "hooks.h"
|
||
|
#include "host_command.h"
|
||
|
#include "led_common.h"
|
||
|
#include "system.h"
|
||
|
#include "util.h"
|
||
|
|
||
|
#define BAT_LED_ON 1
|
||
|
#define BAT_LED_OFF 0
|
||
|
|
||
|
#define LED_TOTAL_TICKS 16
|
||
|
#define LED_ON_TICKS 8
|
||
|
|
||
|
const enum ec_led_id supported_led_ids[] = {
|
||
|
EC_LED_ID_POWER_LED,
|
||
|
EC_LED_ID_BATTERY_LED};
|
||
|
|
||
|
const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
|
||
|
|
||
|
enum led_color {
|
||
|
LED_OFF = 0,
|
||
|
LED_RED,
|
||
|
LED_GREEN,
|
||
|
LED_BLUE,
|
||
|
|
||
|
/* Number of colors, not a color itself */
|
||
|
LED_COLOR_COUNT
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Set LED color
|
||
|
*
|
||
|
* @param color Enumerated color value
|
||
|
*/
|
||
|
static void set_color(enum led_color color)
|
||
|
{
|
||
|
gpio_set_level(GPIO_POWER_LED, !(color == LED_BLUE));
|
||
|
gpio_set_level(GPIO_LED_ACIN, !(color == LED_GREEN));
|
||
|
gpio_set_level(GPIO_LED_CHARGE, !(color == LED_RED));
|
||
|
}
|
||
|
|
||
|
void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
|
||
|
{
|
||
|
brightness_range[EC_LED_COLOR_RED] = 1;
|
||
|
brightness_range[EC_LED_COLOR_BLUE] = 1;
|
||
|
brightness_range[EC_LED_COLOR_GREEN] = 1;
|
||
|
}
|
||
|
|
||
|
int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
|
||
|
{
|
||
|
gpio_set_level(GPIO_POWER_LED, !brightness[EC_LED_COLOR_BLUE]);
|
||
|
gpio_set_level(GPIO_LED_ACIN, !brightness[EC_LED_COLOR_GREEN]);
|
||
|
gpio_set_level(GPIO_LED_CHARGE, !brightness[EC_LED_COLOR_RED]);
|
||
|
|
||
|
return EC_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
static void nautilus_led_set_power_battery(void)
|
||
|
{
|
||
|
static unsigned int power_ticks;
|
||
|
enum led_color cur_led_color = LED_RED;
|
||
|
enum charge_state chg_state = charge_get_state();
|
||
|
int charge_percent = charge_get_percent();
|
||
|
|
||
|
if (chipset_in_state(CHIPSET_STATE_ON)) {
|
||
|
set_color(LED_BLUE);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Flash red on critical battery, which usually inhibits AP power-on. */
|
||
|
if (battery_is_present() != BP_YES ||
|
||
|
charge_percent < CONFIG_CHARGER_MIN_BAT_PCT_FOR_POWER_ON) {
|
||
|
set_color(((power_ticks++ % LED_TOTAL_TICKS) < LED_ON_TICKS) ?
|
||
|
LED_RED : LED_OFF);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* CHIPSET_STATE_OFF */
|
||
|
switch (chg_state) {
|
||
|
case PWR_STATE_DISCHARGE:
|
||
|
if ((charge_get_flags() & CHARGE_FLAG_EXTERNAL_POWER) &&
|
||
|
charge_percent >= BATTERY_LEVEL_NEAR_FULL)
|
||
|
cur_led_color = LED_GREEN;
|
||
|
else
|
||
|
cur_led_color = LED_OFF;
|
||
|
break;
|
||
|
case PWR_STATE_CHARGE:
|
||
|
cur_led_color = LED_RED;
|
||
|
break;
|
||
|
case PWR_STATE_ERROR:
|
||
|
cur_led_color = ((power_ticks++ % LED_TOTAL_TICKS)
|
||
|
< LED_ON_TICKS) ? LED_RED : LED_GREEN;
|
||
|
break;
|
||
|
case PWR_STATE_CHARGE_NEAR_FULL:
|
||
|
case PWR_STATE_IDLE:
|
||
|
if(charge_get_flags() & CHARGE_FLAG_EXTERNAL_POWER)
|
||
|
cur_led_color = LED_GREEN;
|
||
|
else
|
||
|
cur_led_color = LED_OFF;
|
||
|
break;
|
||
|
default:
|
||
|
cur_led_color = LED_RED;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
set_color(cur_led_color);
|
||
|
|
||
|
if (chg_state != PWR_STATE_ERROR)
|
||
|
power_ticks = 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Called by hook task every 250 ms
|
||
|
*/
|
||
|
static void led_tick(void)
|
||
|
{
|
||
|
if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED) &&
|
||
|
led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) {
|
||
|
nautilus_led_set_power_battery();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT);
|