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

#include <zephyr/zephyr.h>
#include <zephyr/init.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/devicetree.h>
#include <zephyr/logging/log.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 (IS_ENABLED(CONFIG_GPIO_AS_PINRESET) && \
				 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 IS_ENABLED(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(const struct device *dev)
{
	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 IS_ENABLED(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(const struct device *dev)
{
	/* 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
