Clean up GPIO module.

No functional changes, just code cleanup.

BUG=chrome-os-partner:15579
BRANCH=none
TEST=gpioget returns reasonable values

Change-Id: I4301ccc68ade775f78f4ccd84710d2cd4bc25252
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/36800
This commit is contained in:
Randall Spangler
2012-10-29 13:14:11 -07:00
committed by Gerrit
parent e82b68bcb9
commit ef89439cc0
5 changed files with 89 additions and 81 deletions

View File

@@ -42,79 +42,6 @@ static int find_gpio_port_index(uint32_t port_base)
return -1;
}
void gpio_pre_init(void)
{
volatile uint32_t scratch __attribute__((unused));
const struct gpio_info *g = gpio_list;
int is_warm = 0;
int i;
if (LM4_SYSTEM_RCGCGPIO == 0x7fff) {
/* This is a warm reboot */
is_warm = 1;
} else {
/* Enable clocks to all the GPIO blocks (since we use all of
* them as GPIOs) */
LM4_SYSTEM_RCGCGPIO |= 0x7fff;
scratch = LM4_SYSTEM_RCGCGPIO; /* Delay a few clocks */
}
/* Disable GPIO commit control for PD7 and PF0, since we don't use the
* NMI pin function. */
LM4_GPIO_LOCK(LM4_GPIO_D) = LM4_GPIO_LOCK_UNLOCK;
LM4_GPIO_CR(LM4_GPIO_D) |= 0x80;
LM4_GPIO_LOCK(LM4_GPIO_D) = 0;
LM4_GPIO_LOCK(LM4_GPIO_F) = LM4_GPIO_LOCK_UNLOCK;
LM4_GPIO_CR(LM4_GPIO_F) |= 0x01;
LM4_GPIO_LOCK(LM4_GPIO_F) = 0;
/* Clear SSI0 alternate function on PA2:5 */
LM4_GPIO_AFSEL(LM4_GPIO_A) &= ~0x3c;
/* Mask all GPIO interrupts */
for (i = 0; gpio_bases[i]; i++)
LM4_GPIO_IM(gpio_bases[i]) = 0;
/* Set all GPIOs to defaults */
for (i = 0; i < GPIO_COUNT; i++, g++) {
/* Use as GPIO, not alternate function */
gpio_set_alternate_function(g->port, g->mask, 0);
/* Set up GPIO based on flags */
gpio_set_flags(i, g->flags);
/* If this is a cold boot, set the level. On a warm reboot,
* leave things where they were or we'll shut off the x86. */
if ((g->flags & GPIO_OUTPUT) && !is_warm)
gpio_set_level(i, g->flags & GPIO_HIGH);
}
}
static void gpio_init(void)
{
/* Enable IRQs now that pins are set up */
task_enable_irq(LM4_IRQ_GPIOA);
task_enable_irq(LM4_IRQ_GPIOB);
task_enable_irq(LM4_IRQ_GPIOC);
task_enable_irq(LM4_IRQ_GPIOD);
task_enable_irq(LM4_IRQ_GPIOE);
task_enable_irq(LM4_IRQ_GPIOF);
task_enable_irq(LM4_IRQ_GPIOG);
task_enable_irq(LM4_IRQ_GPIOH);
task_enable_irq(LM4_IRQ_GPIOJ);
task_enable_irq(LM4_IRQ_GPIOK);
task_enable_irq(LM4_IRQ_GPIOL);
task_enable_irq(LM4_IRQ_GPIOM);
#if defined(KB_SCAN_ROW_IRQ) && (KB_SCAN_ROW_IRQ != LM4_IRQ_GPION)
/* Don't enable interrupts for the keyboard input GPIO bank */
task_enable_irq(LM4_IRQ_GPION);
#endif
task_enable_irq(LM4_IRQ_GPIOP);
task_enable_irq(LM4_IRQ_GPIOQ);
}
DECLARE_HOOK(HOOK_INIT, gpio_init, HOOK_PRIO_DEFAULT);
void gpio_set_alternate_function(int port, int mask, int func)
{
int port_index = find_gpio_port_index(port);
@@ -235,9 +162,91 @@ int gpio_enable_interrupt(enum gpio_signal signal)
return EC_SUCCESS;
}
void gpio_pre_init(void)
{
const struct gpio_info *g = gpio_list;
int is_warm = 0;
int i;
if (LM4_SYSTEM_RCGCGPIO == 0x7fff) {
/* This is a warm reboot */
is_warm = 1;
} else {
/*
* Enable clocks to all the GPIO blocks since we use all of
* them as GPIOs.
*/
LM4_SYSTEM_RCGCGPIO |= 0x7fff;
clock_wait_cycles(6); /* Delay a few clocks */
}
/*
* Disable GPIO commit control for PD7 and PF0, since we don't use the
* NMI pin function.
*/
LM4_GPIO_LOCK(LM4_GPIO_D) = LM4_GPIO_LOCK_UNLOCK;
LM4_GPIO_CR(LM4_GPIO_D) |= 0x80;
LM4_GPIO_LOCK(LM4_GPIO_D) = 0;
LM4_GPIO_LOCK(LM4_GPIO_F) = LM4_GPIO_LOCK_UNLOCK;
LM4_GPIO_CR(LM4_GPIO_F) |= 0x01;
LM4_GPIO_LOCK(LM4_GPIO_F) = 0;
/* Clear SSI0 alternate function on PA2:5 */
LM4_GPIO_AFSEL(LM4_GPIO_A) &= ~0x3c;
/* Mask all GPIO interrupts */
for (i = 0; gpio_bases[i]; i++)
LM4_GPIO_IM(gpio_bases[i]) = 0;
/* Set all GPIOs to defaults */
for (i = 0; i < GPIO_COUNT; i++, g++) {
/* Use as GPIO, not alternate function */
gpio_set_alternate_function(g->port, g->mask, 0);
/* Set up GPIO based on flags */
gpio_set_flags(i, g->flags);
/*
* If this is a cold boot, set the level. On a warm reboot,
* leave things where they were or we'll shut off the main
* chipset.
*/
if ((g->flags & GPIO_OUTPUT) && !is_warm)
gpio_set_level(i, g->flags & GPIO_HIGH);
}
}
/* List of GPIO IRQs to enable */
static const uint8_t gpio_irqs[] = {
LM4_IRQ_GPIOA, LM4_IRQ_GPIOB, LM4_IRQ_GPIOC, LM4_IRQ_GPIOD,
LM4_IRQ_GPIOE, LM4_IRQ_GPIOF, LM4_IRQ_GPIOG, LM4_IRQ_GPIOH,
LM4_IRQ_GPIOJ, LM4_IRQ_GPIOK, LM4_IRQ_GPIOL, LM4_IRQ_GPIOM,
#if defined(KB_SCAN_ROW_IRQ) && (KB_SCAN_ROW_IRQ != LM4_IRQ_GPION)
/* Don't enable interrupts for the keyboard input GPIO bank */
LM4_IRQ_GPION,
#endif
LM4_IRQ_GPIOP, LM4_IRQ_GPIOQ
};
static void gpio_init(void)
{
int i;
/* Enable IRQs now that pins are set up */
for (i = 0; i < ARRAY_SIZE(gpio_irqs); i++)
task_enable_irq(gpio_irqs[i]);
}
DECLARE_HOOK(HOOK_INIT, gpio_init, HOOK_PRIO_DEFAULT);
/*****************************************************************************/
/* Interrupt handlers */
/**
* Handle a GPIO interrupt.
*
* @param port GPIO port (LM4_GPIO_*)
* @param mis Masked interrupt status value for that port
*/
static void gpio_interrupt(int port, uint32_t mis)
{
int i = 0;

View File

@@ -98,7 +98,8 @@ void gpio_set_flags(enum gpio_signal signal, int flags)
* high before it has been configured as such.
*/
if ((flags & GPIO_OUTPUT) && !is_warm_boot)
/* General purpose, MODE = 01
/*
* General purpose, MODE = 01
*
* If this is a cold boot, set the level. On a warm reboot,
* leave things where they were or we'll shut off the AP.

View File

@@ -38,7 +38,8 @@ void gpio_pre_init(void)
/* This is a warm reboot */
is_warm = 1;
} else {
/* Enable all GPIOs clocks
/*
* Enable all GPIOs clocks
* TODO: more fine-grained enabling for power saving
*/
STM32_RCC_AHBENR |= 0x3f;
@@ -141,14 +142,12 @@ void gpio_set_alternate_function(int port, int mask, int func)
STM32_GPIO_MODER_OFF(port) = moder;
}
int gpio_get_level(enum gpio_signal signal)
{
return !!(STM32_GPIO_IDR_OFF(gpio_list[signal].port) &
gpio_list[signal].mask);
}
void gpio_set_level(enum gpio_signal signal, int value)
{
STM32_GPIO_BSRR_OFF(gpio_list[signal].port) =

View File

@@ -8,7 +8,6 @@
#include "common.h"
#include "gpio.h"
const char *gpio_get_name(enum gpio_signal signal)
{
return gpio_list[signal].name;

View File

@@ -58,14 +58,14 @@ extern const struct gpio_info gpio_list[GPIO_COUNT];
#define GPIO_SIGNAL_NOT_IMPLEMENTED(name) {name, LM4_GPIO_A, 0, 0, NULL}
/**
* Pre-initializes the module.
* Pre-initialize GPIOs.
*
* This occurs before clocks or tasks are set up.
*/
void gpio_pre_init(void);
/**
* Get the current value of a signal
* Get the current value of a signal.
*
* @param signal Signal to get
* @return 0 if low, 1 if high.
@@ -73,7 +73,7 @@ void gpio_pre_init(void);
int gpio_get_level(enum gpio_signal signal);
/**
* Get faster access to a GPIO level
* Get faster access to a GPIO level.
*
* Use this function to find out the register address and mask for a GPIO
* value. Then you can just check that instead of calling gpio_get_level().