diff options
Diffstat (limited to 'chip/mec1322/gpio.c')
-rw-r--r-- | chip/mec1322/gpio.c | 291 |
1 files changed, 0 insertions, 291 deletions
diff --git a/chip/mec1322/gpio.c b/chip/mec1322/gpio.c deleted file mode 100644 index 331022c87c..0000000000 --- a/chip/mec1322/gpio.c +++ /dev/null @@ -1,291 +0,0 @@ -/* Copyright 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. - */ - -/* GPIO module for MEC1322 */ - -#include "common.h" -#include "gpio.h" -#include "hooks.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -struct gpio_int_mapping { - int8_t girq_id; - int8_t port_offset; -}; - -/* Mapping from GPIO port to GIRQ info */ -static const struct gpio_int_mapping int_map[22] = { - {11, 0}, {11, 0}, {11, 0}, {11, 0}, - {10, 4}, {10, 4}, {10, 4}, {-1, -1}, - {-1, -1}, {-1, -1}, {9, 10}, {9, 10}, - {9, 10}, {9, 10}, {8, 14}, {8, 14}, - {8, 14}, {-1, -1}, {-1, -1}, {-1, -1}, - {20, 20}, {20, 20} -}; - -void gpio_set_alternate_function(uint32_t port, uint32_t mask, - enum gpio_alternate_func func) -{ - int i; - uint32_t val; - - while (mask) { - i = __builtin_ffs(mask) - 1; - val = MEC1322_GPIO_CTL(port, i); - val &= ~(BIT(12) | BIT(13)); - /* mux_control = DEFAULT, indicates GPIO */ - if (func > GPIO_ALT_FUNC_DEFAULT) - val |= (func & 0x3) << 12; - MEC1322_GPIO_CTL(port, i) = val; - mask &= ~BIT(i); - } -} - -test_mockable int gpio_get_level(enum gpio_signal signal) -{ - uint32_t mask = gpio_list[signal].mask; - int i; - uint32_t val; - - if (mask == 0) - return 0; - i = GPIO_MASK_TO_NUM(mask); - val = MEC1322_GPIO_CTL(gpio_list[signal].port, i); - - return (val & BIT(24)) ? 1 : 0; -} - -void gpio_set_level(enum gpio_signal signal, int value) -{ - uint32_t mask = gpio_list[signal].mask; - int i; - - if (mask == 0) - return; - i = GPIO_MASK_TO_NUM(mask); - - if (value) - MEC1322_GPIO_CTL(gpio_list[signal].port, i) |= BIT(16); - else - MEC1322_GPIO_CTL(gpio_list[signal].port, i) &= ~BIT(16); -} - -void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags) -{ - int i; - uint32_t val; - while (mask) { - i = GPIO_MASK_TO_NUM(mask); - mask &= ~BIT(i); - val = MEC1322_GPIO_CTL(port, i); - - /* - * Select open drain first, so that we don't glitch the signal - * when changing the line to an output. - */ - if (flags & GPIO_OPEN_DRAIN) - val |= BIT(8); - else - val &= ~BIT(8); - - if (flags & GPIO_OUTPUT) { - val |= BIT(9); - val &= ~BIT(10); - } else { - val &= ~BIT(9); - val |= BIT(10); - } - - /* Handle pullup / pulldown */ - if (flags & GPIO_PULL_UP) - val = (val & ~0x3) | 0x1; - else if (flags & GPIO_PULL_DOWN) - val = (val & ~0x3) | 0x2; - else - val &= ~0x3; - - /* Set up interrupt */ - if (flags & (GPIO_INT_F_RISING | GPIO_INT_F_FALLING)) - val |= BIT(7); - else - val &= ~BIT(7); - - val &= ~(0x7 << 4); - - if ((flags & GPIO_INT_F_RISING) && (flags & GPIO_INT_F_FALLING)) - val |= 0x7 << 4; - else if (flags & GPIO_INT_F_RISING) - val |= 0x5 << 4; - else if (flags & GPIO_INT_F_FALLING) - val |= 0x6 << 4; - else if (flags & GPIO_INT_F_HIGH) - val |= 0x1 << 4; - else if (!(flags & GPIO_INT_F_LOW)) /* No interrupt flag set */ - val |= 0x4 << 4; - - /* Set up level */ - if (flags & GPIO_HIGH) - val |= BIT(16); - else if (flags & GPIO_LOW) - val &= ~BIT(16); - - MEC1322_GPIO_CTL(port, i) = val; - } -} - -int gpio_enable_interrupt(enum gpio_signal signal) -{ - int i, port, girq_id, bit_id; - - if (gpio_list[signal].mask == 0) - return EC_SUCCESS; - - i = GPIO_MASK_TO_NUM(gpio_list[signal].mask); - port = gpio_list[signal].port; - girq_id = int_map[port].girq_id; - bit_id = (port - int_map[port].port_offset) * 8 + i; - - MEC1322_INT_ENABLE(girq_id) |= BIT(bit_id); - MEC1322_INT_BLK_EN |= BIT(girq_id); - - return EC_SUCCESS; -} - -int gpio_disable_interrupt(enum gpio_signal signal) -{ - int i, port, girq_id, bit_id; - - if (gpio_list[signal].mask == 0) - return EC_SUCCESS; - - i = GPIO_MASK_TO_NUM(gpio_list[signal].mask); - port = gpio_list[signal].port; - girq_id = int_map[port].girq_id; - bit_id = (port - int_map[port].port_offset) * 8 + i; - - MEC1322_INT_DISABLE(girq_id) = BIT(bit_id); - - return EC_SUCCESS; -} - -int gpio_clear_pending_interrupt(enum gpio_signal signal) -{ - int i, port, girq_id, bit_id; - - if (gpio_list[signal].mask == 0) - return EC_SUCCESS; - - i = GPIO_MASK_TO_NUM(gpio_list[signal].mask); - port = gpio_list[signal].port; - girq_id = int_map[port].girq_id; - bit_id = (port - int_map[port].port_offset) * 8 + i; - - /* Clear interrupt source sticky status bit even if not enabled */ - MEC1322_INT_SOURCE(girq_id) |= 1 << bit_id; - - return EC_SUCCESS; -} - -void gpio_pre_init(void) -{ - int i; - int flags; - int is_warm = system_is_reboot_warm(); - const struct gpio_info *g = gpio_list; - - - for (i = 0; i < GPIO_COUNT; i++, g++) { - flags = g->flags; - - if (flags & GPIO_DEFAULT) - continue; - - /* - * If this is a warm reboot, don't set the output levels or - * we'll shut off the AP. - */ - if (is_warm) - flags &= ~(GPIO_LOW | GPIO_HIGH); - - gpio_set_flags_by_mask(g->port, g->mask, flags); - - /* Use as GPIO, not alternate function */ - gpio_set_alternate_function(g->port, g->mask, - GPIO_ALT_FUNC_NONE); - } -} - -/* Clear any interrupt flags before enabling GPIO interrupt */ -#define ENABLE_GPIO_GIRQ(x) \ - do { \ - MEC1322_INT_SOURCE(x) |= MEC1322_INT_RESULT(x); \ - task_enable_irq(MEC1322_IRQ_GIRQ ## x); \ - } while (0) - -static void gpio_init(void) -{ - ENABLE_GPIO_GIRQ(8); - ENABLE_GPIO_GIRQ(9); - ENABLE_GPIO_GIRQ(10); - ENABLE_GPIO_GIRQ(11); - ENABLE_GPIO_GIRQ(20); -} -DECLARE_HOOK(HOOK_INIT, gpio_init, HOOK_PRIO_DEFAULT); - -/*****************************************************************************/ -/* Interrupt handlers */ - - -/** - * Handler for each GIRQ interrupt. This reads and clears the interrupt bits for - * the GIRQ interrupt, then finds and calls the corresponding GPIO interrupt - * handlers. - * - * @param girq GIRQ index - * @param port_offset GPIO port offset for the given GIRQ - */ -static void gpio_interrupt(int girq, int port_offset) -{ - int i, bit; - const struct gpio_info *g = gpio_list; - uint32_t sts = MEC1322_INT_RESULT(girq); - - MEC1322_INT_SOURCE(girq) |= sts; - - for (i = 0; i < GPIO_IH_COUNT && sts; ++i, ++g) { - bit = (g->port - port_offset) * 8 + __builtin_ffs(g->mask) - 1; - if (sts & BIT(bit)) - gpio_irq_handlers[i](i); - sts &= ~BIT(bit); - } -} - -#define GPIO_IRQ_FUNC(irqfunc, girq, port_offset) \ - void irqfunc(void) \ - { \ - gpio_interrupt(girq, port_offset); \ - } - -GPIO_IRQ_FUNC(__girq_8_interrupt, 8, 14); -GPIO_IRQ_FUNC(__girq_9_interrupt, 9, 10); -GPIO_IRQ_FUNC(__girq_10_interrupt, 10, 4); -GPIO_IRQ_FUNC(__girq_11_interrupt, 11, 0); -GPIO_IRQ_FUNC(__girq_20_interrupt, 20, 20); - -#undef GPIO_IRQ_FUNC - -/* - * Declare IRQs. Nesting this macro inside the GPIO_IRQ_FUNC macro works - * poorly because DECLARE_IRQ() stringizes its inputs. - */ -DECLARE_IRQ(MEC1322_IRQ_GIRQ8, __girq_8_interrupt, 1); -DECLARE_IRQ(MEC1322_IRQ_GIRQ9, __girq_9_interrupt, 1); -DECLARE_IRQ(MEC1322_IRQ_GIRQ10, __girq_10_interrupt, 1); -DECLARE_IRQ(MEC1322_IRQ_GIRQ11, __girq_11_interrupt, 1); -DECLARE_IRQ(MEC1322_IRQ_GIRQ20, __girq_20_interrupt, 1); |