summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/lm4/gpio.c155
-rw-r--r--chip/stm32/gpio-stm32f100.c3
-rw-r--r--chip/stm32/gpio-stm32l15x.c5
-rw-r--r--chip/stm32/gpio.c1
-rw-r--r--include/gpio.h6
5 files changed, 89 insertions, 81 deletions
diff --git a/chip/lm4/gpio.c b/chip/lm4/gpio.c
index b5b1105632..7c8a7a73f4 100644
--- a/chip/lm4/gpio.c
+++ b/chip/lm4/gpio.c
@@ -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;
diff --git a/chip/stm32/gpio-stm32f100.c b/chip/stm32/gpio-stm32f100.c
index b308138e93..55c2b309de 100644
--- a/chip/stm32/gpio-stm32f100.c
+++ b/chip/stm32/gpio-stm32f100.c
@@ -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.
diff --git a/chip/stm32/gpio-stm32l15x.c b/chip/stm32/gpio-stm32l15x.c
index 659e05df78..587abb7644 100644
--- a/chip/stm32/gpio-stm32l15x.c
+++ b/chip/stm32/gpio-stm32l15x.c
@@ -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) =
diff --git a/chip/stm32/gpio.c b/chip/stm32/gpio.c
index d488c9c619..b7423900e2 100644
--- a/chip/stm32/gpio.c
+++ b/chip/stm32/gpio.c
@@ -8,7 +8,6 @@
#include "common.h"
#include "gpio.h"
-
const char *gpio_get_name(enum gpio_signal signal)
{
return gpio_list[signal].name;
diff --git a/include/gpio.h b/include/gpio.h
index 77923ef4cb..05470b3f1d 100644
--- a/include/gpio.h
+++ b/include/gpio.h
@@ -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().