spring: Add function to switch ILIM pin between GPIO and PWM

To save power, we need the ability to switch ILIM pin back to GPIO when
we are not using PWM.

BUG=chrome-os-partner:14319
TEST=In console, test 'ilim on', 'ilim off', and 'ilim 50'.
BRANCH=none

Change-Id: Ib3e0400266ef94df25fca1c6e5f118eba37b3848
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/39835
This commit is contained in:
Vic Yang
2012-12-18 11:16:33 +08:00
committed by Gerrit
parent e22087126a
commit 41204a1cd9
3 changed files with 69 additions and 13 deletions

View File

@@ -93,6 +93,7 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
{"KB_OUT11", GPIO_C, (1<<6), GPIO_KB_OUTPUT, NULL},
{"KB_OUT12", GPIO_C, (1<<7), GPIO_KB_OUTPUT, NULL},
{"BOOST_EN", GPIO_B, (1<<3), GPIO_OUT_HIGH, NULL},
{"ILIM", GPIO_B, (1<<4), GPIO_OUT_LOW, NULL},
};
/* ADC channels */
@@ -130,9 +131,6 @@ void configure_board(void)
STM32_GPIO_AFIO_MAPR = (STM32_GPIO_AFIO_MAPR & ~(0x3 << 10))
| (2 << 10);
/* Set up PWM on TIM3 */
board_configure_pwm();
/*
* Set alternate function for USART1. For alt. function input
* the port is configured in either floating or pull-up/down

View File

@@ -122,10 +122,18 @@ enum gpio_signal {
GPIO_KB_OUT11,
GPIO_KB_OUT12,
GPIO_BOOST_EN,
GPIO_ILIM,
/* Number of GPIOs; not an actual GPIO */
GPIO_COUNT
};
/* ILIM pin control */
enum ilim_config {
ILIM_CONFIG_MANUAL_OFF,
ILIM_CONFIG_MANUAL_ON,
ILIM_CONFIG_PWM,
};
void configure_board(void);
void matrix_interrupt(enum gpio_signal signal);
@@ -139,8 +147,8 @@ int board_pmu_init(void);
/* Force the pmu to reset everything on the board */
void board_hard_reset(void);
/* Set up PWM for ILIM */
void board_configure_pwm(void);
/* Set ILIM pin control type */
void board_ilim_config(enum ilim_config config);
/* Set PWM duty cycle */
void board_pwm_duty_cycle(int percent);

View File

@@ -7,12 +7,27 @@
#include "board.h"
#include "console.h"
#include "gpio.h"
#include "registers.h"
#include "util.h"
#define PWM_FREQUENCY 100 /* Hz */
void board_configure_pwm(void)
static enum ilim_config current_ilim_config = ILIM_CONFIG_MANUAL_OFF;
static void board_ilim_use_gpio(void)
{
/* Disable counter */
STM32_TIM_CR1(3) &= ~0x1;
/* Disable TIM3 clock */
STM32_RCC_APB1ENR &= ~0x2;
/* Switch to GPIO */
gpio_set_flags(GPIO_ILIM, GPIO_OUTPUT);
}
static void board_ilim_use_pwm(void)
{
uint32_t val;
@@ -52,8 +67,31 @@ void board_configure_pwm(void)
STM32_TIM_CR1(3) |= (1 << 7) | (1 << 0);
}
void board_ilim_config(enum ilim_config config)
{
if (config == current_ilim_config)
return;
current_ilim_config = config;
switch (config) {
case ILIM_CONFIG_MANUAL_OFF:
case ILIM_CONFIG_MANUAL_ON:
board_ilim_use_gpio();
gpio_set_level(GPIO_ILIM,
config == ILIM_CONFIG_MANUAL_ON ? 1 : 0);
break;
case ILIM_CONFIG_PWM:
board_ilim_use_pwm();
break;
default:
break;
}
}
void board_pwm_duty_cycle(int percent)
{
if (current_ilim_config != ILIM_CONFIG_PWM)
board_ilim_config(ILIM_CONFIG_PWM);
if (percent < 0)
percent = 0;
if (percent > 100)
@@ -71,16 +109,28 @@ static int command_ilim(int argc, char **argv)
int percent;
if (argc >= 2) {
percent = strtoi(argv[1], &e, 0);
if (*e)
return EC_ERROR_PARAM1;
board_pwm_duty_cycle(percent);
if (strcasecmp(argv[1], "on") == 0)
board_ilim_config(ILIM_CONFIG_MANUAL_ON);
else if (strcasecmp(argv[1], "off") == 0)
board_ilim_config(ILIM_CONFIG_MANUAL_OFF);
else {
percent = strtoi(argv[1], &e, 0);
if (*e)
return EC_ERROR_PARAM1;
board_pwm_duty_cycle(percent);
}
}
ccprintf("PWM duty cycle set to %d%%\n", STM32_TIM_CCR1(3));
if (current_ilim_config == ILIM_CONFIG_MANUAL_ON)
ccprintf("ILIM is GPIO high\n");
else if (current_ilim_config == ILIM_CONFIG_MANUAL_OFF)
ccprintf("ILIM is GPIO low\n");
else
ccprintf("ILIM is PWM duty cycle %d%%\n", STM32_TIM_CCR1(3));
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(ilim, command_ilim,
"[percent]",
"Set or show ILIM duty cycle",
"[percent | on | off]",
"Set or show ILIM duty cycle/GPIO value",
NULL);