/*
 * Copyright (c) 2018-2021 Nordic Semiconductor ASA.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/init.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/devicetree.h>
#include <zephyr/logging/log.h>
#include <soc.h>
#include <hal/nrf_gpio.h>

LOG_MODULE_REGISTER(board_control, CONFIG_BOARD_NRF9160DK_LOG_LEVEL);

#define GET_CTLR(name, prop, idx) \
	DT_GPIO_CTLR_BY_IDX(DT_NODELABEL(name), prop, idx)
#define GET_PIN(name, prop, idx) \
	DT_GPIO_PIN_BY_IDX(DT_NODELABEL(name), prop, idx)
#define GET_PORT(name, prop, idx) \
	DT_PROP_BY_PHANDLE_IDX(DT_NODELABEL(name), prop, idx, port)
#define GET_FLAGS(name, prop, idx) \
	DT_GPIO_FLAGS_BY_IDX(DT_NODELABEL(name), prop, idx)
#define GET_DEV(name, prop, idx) DEVICE_DT_GET(GET_CTLR(name, prop, idx))

/* If the GPIO pin selected to be the reset line is actually the pin that
 * exposes the nRESET function (P0.18 in nRF52840), there is no need to
 * provide any additional GPIO configuration for it.
 */
#define RESET_INPUT_IS_PINRESET (DT_PROP(DT_NODELABEL(uicr), gpio_as_nreset) && \
				 GET_PORT(reset_input, gpios, 0) == 0 && \
				 GET_PIN(reset_input, gpios, 0) == 18)
#define USE_RESET_GPIO \
	(DT_NODE_HAS_STATUS(DT_NODELABEL(reset_input), okay) && \
	 !RESET_INPUT_IS_PINRESET)

struct switch_cfg {
	const struct device *gpio;
	gpio_pin_t pin;
	gpio_dt_flags_t flags;
	bool on;
#if defined(CONFIG_LOG)
	uint8_t port;
	bool info;
	const char *name;
#endif
};

#define ROUTING_ENABLED(_name) DT_NODE_HAS_STATUS(DT_NODELABEL(_name), okay)
#define SWITCH_CFG(_name, _idx)					\
{								\
	.gpio  = GET_DEV(_name, control_gpios, _idx),		\
	.pin   = GET_PIN(_name, control_gpios, _idx),		\
	.flags = GET_FLAGS(_name, control_gpios, _idx),		\
	.on    = ROUTING_ENABLED(_name),			\
	COND_CODE_1(CONFIG_LOG,					\
	(							\
		.port = GET_PORT(_name, control_gpios, _idx),	\
		.info = (_idx == 0),				\
		.name = #_name,					\
	), ())							\
}
#define HAS_TWO_PINS(_name) \
	DT_PHA_HAS_CELL_AT_IDX(DT_NODELABEL(_name), control_gpios, 1, pin)

#define ROUTING_SWITCH(_name)					\
	COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(_name)),	\
	(							\
		COND_CODE_1(HAS_TWO_PINS(_name),		\
		(						\
			SWITCH_CFG(_name, 1),			\
		), ())						\
		SWITCH_CFG(_name, 0),				\
	), ())

static const struct switch_cfg routing_switches[] = {
	ROUTING_SWITCH(vcom0_pins_routing)
	ROUTING_SWITCH(vcom2_pins_routing)
	ROUTING_SWITCH(led1_pin_routing)
	ROUTING_SWITCH(led2_pin_routing)
	ROUTING_SWITCH(led3_pin_routing)
	ROUTING_SWITCH(led4_pin_routing)
	ROUTING_SWITCH(switch1_pin_routing)
	ROUTING_SWITCH(switch2_pin_routing)
	ROUTING_SWITCH(button1_pin_routing)
	ROUTING_SWITCH(button2_pin_routing)
	ROUTING_SWITCH(nrf_interface_pins_0_2_routing)
	ROUTING_SWITCH(nrf_interface_pins_3_5_routing)
	ROUTING_SWITCH(nrf_interface_pins_6_8_routing)
	ROUTING_SWITCH(nrf_interface_pin_9_routing)
	ROUTING_SWITCH(io_expander_pins_routing)
	ROUTING_SWITCH(external_flash_pins_routing)
};

#if USE_RESET_GPIO
static void chip_reset(const struct device *gpio,
		       struct gpio_callback *cb, uint32_t pins)
{
	const uint32_t stamp = k_cycle_get_32();

	printk("GPIO reset line asserted, device reset.\n");
	printk("Bye @ cycle32 %u\n", stamp);

	NVIC_SystemReset();
}

static void reset_pin_wait_inactive(const struct device *gpio, uint32_t pin)
{
	int val;

	/* Wait until the pin becomes inactive. */
	do {
		val = gpio_pin_get(gpio, pin);
	} while (val > 0);
}

static int reset_pin_configure(void)
{
	int rc;
	static struct gpio_callback gpio_ctx;

	const struct device *gpio = GET_DEV(reset_input, gpios, 0);
	gpio_pin_t pin = GET_PIN(reset_input, gpios, 0);
	gpio_dt_flags_t flags = GET_FLAGS(reset_input, gpios, 0);

	if (!device_is_ready(gpio)) {
		LOG_ERR("%s is not ready", gpio->name);
		return -ENODEV;
	}

	rc = gpio_pin_configure(gpio, pin, flags | GPIO_INPUT);
	if (rc) {
		LOG_ERR("Error %d while configuring pin P%d.%02d",
			rc, GET_PORT(reset_input, gpios, 0), pin);
		return rc;
	}

	gpio_init_callback(&gpio_ctx, chip_reset, BIT(pin));

	rc = gpio_add_callback(gpio, &gpio_ctx);
	if (rc) {
		return rc;
	}

	rc = gpio_pin_interrupt_configure(gpio, pin, GPIO_INT_EDGE_TO_ACTIVE);
	if (rc) {
		return rc;
	}

	LOG_INF("GPIO reset line enabled on pin P%d.%02d, holding...",
		GET_PORT(reset_input, gpios, 0), pin);

	/* Wait until the pin becomes inactive before continuing.
	 * This lets the other side ensure that they are ready.
	 */
	reset_pin_wait_inactive(gpio, pin);

	return 0;
}
#endif /* USE_RESET_GPIO */

static int init(void)
{
	int rc;

	for (int i = 0; i < ARRAY_SIZE(routing_switches); ++i) {
		const struct switch_cfg *cfg = &routing_switches[i];
		gpio_flags_t flags = cfg->flags;

		if (!device_is_ready(cfg->gpio)) {
			LOG_ERR("%s is not ready", cfg->gpio->name);
			return -ENODEV;
		}

		flags |= (cfg->on ? GPIO_OUTPUT_ACTIVE
				  : GPIO_OUTPUT_INACTIVE);
		rc = gpio_pin_configure(cfg->gpio, cfg->pin, flags);
#if defined(CONFIG_LOG)
		LOG_DBG("Configuring P%d.%02d with flags: 0x%08x",
			cfg->port, cfg->pin, flags);
		if (rc) {
			LOG_ERR("Error %d while configuring pin P%d.%02d (%s)",
				rc, cfg->port, cfg->pin, cfg->name);
		} else if (cfg->info) {
			LOG_INF("%s is %s",
				cfg->name, cfg->on ? "ENABLED" : "disabled");
		}
#endif
		if (rc) {
			return rc;
		}
	}

	/* Make sure to configure the switches before initializing
	 * the GPIO reset pin, so that we are connected to
	 * the nRF9160 before enabling our interrupt.
	 */

#if USE_RESET_GPIO
	rc = reset_pin_configure();
	if (rc) {
		LOG_ERR("Unable to configure reset pin, err %d", rc);
		return -EIO;
	}
#endif

	LOG_INF("Board configured.");

	return 0;
}

SYS_INIT(init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);

#define EXT_MEM_CTRL DT_NODELABEL(external_flash_pins_routing)
#if DT_NODE_EXISTS(EXT_MEM_CTRL)

static int early_init(void)
{
	/* As soon as possible after the system starts up, enable the analog
	 * switch that routes signals to the external flash. Otherwise, the
	 * HOLD line in the flash chip may not be properly pulled up internally
	 * and consequently the chip will not respond to any command.
	 * Later on, during the normal initialization performed above, this
	 * analog switch will get configured according to what is selected
	 * in devicetree.
	 */
	uint32_t psel = NRF_DT_GPIOS_TO_PSEL(EXT_MEM_CTRL, control_gpios);
	gpio_dt_flags_t flags = DT_GPIO_FLAGS(EXT_MEM_CTRL, control_gpios);

	if (flags & GPIO_ACTIVE_LOW) {
		nrf_gpio_pin_clear(psel);
	} else {
		nrf_gpio_pin_set(psel);
	}
	nrf_gpio_cfg_output(psel);

	return 0;
}

SYS_INIT(early_init, PRE_KERNEL_1, 0);
#endif
