summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorgit-CarryBK_Chen.compal.com <CarryBK_Chen@compal.com>2014-02-20 10:14:01 +0800
committerDave Parker <dparker@chromium.org>2014-02-23 16:44:31 +0000
commit1767e7887fa0d90b1aefc93c230c69a3cc423381 (patch)
treeedc5c9c21c139e201e1ea14e7bf238a066e985ab /board
parentc98a49f7f952501a28aeaa2647b15edb6a406abc (diff)
downloadchrome-ec-1767e7887fa0d90b1aefc93c230c69a3cc423381.tar.gz
Clapper: Add LED function
1. Power LED 2. Battery LED 3. Test LED BRANCH=clapper BUG=chrome-os-partner:24371 TEST=manually Signed-off-by: Carry Chen <CarryBK_Chen@compal.com> Change-Id: I6e371964180077791b19a8839c418e0f57013c10 Reviewed-on: https://chromium-review.googlesource.com/187190 Reviewed-by: Dave Parker <dparker@chromium.org> Commit-Queue: Antonie Cheng <Antonie_Cheng@compal.com> Tested-by: Antonie Cheng <Antonie_Cheng@compal.com> Commit-Queue: Dave Parker <dparker@chromium.org>
Diffstat (limited to 'board')
-rw-r--r--board/clapper/board.c8
-rw-r--r--board/clapper/board.h8
-rw-r--r--board/clapper/build.mk4
-rw-r--r--board/clapper/led.c218
4 files changed, 229 insertions, 9 deletions
diff --git a/board/clapper/board.c b/board/clapper/board.c
index 17c9f69525..d1ecf712eb 100644
--- a/board/clapper/board.c
+++ b/board/clapper/board.c
@@ -133,7 +133,8 @@ const struct gpio_alt_func gpio_alt_funcs[] = {
{GPIO_D, 0x0f, 2, MODULE_SPI}, /* SPI1 */
{GPIO_L, 0x3f, 15, MODULE_LPC}, /* LPC */
{GPIO_M, 0x21, 15, MODULE_LPC}, /* LPC */
- {GPIO_N, 0x14, 1, MODULE_PWM_LED, GPIO_OPEN_DRAIN}, /* FAN0PWM 3&4 */
+ {GPIO_N, 0x14, 1, MODULE_PWM_LED, GPIO_OPEN_DRAIN}, /* FAN0PWM 2&3 */
+ {GPIO_M, 0x40, 1, MODULE_PWM_LED, GPIO_OPEN_DRAIN}, /* FAN0PWM0 */
};
const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
@@ -175,8 +176,9 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT);
/* PWM channels. Must be in the exactly same order as in enum pwm_channel. */
const struct pwm_t pwm_channels[] = {
- {4, PWM_CONFIG_ACTIVE_LOW},
- {3, PWM_CONFIG_ACTIVE_LOW},
+ {3, PWM_CONFIG_ACTIVE_LOW}, /* Amber battery LED */
+ {2, PWM_CONFIG_ACTIVE_LOW}, /* White battery LED */
+ {0, PWM_CONFIG_ACTIVE_LOW}, /* White power LED */
};
BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
diff --git a/board/clapper/board.h b/board/clapper/board.h
index 4678077ece..a128ddeb7c 100644
--- a/board/clapper/board.h
+++ b/board/clapper/board.h
@@ -30,7 +30,7 @@
#define CONFIG_KEYBOARD_COL2_INVERTED
#define CONFIG_KEYBOARD_IRQ_GPIO GPIO_KBD_IRQ_L
#define CONFIG_KEYBOARD_PROTOCOL_8042
-#undef CONFIG_LED_COMMON
+#define CONFIG_LED_COMMON
#define CONFIG_LOW_POWER_IDLE
#undef CONFIG_PECI
#define CONFIG_POWER_BUTTON
@@ -166,10 +166,10 @@ enum adc_channel {
ADC_CH_COUNT
};
-/* TODO(crosbug.com/p/24371): Add support for charger + power LEDs */
enum pwm_channel {
- PWM_CH_LED_GREEN,
- PWM_CH_LED_RED,
+ PWM_CH_BATTERY_LED_AMBER,
+ PWM_CH_BATTERY_LED_WHITE,
+ PWM_CH_POWER_LED_WHITE,
/* Number of PWM channels */
PWM_CH_COUNT
diff --git a/board/clapper/build.mk b/board/clapper/build.mk
index b82aa39df6..887e527d1b 100644
--- a/board/clapper/build.mk
+++ b/board/clapper/build.mk
@@ -1,5 +1,5 @@
# -*- makefile -*-
-# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Copyright (c) 2014 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.
#
@@ -9,4 +9,4 @@
# the IC is TI Stellaris LM4
CHIP:=lm4
-board-y=board.o battery.o
+board-y=board.o battery.o led.o
diff --git a/board/clapper/led.c b/board/clapper/led.c
new file mode 100644
index 0000000000..81e2b34ec1
--- /dev/null
+++ b/board/clapper/led.c
@@ -0,0 +1,218 @@
+/* Copyright (c) 2014 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.
+ *
+ * Battery LED control for Clapper
+ */
+
+#include "charge_state.h"
+#include "chipset.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "led_common.h"
+#include "pwm.h"
+#include "util.h"
+
+const enum ec_led_id supported_led_ids[] = {
+ EC_LED_ID_BATTERY_LED, 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,
+
+ /* Number of colors, not a color itself */
+ LED_COLOR_COUNT
+};
+
+/* Brightness vs. color, for {amber, white} LEDs */
+static const uint8_t color_brightness[LED_COLOR_COUNT][2] = {
+ {0, 0},
+ {100, 0},
+ {0, 100},
+};
+
+/**
+ * Set battery/charger LED color
+ *
+ * @param color Enumerated color value
+ */
+static void set_color_battery(enum led_color color)
+{
+ pwm_set_duty(PWM_CH_BATTERY_LED_AMBER, color_brightness[color][0]);
+ pwm_set_duty(PWM_CH_BATTERY_LED_WHITE, color_brightness[color][1]);
+}
+
+/**
+ * Set power LED color
+ *
+ * @param color Enumerated color value
+ */
+static void set_color_power(enum led_color color)
+{
+ /* Setting the color to AMBER is equivalent to OFF */
+ pwm_set_duty(PWM_CH_POWER_LED_WHITE, color_brightness[color][1]);
+}
+
+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] = 100;
+ brightness_range[EC_LED_COLOR_YELLOW] = 100;
+ break;
+ case EC_LED_ID_POWER_LED:
+ brightness_range[EC_LED_COLOR_WHITE] = 100;
+ break;
+ default:
+ /* Nothing to do */
+ break;
+ }
+}
+
+int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
+{
+ switch (led_id) {
+ case EC_LED_ID_BATTERY_LED:
+ pwm_set_duty(PWM_CH_BATTERY_LED_AMBER,
+ brightness[EC_LED_COLOR_YELLOW]);
+ pwm_set_duty(PWM_CH_BATTERY_LED_WHITE,
+ brightness[EC_LED_COLOR_WHITE]);
+ break;
+ case EC_LED_ID_POWER_LED:
+ pwm_set_duty(PWM_CH_POWER_LED_WHITE,
+ brightness[EC_LED_COLOR_WHITE]);
+ break;
+ default:
+ break;
+ }
+ return EC_SUCCESS;
+}
+
+static void power_led_update(void)
+{
+ static unsigned timer;
+
+ /* 2 sec */
+ if (++timer > 20)
+ timer = 0;
+
+ /* S5 */
+ if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
+ set_color_power(LED_OFF);
+
+ /* S3 */
+ } else if (chipset_in_state(CHIPSET_STATE_SUSPEND)) {
+ /* Flashing 1 sec on, 1 sec off */
+ set_color_power((timer <= 10) ? LED_OFF : LED_WHITE);
+
+ /* S0 */
+ } else if (chipset_in_state(CHIPSET_STATE_ON)) {
+ set_color_power(LED_WHITE);
+ }
+}
+
+static void battery_led_update(void)
+{
+ static unsigned timer;
+ unsigned battery = charge_get_percent();
+
+ /* least common multiple : 15, 33, 51 */
+ if (++timer == 2805)
+ timer = 0;
+
+ switch (charge_get_state()) {
+ case PWR_STATE_CHARGE:
+ /* 1% ~ 4% */
+ if (battery > 0 && battery < 5) {
+ /* 1000 ms on */
+ if (timer%15 < 10)
+ set_color_battery(LED_AMBER);
+ /* 500 ms off */
+ else
+ set_color_battery(LED_OFF);
+ }
+ /* 5% ~ 19% */
+ else if (battery >= 5 && battery < 20) {
+ /* 3200 ms on */
+ if (timer%33 < 32)
+ set_color_battery(LED_AMBER);
+ /* 100 ms off */
+ else
+ set_color_battery(LED_OFF);
+ }
+ /* 20% ~ 79% */
+ else if (battery >= 20 && battery < 80) {
+ /* 5000 ms on */
+ if (timer%51 < 50)
+ set_color_battery(LED_WHITE);
+ /* 100 ms off */
+ else
+ set_color_battery(LED_OFF);
+ }
+ /* 80%i ~ 100% */
+ else if (battery >= 80 && battery <= 100)
+ set_color_battery(LED_WHITE);
+ break;
+ case PWR_STATE_DISCHARGE: /* without AC */
+ case PWR_STATE_CHARGE_NEAR_FULL: /* with AC */
+ case PWR_STATE_IDLE: /* with AC */
+ /* not S0 */
+ if (!chipset_in_state(CHIPSET_STATE_ON))
+ set_color_battery(LED_OFF);
+ /* 1% ~ 4% */
+ else if (battery > 0 && battery < 5) {
+ /* 1000 ms on */
+ if (timer%15 < 10)
+ set_color_battery(LED_AMBER);
+ /* 500 ms off */
+ else
+ set_color_battery(LED_OFF);
+ }
+ /* 5% ~ 19% */
+ else if (battery >= 5 && battery < 20)
+ set_color_battery(LED_AMBER);
+ /* 20% ~ 100% */
+ else if (battery >= 20 && battery <= 100)
+ set_color_battery(LED_WHITE);
+ break;
+ default:
+ /* Other states don't alter LED behavior */
+ break;
+ }
+}
+
+/**
+ * Called every 100 ms
+ */
+static void led_update(void)
+{
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
+ power_led_update();
+
+ if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED))
+ battery_led_update();
+
+ hook_call_deferred(led_update, 100 * MSEC);
+}
+DECLARE_DEFERRED(led_update);
+
+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, the LM4
+ * seems to ground the pins instead of letting them float.
+ */
+ pwm_enable(PWM_CH_BATTERY_LED_AMBER, 1);
+ pwm_enable(PWM_CH_BATTERY_LED_WHITE, 1);
+ pwm_enable(PWM_CH_POWER_LED_WHITE, 1);
+ set_color_battery(LED_OFF);
+ set_color_power(LED_OFF);
+
+ hook_call_deferred(led_update, 0);
+}
+DECLARE_HOOK(HOOK_INIT, led_init, HOOK_PRIO_DEFAULT);