mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
rambi: Control LEDs using PWM
Rambi has a pair of LEDs which are attached to the PWM fan controller.
Add support for them. Also add a generic 'pwmduty' command which can
be used to get/set the duty cycle for any PWM channel.
Also fix rounding errors in pwm module, so that set/get duty doesn't
keep rounding down.
BUG=chrome-os-partner:22895
BRANCH=none
TEST=Boot rambi. LEDs are off.
pwmduty -> both are 0%
pwmduty 0 10 -> green LED on dimly
pwmduty 1 10 -> red LED on dimly
pwmduty 0 99 -> green LED on brightly
pwmduty 1 100 -> red LED on brightly
pwmduty 1 0 -> red LED off
pwmduty 1 -1 -> red LED turns back on because fan controller is disabled
pwmduty -> channel 0 at 99%, channel 1 disabled
Build all platforms. Pass all unit tests.
Change-Id: Ib0a6289a757554e696a9a0153a85bdc34e2ee2ae
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/172094
This commit is contained in:
committed by
chrome-internal-fetch
parent
99157c265c
commit
ff8c8fee79
@@ -14,7 +14,6 @@
|
||||
#define CONFIG_KEYBOARD_PROTOCOL_MKBP
|
||||
#define CONFIG_POWER_BUTTON
|
||||
#undef CONFIG_WATCHDOG
|
||||
#define CONFIG_PWM
|
||||
#define CONFIG_SWITCH
|
||||
|
||||
#undef CONFIG_CONSOLE_HISTORY
|
||||
|
||||
@@ -110,7 +110,7 @@ const struct gpio_alt_func gpio_alt_funcs[] = {
|
||||
{GPIO_D, 0x0f, 2, MODULE_SPI}, /* SPI1 */
|
||||
{GPIO_L, 0x3f, 15, MODULE_LPC}, /* LPC */
|
||||
{GPIO_M, 0x33, 15, MODULE_LPC}, /* LPC */
|
||||
{GPIO_N, 0x50, 1, MODULE_PWM_LED}, /* Power LEDs */
|
||||
{GPIO_N, 0x50, 1, MODULE_PWM_LED, GPIO_OPEN_DRAIN}, /* Power LEDs */
|
||||
};
|
||||
const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
|
||||
|
||||
@@ -152,8 +152,8 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT);
|
||||
|
||||
/* PWM channels */
|
||||
const struct pwm_t pwm_channels[] = {
|
||||
[PWM_CH_LED_GREEN] = {4, 0},
|
||||
[PWM_CH_LED_RED] = {3, 0},
|
||||
[PWM_CH_LED_GREEN] = {4, PWM_CONFIG_ACTIVE_LOW},
|
||||
[PWM_CH_LED_RED] = {3, PWM_CONFIG_ACTIVE_LOW},
|
||||
};
|
||||
|
||||
BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define CONFIG_CMD_GSV
|
||||
#define CONFIG_EXTPOWER_GPIO
|
||||
#define CONFIG_KEYBOARD_PROTOCOL_8042
|
||||
#define CONFIG_LED_COMMON
|
||||
#undef CONFIG_PECI
|
||||
#define CONFIG_POWER_BUTTON
|
||||
#define CONFIG_POWER_BUTTON_X86
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
# the IC is TI Stellaris LM4
|
||||
CHIP:=lm4
|
||||
|
||||
board-y=board.o
|
||||
board-y=board.o led.o
|
||||
|
||||
45
board/rambi/led.c
Normal file
45
board/rambi/led.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/* Copyright (c) 2013 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 Rambi
|
||||
*/
|
||||
|
||||
#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};
|
||||
const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
|
||||
|
||||
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_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_GREEN, brightness[EC_LED_COLOR_GREEN]);
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
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_LED_RED, 1);
|
||||
pwm_set_duty(PWM_CH_LED_RED, 0);
|
||||
|
||||
pwm_enable(PWM_CH_LED_GREEN, 1);
|
||||
pwm_set_duty(PWM_CH_LED_GREEN, 0);
|
||||
}
|
||||
DECLARE_HOOK(HOOK_INIT, led_init, HOOK_PRIO_DEFAULT);
|
||||
@@ -15,13 +15,12 @@ chip-y=clock.o gpio.o hwtimer.o jtag.o system.o uart.o
|
||||
# Optional chip modules
|
||||
chip-$(CONFIG_ADC)+=adc.o chip_temp_sensor.o
|
||||
chip-$(CONFIG_EEPROM)+=eeprom.o
|
||||
chip-$(CONFIG_FAN)+=fan.o
|
||||
chip-$(CONFIG_FLASH)+=flash.o
|
||||
chip-$(CONFIG_I2C)+=i2c.o
|
||||
chip-$(CONFIG_LPC)+=lpc.o
|
||||
chip-$(CONFIG_PECI)+=peci.o
|
||||
chip-$(CONFIG_PWM)+=pwm.o
|
||||
chip-$(CONFIG_FAN)+=fan.o
|
||||
chip-$(CONFIG_PWM_KBLIGHT)+=pwm_kblight.o
|
||||
chip-$(CONFIG_SPI)+=spi.o
|
||||
chip-$(CONFIG_WATCHDOG)+=watchdog.o
|
||||
chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "pwm.h"
|
||||
#include "pwm_data.h"
|
||||
#include "registers.h"
|
||||
#include "thermal.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Maximum RPM for PWM controller */
|
||||
@@ -47,7 +46,10 @@ void pwm_set_duty(enum pwm_channel ch, int percent)
|
||||
else if (percent > 100)
|
||||
percent = 100;
|
||||
|
||||
duty = (MAX_PWM * percent) / 100;
|
||||
if (pwm->flags & PWM_CONFIG_ACTIVE_LOW)
|
||||
percent = 100 - percent;
|
||||
|
||||
duty = (MAX_PWM * percent + 50) / 100;
|
||||
|
||||
/* Always enable the channel */
|
||||
pwm_enable(ch, 1);
|
||||
@@ -59,8 +61,13 @@ void pwm_set_duty(enum pwm_channel ch, int percent)
|
||||
int pwm_get_duty(enum pwm_channel ch)
|
||||
{
|
||||
const struct pwm_t *pwm = pwm_channels + ch;
|
||||
int percent = ((LM4_FAN_FANCMD(pwm->channel) >> 16) * 100 + MAX_PWM / 2)
|
||||
/ MAX_PWM;
|
||||
|
||||
return (LM4_FAN_FANCMD(pwm->channel) >> 16) * 100 / MAX_PWM;
|
||||
if (pwm->flags & PWM_CONFIG_ACTIVE_LOW)
|
||||
percent = 100 - percent;
|
||||
|
||||
return percent;
|
||||
}
|
||||
|
||||
static void pwm_init(void)
|
||||
@@ -109,4 +116,4 @@ static void pwm_init(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
DECLARE_HOOK(HOOK_INIT, pwm_init, HOOK_PRIO_DEFAULT);
|
||||
DECLARE_HOOK(HOOK_INIT, pwm_init, HOOK_PRIO_INIT_PWM);
|
||||
|
||||
@@ -135,6 +135,11 @@ void pwm_enable(enum pwm_channel ch, int enabled)
|
||||
pwm_disable(ch);
|
||||
}
|
||||
|
||||
int pwm_get_enabled(enum pwm_channel ch)
|
||||
{
|
||||
return using_pwm[ch];
|
||||
}
|
||||
|
||||
static void pwm_reconfigure(enum pwm_channel ch)
|
||||
{
|
||||
using_pwm[ch] = 0;
|
||||
|
||||
@@ -37,6 +37,7 @@ common-$(CONFIG_EXTPOWER_FALCO)+=extpower_falco.o
|
||||
common-$(CONFIG_EXTPOWER_GPIO)+=extpower_gpio.o
|
||||
common-$(CONFIG_EXTPOWER_KIRBY)+=extpower_kirby.o
|
||||
common-$(CONFIG_EXTPOWER_SPRING)+=extpower_spring.o
|
||||
common-$(CONFIG_FAN)+=pwm_fan.o
|
||||
common-$(CONFIG_FLASH)+=flash_common.o
|
||||
common-$(CONFIG_FMAP)+=fmap.o
|
||||
common-$(CONFIG_I2C)+=i2c_common.o
|
||||
@@ -53,16 +54,17 @@ common-$(CONFIG_ONEWIRE)+=onewire.o
|
||||
common-$(CONFIG_POWER_BUTTON)+=power_button.o
|
||||
common-$(CONFIG_POWER_BUTTON_X86)+=power_button_x86.o
|
||||
common-$(CONFIG_PSTORE)+=pstore_commands.o
|
||||
common-$(CONFIG_FAN)+=pwm_fan.o
|
||||
common-$(CONFIG_PWM)+=pwm_common.o
|
||||
common-$(CONFIG_PWM_KBLIGHT)+=pwm_kblight.o
|
||||
common-$(CONFIG_REGULATOR_IR357X)+=regulator_ir357x.o
|
||||
common-$(CONFIG_SWITCH)+=switch.o
|
||||
common-$(CONFIG_WIRELESS)+=wireless.o
|
||||
common-$(CONFIG_TEMP_SENSOR)+=temp_sensor.o thermal.o
|
||||
common-$(CONFIG_TEMP_SENSOR_G781)+=temp_sensor_g781.o
|
||||
common-$(CONFIG_TEMP_SENSOR_TMP006)+=temp_sensor_tmp006.o
|
||||
common-$(CONFIG_USB_PORT_POWER_SMART)+=usb_port_power_smart.o
|
||||
common-$(CONFIG_USB_PORT_POWER_DUMB)+=usb_port_power_dumb.o
|
||||
common-$(CONFIG_USB_PORT_POWER_SMART)+=usb_port_power_smart.o
|
||||
common-$(CONFIG_USB_SWITCH_TSU6721)+=usb_switch_tsu6721.o
|
||||
common-$(CONFIG_WIRELESS)+=wireless.o
|
||||
common-$(HAS_TASK_CHIPSET)+=chipset.o
|
||||
common-$(HAS_TASK_CONSOLE)+=console.o
|
||||
common-$(HAS_TASK_HOSTCMD)+=host_command.o host_event_commands.o
|
||||
|
||||
63
common/pwm_common.c
Normal file
63
common/pwm_common.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/* Copyright (c) 2013 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.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "pwm.h"
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
* Print status of a PWM channel.
|
||||
*
|
||||
* @param ch Channel to print.
|
||||
*/
|
||||
static void print_channel(enum pwm_channel ch)
|
||||
{
|
||||
if (pwm_get_enabled(ch))
|
||||
ccprintf(" %d: %d%%\n", ch, pwm_get_duty(ch));
|
||||
else
|
||||
ccprintf(" %d: disabled\n", ch);
|
||||
}
|
||||
|
||||
static int cc_pwm_duty(int argc, char **argv)
|
||||
{
|
||||
int percent = 0;
|
||||
int ch;
|
||||
char *e;
|
||||
|
||||
if (argc < 2) {
|
||||
ccprintf("PWM channels:\n");
|
||||
for (ch = 0; ch < PWM_CH_COUNT; ch++)
|
||||
print_channel(ch);
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
ch = strtoi(argv[1], &e, 0);
|
||||
if (*e || ch < 0 || ch >= PWM_CH_COUNT)
|
||||
return EC_ERROR_PARAM1;
|
||||
|
||||
if (argc > 2) {
|
||||
percent = strtoi(argv[2], &e, 0);
|
||||
if (*e || percent > 100) {
|
||||
/* Bad param */
|
||||
return EC_ERROR_PARAM1;
|
||||
} else if (percent < 0) {
|
||||
/* Negative = disable */
|
||||
pwm_enable(ch, 0);
|
||||
} else {
|
||||
ccprintf("Setting channel %d to %d%%\n", ch, percent);
|
||||
pwm_enable(ch, 1);
|
||||
pwm_set_duty(ch, percent);
|
||||
}
|
||||
}
|
||||
|
||||
print_channel(ch);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_CONSOLE_COMMAND(pwmduty, cc_pwm_duty,
|
||||
"[channel [<percent> | -1=disable]]",
|
||||
"Get/set PWM duty cycles ",
|
||||
NULL);
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
/* PWM control module for Chromebook keyboard backlight. */
|
||||
|
||||
#include "clock.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "gpio.h"
|
||||
@@ -13,15 +12,9 @@
|
||||
#include "host_command.h"
|
||||
#include "lid_switch.h"
|
||||
#include "pwm.h"
|
||||
#include "registers.h"
|
||||
#include "system.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Max PWM for controller */
|
||||
#define MAX_PWM 0x1ff
|
||||
|
||||
#define PWMKBD_SYSJUMP_TAG 0x504b /* "PK" */
|
||||
#define PWM_HOOK_VERSION 1
|
||||
/* Saved PWM state across sysjumps */
|
||||
@@ -27,6 +27,8 @@ enum hook_priority {
|
||||
HOOK_PRIO_INIT_LID = HOOK_PRIO_FIRST + 3,
|
||||
/* Power button inits before chipset and switch */
|
||||
HOOK_PRIO_INIT_POWER_BUTTON = HOOK_PRIO_FIRST + 4,
|
||||
/* PWM inits before modules which might use it (fans, LEDs) */
|
||||
HOOK_PRIO_INIT_PWM = HOOK_PRIO_FIRST + 5,
|
||||
|
||||
/* Specific values to lump temperature-related hooks together */
|
||||
HOOK_PRIO_TEMP_SENSOR = 6000,
|
||||
|
||||
Reference in New Issue
Block a user