diff options
-rw-r--r-- | chip/lm4/gpio.c | 155 | ||||
-rw-r--r-- | chip/stm32/gpio-stm32f100.c | 3 | ||||
-rw-r--r-- | chip/stm32/gpio-stm32l15x.c | 5 | ||||
-rw-r--r-- | chip/stm32/gpio.c | 1 | ||||
-rw-r--r-- | include/gpio.h | 6 |
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(). |