/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/* Include esp-idf headers first to avoid redefining BIT() macro */
#include <soc/gpio_reg.h>
#include <soc/io_mux_reg.h>
#include <soc/soc.h>

#include <errno.h>
#include <misc/util.h>
#include <pinmux.h>

/* DR_REG_IO_MUX_BASE is a 32-bit constant.  Define a pin mux table
 * using only offsets, in order to reduce ROM footprint.
 * This table has been compiled from information present in "ESP32
 * Technical Reference Manual", "IO_MUX Pad List".  The items in
 * this array covers only the first function of each I/O pin.
 * Items with offset `0` are not present in the documentation, and
 * trying to configure them will result in -EINVAL being returned.
 */
#define PIN(id)   ((PERIPHS_IO_MUX_ ## id ## _U) - (DR_REG_IO_MUX_BASE))
static const u8_t pin_mux_off[] = {
	PIN(GPIO0),    PIN(U0TXD),    PIN(GPIO2),    PIN(U0RXD),
	PIN(GPIO4),    PIN(GPIO5),    PIN(SD_CLK),   PIN(SD_DATA0),
	PIN(SD_DATA1), PIN(SD_DATA2), PIN(SD_DATA3), PIN(SD_CMD),
	PIN(MTDI),     PIN(MTCK),     PIN(MTMS),     PIN(MTDO),
	PIN(GPIO16),   PIN(GPIO17),   PIN(GPIO18),   PIN(GPIO19),
	0,             PIN(GPIO21),   PIN(GPIO22),   PIN(GPIO23),
	0,             PIN(GPIO25),   PIN(GPIO26),   PIN(GPIO27),
	0,             0,             0,             0,
	PIN(GPIO32),   PIN(GPIO33),   PIN(GPIO34),   PIN(GPIO35),
	PIN(GPIO36),   PIN(GPIO37),   PIN(GPIO38),   PIN(GPIO39)
};
#undef PIN

static u32_t *reg_for_pin(u32_t pin)
{
	u8_t off;

	if (pin >= ARRAY_SIZE(pin_mux_off)) {
		return NULL;
	}

	off = pin_mux_off[pin];
	if (!off) {
		return NULL;
	}

	return (u32_t *)(DR_REG_IO_MUX_BASE + off);
}

static int set_reg(u32_t pin, u32_t clr_mask, u32_t set_mask)
{
	volatile u32_t *reg = reg_for_pin(pin);
	u32_t v;

	if (!reg) {
		return -EINVAL;
	}

	v = *reg;
	v &= ~clr_mask;
	v |= set_mask;
	*reg = v;

	return 0;
}

static int pinmux_set(struct device *dev, u32_t pin, u32_t func)
{
	ARG_UNUSED(dev);

	/* FIXME: Drive strength (FUN_DRV) is also set here to its maximum
	 * value due to a deficiency in the pinmux API.  This setting is
	 * part of the GPIO API.
	 */

	if (func > 6) {
		return -EINVAL;
	}

	return set_reg(pin, MCU_SEL_M, func<<MCU_SEL_S | 2<<FUN_DRV_S);
}

static int pinmux_get(struct device *dev, u32_t pin, u32_t *func)
{
	volatile u32_t *reg = reg_for_pin(pin);

	if (!reg) {
		return -EINVAL;
	}

	*func = (*reg & MCU_SEL_M) >> MCU_SEL_S;

	ARG_UNUSED(dev);
	return 0;
}

static int pinmux_pullup(struct device *dev, u32_t pin, u8_t func)
{
	switch (func) {
	case PINMUX_PULLUP_DISABLE:
		return set_reg(pin, FUN_PU, FUN_PD);
	case PINMUX_PULLUP_ENABLE:
		return set_reg(pin, FUN_PD, FUN_PU);
	}

	ARG_UNUSED(dev);
	return -EINVAL;
}

#define CFG(id)   ((GPIO_ ## id ## _REG) & 0xff)
static int pinmux_input(struct device *dev, u32_t pin, u8_t func)
{
	static const u8_t offs[2][3] = {
		{ CFG(ENABLE1_W1TC), CFG(ENABLE1_W1TS), 32 },
		{ CFG(ENABLE_W1TC), CFG(ENABLE_W1TS), 0 },
	};
	const u8_t *line = offs[pin < 32];
	volatile u32_t *reg;
	int r;

	/* Since PINMUX_INPUT_ENABLED == 1 and PINMUX_OUTPUT_ENABLED == 0,
	 * we can not set a gpio port as input and output at the same time,
	 * So we always set the gpio as input. Thus, the gpio can be used on
	 * I2C drivers for example.
	 */
	r = set_reg(pin, 0, FUN_IE);
	if (func == PINMUX_INPUT_ENABLED) {
		reg = (u32_t *)(DR_REG_GPIO_BASE + line[0]);
	} else if (func == PINMUX_OUTPUT_ENABLED) {
		if (pin >= 34U && pin <= 39U) {
			/* These pins are input only */
			return -EINVAL;
		}
		reg = (u32_t *)(DR_REG_GPIO_BASE + line[1]);
	} else {
		return -EINVAL;
	}

	if (r < 0) {
		return r;
	}

	*reg = BIT(pin - line[2]);

	ARG_UNUSED(dev);
	return 0;
}
#undef CFG

static struct pinmux_driver_api api_funcs = {
	.set = pinmux_set,
	.get = pinmux_get,
	.pullup = pinmux_pullup,
	.input = pinmux_input
};

static int pinmux_initialize(struct device *device)
{
	u32_t pin;

	for (pin = 0U; pin < ARRAY_SIZE(pin_mux_off); pin++) {
		pinmux_set(NULL, pin, 0);
	}

	ARG_UNUSED(device);
	return 0;
}

/* Initialize using PRE_KERNEL_1 priority so that GPIO can use the pin
 * mux driver.
 */
DEVICE_AND_API_INIT(pmux_dev, CONFIG_PINMUX_NAME,
		    &pinmux_initialize, NULL, NULL,
		    PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
		    &api_funcs);
