summaryrefslogtreecommitdiff
path: root/chip/stm32
diff options
context:
space:
mode:
authorDavid Hendricks <dhendrix@chromium.org>2012-08-08 17:28:13 -0700
committerGerrit <chrome-bot@google.com>2012-08-17 16:55:26 -0700
commit1f091487b210125e351c8397186e2012d8a19cb7 (patch)
treeafd7aa4e91ffad842b05cc415bab7da9e0e31408 /chip/stm32
parentc1c3ec56f89bd2bb132e1e360b0aaf43aa77e0d8 (diff)
downloadchrome-ec-1f091487b210125e351c8397186e2012d8a19cb7.tar.gz
snow/stm32: re-configure power LED on the fly (input vs. pwm)
Usually the power LED is driven by the PWM mode so that its nominal brightness can be set to a "soft" on value. However, when the LED is to remain off the LED should be switched to floating input mode. This reduces voltage leakage. This CL updates the power_led_task to configure the LED however is appropriate and adds board functions to re-configure the GPIO. Signed-off-by: David Hendricks <dhendrix@chromium.org> BRANCH=snow BUG=chrome-os-partner:12381 TEST=LED responds as expected in suspend and on/off states, also tested that leakage is reduced with multimeter Change-Id: If90ac78aaffe7358cce80dd02ec1423c2cb4f664 Reviewed-on: https://gerrit.chromium.org/gerrit/29705 Reviewed-by: Simon Glass <sjg@chromium.org> Commit-Ready: David Hendricks <dhendrix@chromium.org> Tested-by: David Hendricks <dhendrix@chromium.org>
Diffstat (limited to 'chip/stm32')
-rw-r--r--chip/stm32/power_led.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/chip/stm32/power_led.c b/chip/stm32/power_led.c
index a080dbfa07..bc354ee492 100644
--- a/chip/stm32/power_led.c
+++ b/chip/stm32/power_led.c
@@ -7,7 +7,8 @@
* Keyboard power button LED state machine.
*
* This sets up TIM2 to drive the power button LED so that the duty cycle
- * can range from 0-100%.
+ * can range from 0-100%. When the lid is closed or turned off, then the
+ * PWM is disabled and the GPIO is reconfigured to minimize leakage voltage.
*
* In suspend mode, duty cycle transitions progressively slower from 0%
* to 100%, and progressively faster from 100% back down to 0%. This
@@ -25,8 +26,9 @@
#define LED_HOLD_TIME 330000 /* hold for 330ms at min/max */
#define LED_STEP_PERCENT 4 /* incremental value of each step */
-static enum powerled_state led_state;
-static int power_led_percent;
+static enum powerled_state led_state = POWERLED_STATE_ON;
+static enum powerled_config led_config = POWERLED_CONFIG_MANUAL_OFF;
+static int power_led_percent = 100;
void powerled_set_state(enum powerled_state new_state)
{
@@ -35,8 +37,19 @@ void powerled_set_state(enum powerled_state new_state)
task_wake(TASK_ID_POWERLED);
}
-static void power_led_timer_init(void)
+/* set board-level power LED config options (e.g. manual off/on, PWM) */
+void board_power_led_config(enum powerled_state config)
+ __attribute__((weak, alias("__board_power_led_config")));
+
+/* Provide a default function in case the board doesn't have one */
+void __board_power_led_config(enum powerled_config config)
+{
+}
+
+static void power_led_use_pwm(void)
{
+ board_power_led_config(POWERLED_CONFIG_PWM);
+
/* enable TIM2 clock */
STM32_RCC_APB1ENR |= 0x1;
@@ -66,6 +79,20 @@ static void power_led_timer_init(void)
/* enable auto-reload preload, start counting */
STM32_TIM_CR1(2) |= (1 << 7) | (1 << 0);
+
+ led_config = POWERLED_CONFIG_PWM;
+}
+
+static void power_led_manual_off(void)
+{
+ /* disable counter */
+ STM32_TIM_CR1(2) &= ~0x1;
+
+ /* disable TIM2 clock */
+ STM32_RCC_APB1ENR &= ~0x1;
+
+ board_power_led_config(POWERLED_CONFIG_MANUAL_OFF);
+ led_config = POWERLED_CONFIG_MANUAL_OFF;
}
static void power_led_set_duty(int percent)
@@ -109,21 +136,31 @@ static int power_led_step(void)
void power_led_task(void)
{
- power_led_timer_init();
-
while (1) {
int state_timeout = -1;
switch (led_state) {
case POWERLED_STATE_ON:
+ /*
+ * "ON" implies driving the LED using the PWM with a
+ * duty duty cycle of 100%. This produces a softer
+ * brightness than setting the GPIO to solid ON.
+ */
+ if (led_config != POWERLED_CONFIG_PWM)
+ power_led_use_pwm();
power_led_set_duty(100);
state_timeout = -1;
break;
case POWERLED_STATE_OFF:
- power_led_set_duty(0);
+ /* reconfigure GPIO to disable the LED */
+ if (led_config != POWERLED_CONFIG_MANUAL_OFF)
+ power_led_manual_off();
state_timeout = -1;
break;
case POWERLED_STATE_SUSPEND:
+ /* drive using PWM with variable duty cycle */
+ if (led_config != POWERLED_CONFIG_PWM)
+ power_led_use_pwm();
state_timeout = power_led_step();
break;
default: