summaryrefslogtreecommitdiff
path: root/chip/nrf51/gpio.c
diff options
context:
space:
mode:
authorLouis Yung-Chieh Lo <yjlou@chromium.org>2014-07-15 10:41:16 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-07-29 02:21:22 +0000
commitf93f1cfe77ed3603ab16047d79a283a781416db4 (patch)
treed0ec489650265d06c90297b884f02b96b18094c0 /chip/nrf51/gpio.c
parentbbb5b0636b5d2b9a9d339e32142bf775717bd929 (diff)
downloadchrome-ec-f93f1cfe77ed3603ab16047d79a283a781416db4.tar.gz
hadoken: initial commit.
Board bring up. GPIO / UART / timer / console / task / hook are working now. BRANCH=tot BUG=none TEST=run on evaluation board and see LED 0/1 are blinking. Console commands are available to use. Change-Id: If93a2c94b8abe1c2c931c03a7a12ddd2bed9d9f6 Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/209403 Reviewed-by: Vic Yang <victoryang@chromium.org>
Diffstat (limited to 'chip/nrf51/gpio.c')
-rw-r--r--chip/nrf51/gpio.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/chip/nrf51/gpio.c b/chip/nrf51/gpio.c
new file mode 100644
index 0000000000..db2bd1a5e6
--- /dev/null
+++ b/chip/nrf51/gpio.c
@@ -0,0 +1,101 @@
+/* Copyright (c) 2014 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.
+ */
+
+#include "common.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "registers.h"
+#include "task.h"
+
+
+void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags)
+{
+ uint32_t val = 0;
+ uint32_t bit = 31 - __builtin_clz(mask);
+
+ if (flags & GPIO_OUTPUT)
+ val |= 1 << 0;
+ else if (flags & GPIO_INPUT)
+ val |= 0 << 0;
+
+ if (flags & GPIO_PULL_DOWN)
+ val |= 1 << 2;
+ else if (flags & GPIO_PULL_UP)
+ val |= 3 << 2;
+
+ if (flags & GPIO_OUTPUT) {
+ if (flags & GPIO_HIGH)
+ NRF51_GPIO0_OUTSET = 1 << bit;
+ else if (flags & GPIO_LOW)
+ NRF51_GPIO0_OUTCLR = 1 << bit;
+ }
+
+ NRF51_PIN_CNF(bit) = val;
+}
+
+
+static void gpio_init(void)
+{
+ task_enable_irq(NRF51_PERID_GPIOTE);
+}
+DECLARE_HOOK(HOOK_INIT, gpio_init, HOOK_PRIO_DEFAULT);
+
+
+test_mockable int gpio_get_level(enum gpio_signal signal)
+{
+ return !!(NRF51_GPIO0_IN & gpio_list[signal].mask);
+}
+
+void gpio_set_level(enum gpio_signal signal, int value)
+{
+ if (value)
+ NRF51_GPIO0_OUTSET = gpio_list[signal].mask;
+ else
+ NRF51_GPIO0_OUTCLR = gpio_list[signal].mask;
+}
+
+
+void gpio_pre_init(void)
+{
+ const struct gpio_info *g = gpio_list;
+ int is_warm = 0;
+ int i;
+
+ if (NRF51_POWER_RESETREAS & (1 << 2)) {
+ /* This is a warm reboot */
+ is_warm = 1;
+ }
+
+ /* Set all GPIOs to defaults */
+ for (i = 0; i < GPIO_COUNT; i++, g++) {
+ int 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);
+
+ /* Set up GPIO based on flags */
+ gpio_set_flags_by_mask(g->port, g->mask, flags);
+ }
+}
+
+
+/*
+ * TODO: implement GPIO interrupt.
+ */
+int gpio_enable_interrupt(enum gpio_signal signal)
+{
+ return EC_ERROR_INVAL;
+}
+void gpio_interrupt(void)
+{
+}
+DECLARE_IRQ(NRF51_PERID_GPIOTE, gpio_interrupt, 1);