diff options
author | li feng <li1.feng@intel.com> | 2015-03-12 16:32:54 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-04-17 04:06:31 +0000 |
commit | bbdf126ef58bcc29130a4b5287da11b208ddf5bd (patch) | |
tree | bfe295299a7054bcb5f2a1f4a38c4ae5c18464dd | |
parent | f55a7e5774447dd1dcdb03ce4cc2d62f613b0eda (diff) | |
download | chrome-ec-bbdf126ef58bcc29130a4b5287da11b208ddf5bd.tar.gz |
strago: Added power/battery LED support.
BUG=None
TEST=Verified LED changes color according to AC and battery status.
BRANCH=none
Change-Id: I83cc8255da385e38f08ee13b1eab90ee494b792d
Signed-off-by: li feng <li1.feng@intel.com>
Signed-off-by: Kevin K Wong <kevin.k.wong@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/265543
Reviewed-by: Shawn N <shawnn@chromium.org>
Commit-Queue: Divya Jyothi <divya.jyothi@intel.com>
-rw-r--r-- | board/strago/board.c | 11 | ||||
-rw-r--r-- | board/strago/board.h | 12 | ||||
-rw-r--r-- | board/strago/build.mk | 2 | ||||
-rw-r--r-- | board/strago/led.c | 203 |
4 files changed, 226 insertions, 2 deletions
diff --git a/board/strago/board.c b/board/strago/board.c index 3b749c8691..e175fc1f75 100644 --- a/board/strago/board.c +++ b/board/strago/board.c @@ -18,6 +18,8 @@ #include "motion_sense.h" #include "power.h" #include "power_button.h" +#include "pwm.h" +#include "pwm_chip.h" #include "registers.h" #include "temp_sensor.h" #include "temp_sensor_chip.h" @@ -30,6 +32,15 @@ #include "gpio_list.h" +/* PWM channels. Must be in the exactly same order as in enum pwm_channel. */ +const struct pwm_t pwm_channels[] = { + {0, PWM_CONFIG_ACTIVE_LOW}, + {1, PWM_CONFIG_ACTIVE_LOW}, + {3, PWM_CONFIG_ACTIVE_LOW}, +}; + +BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); + /* power signal list. Must match order of enum power_signal. */ const struct power_signal_info power_signal_list[] = { {GPIO_ALL_SYS_PGOOD, 1, "ALL_SYS_PWRGD"}, diff --git a/board/strago/board.h b/board/strago/board.h index 6961541365..b98b2b654f 100644 --- a/board/strago/board.h +++ b/board/strago/board.h @@ -44,6 +44,9 @@ #define CONFIG_CHARGER_INPUT_CURRENT 2240 #define CONFIG_CHARGER_DISCHARGE_ON_AC +#define CONFIG_PWM +#define CONFIG_LED_COMMON + #define CONFIG_I2C /* I2C ports */ @@ -68,7 +71,6 @@ #undef CONFIG_EOPTION #undef CONFIG_PSTORE #undef CONFIG_PECI -#undef CONFIG_PWM #undef CONFIG_FANS #undef CONFIG_ADC #undef CONFIG_WAKE_PIN @@ -87,6 +89,14 @@ enum power_signal { POWER_SIGNAL_COUNT }; +enum pwm_channel { + PWM_CH_LED_RED, + PWM_CH_LED_BLUE, + PWM_CH_LED_GREEN, + /* Number of PWM channels */ + PWM_CH_COUNT +}; + enum temp_sensor_id { /* TMP432 local and remote sensors */ TEMP_SENSOR_I2C_TMP432_LOCAL, diff --git a/board/strago/build.mk b/board/strago/build.mk index 06e3c66f91..894de2b191 100644 --- a/board/strago/build.mk +++ b/board/strago/build.mk @@ -10,5 +10,5 @@ CHIP:=mec1322 CHIP_SPI_SIZE_KB:=512 -board-y=board.o +board-y=board.o led.o board-$(CONFIG_BATTERY_SMART)+=battery.o diff --git a/board/strago/led.c b/board/strago/led.c new file mode 100644 index 0000000000..1ecaf3d3f2 --- /dev/null +++ b/board/strago/led.c @@ -0,0 +1,203 @@ +/* Copyright 2015 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/Battery LED control for Strago + */ + +#include "charge_state.h" +#include "chipset.h" +#include "console.h" +#include "gpio.h" +#include "hooks.h" +#include "led_common.h" +#include "pwm.h" +#include "registers.h" +#include "util.h" + +#define CPRINTF(format, args...) cprintf(CC_PWM, format, ## args) +#define CPRINTS(format, args...) cprints(CC_PWM, format, ## args) + +#define LED_TOTAL_TICKS 16 +#define LED_ON_TICKS 4 + +static int led_debug; + +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_AMBER, + LED_GREEN, + + /* Number of colors, not a color itself */ + LED_COLOR_COUNT +}; + +/* Brightness vs. color, in the order of off, red, amber, and green */ +static const uint8_t color_brightness[LED_COLOR_COUNT][3] = { + /* {Red, Blue, Green}, */ + [LED_OFF] = { 0, 0, 0}, + [LED_RED] = {100, 0, 0}, + [LED_AMBER] = { 75, 0, 10}, + [LED_GREEN] = { 0, 0, 100}, +}; + +/** + * Set LED color + * + * @param color Enumerated color value + */ +static void set_color(enum led_color color) +{ + pwm_set_duty(PWM_CH_LED_RED, color_brightness[color][0]); + pwm_set_duty(PWM_CH_LED_BLUE, color_brightness[color][1]); + pwm_set_duty(PWM_CH_LED_GREEN, color_brightness[color][2]); +} + +void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) +{ + brightness_range[EC_LED_COLOR_RED] = 100; + brightness_range[EC_LED_COLOR_BLUE] = 100; + brightness_range[EC_LED_COLOR_GREEN] = 100; +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + pwm_set_duty(PWM_CH_LED_RED, brightness[EC_LED_COLOR_RED]); + pwm_set_duty(PWM_CH_LED_BLUE, brightness[EC_LED_COLOR_BLUE]); + pwm_set_duty(PWM_CH_LED_GREEN, brightness[EC_LED_COLOR_GREEN]); + return EC_SUCCESS; +} + +static void strago_led_set_power(void) +{ + static int power_ticks; + static int previous_state_suspend; + + power_ticks++; + + if (chipset_in_state(CHIPSET_STATE_SUSPEND)) { + /* Reset ticks if entering suspend so LED turns amber + * as soon as possible. */ + if (!previous_state_suspend) + power_ticks = 0; + + /* Blink once every four seconds. */ + set_color( + (power_ticks % LED_TOTAL_TICKS) < LED_ON_TICKS ? + LED_AMBER : LED_OFF); + + previous_state_suspend = 1; + return; + } + + previous_state_suspend = 0; + + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + set_color(LED_OFF); + else if (chipset_in_state(CHIPSET_STATE_ON)) + set_color(LED_GREEN); +} + +static void strago_led_set_battery(void) +{ + static int battery_ticks; + + battery_ticks++; + + switch (charge_get_state()) { + case PWR_STATE_CHARGE: + set_color(LED_AMBER); + break; + case PWR_STATE_ERROR: + set_color(LED_RED); + break; + case PWR_STATE_CHARGE_NEAR_FULL: + case PWR_STATE_IDLE: /* External power connected in IDLE. */ + set_color(LED_GREEN); + break; + default: + /* Other states don't alter LED behavior */ + break; + } +} + +static void led_init(void) +{ + /* Configure GPIOs */ + gpio_config_module(MODULE_PWM_LED, 1); + + /* + * Enable PWMs and set to 0% duty cycle. If they're disabled, + * seems to ground the pins instead of letting them float. + */ + pwm_enable(PWM_CH_LED_RED, 1); + pwm_enable(PWM_CH_LED_GREEN, 1); + pwm_enable(PWM_CH_LED_BLUE, 1); + + set_color(LED_OFF); +} +DECLARE_HOOK(HOOK_INIT, led_init, HOOK_PRIO_DEFAULT); + +/** + * Called by hook task every 250 ms + */ +static void led_tick(void) +{ + if (led_debug) + return; + + if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED)) + strago_led_set_power(); + + if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) + strago_led_set_battery(); +} +DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT); + +static void dump_pwm_channels(void) +{ + int ch; + for (ch = 0; ch < 4; ch++) { + CPRINTF("channel = %d\n", ch); + CPRINTF("0x%04X 0x%04X 0x%04X\n", + MEC1322_PWM_CFG(ch), + MEC1322_PWM_ON(ch), + MEC1322_PWM_OFF(ch)); + } +} +/******************************************************************/ +/* Console commands */ +static int command_led_color(int argc, char **argv) +{ + if (argc > 1) { + if (!strcasecmp(argv[1], "debug")) { + led_debug ^= 1; + CPRINTF("led_debug = %d\n", led_debug); + } else if (!strcasecmp(argv[1], "off")) { + set_color(LED_OFF); + } else if (!strcasecmp(argv[1], "red")) { + set_color(LED_RED); + } else if (!strcasecmp(argv[1], "green")) { + set_color(LED_GREEN); + } else if (!strcasecmp(argv[1], "amber")) { + set_color(LED_AMBER); + } else { + /* maybe handle board_discharge_on_ac() too? */ + return EC_ERROR_PARAM1; + } + } + + if (led_debug == 1) + dump_pwm_channels(); + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(ledcolor, command_led_color, + "[debug|red|green|amber|off]", + "Change LED color", + NULL); + |