/*
 * Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @brief PINMUX driver for the SiFive Freedom Processor
 */

#include <errno.h>
#include <device.h>
#include <pinmux.h>
#include <soc.h>

struct pinmux_sifive_config {
	u32_t base;
};

struct pinmux_sifive_regs_t {
	u32_t iof_en;
	u32_t iof_sel;
};

#define DEV_CFG(dev)					\
	((const struct pinmux_sifive_config * const)	\
	 (dev)->config->config_info)

#define DEV_PINMUX(dev)						\
	((struct pinmux_sifive_regs_t *)(DEV_CFG(dev))->base)

static int pinmux_sifive_set(struct device *dev, u32_t pin, u32_t func)
{
	volatile struct pinmux_sifive_regs_t *pinmux = DEV_PINMUX(dev);

	if (func > SIFIVE_PINMUX_IOF1 ||
	    pin >= SIFIVE_PINMUX_PINS)
		return -EINVAL;

	if (func == SIFIVE_PINMUX_IOF1)
		pinmux->iof_sel |= (SIFIVE_PINMUX_IOF1 << pin);
	else
		pinmux->iof_sel &= ~(SIFIVE_PINMUX_IOF1 << pin);

	/* Enable IO function for this pin */
	pinmux->iof_en |= (1 << pin);

	return 0;
}

static int pinmux_sifive_get(struct device *dev, u32_t pin, u32_t *func)
{
	volatile struct pinmux_sifive_regs_t *pinmux = DEV_PINMUX(dev);

	if (pin >= SIFIVE_PINMUX_PINS ||
	    func == NULL)
		return -EINVAL;

	*func = (pinmux->iof_sel & (SIFIVE_PINMUX_IOF1 << pin)) ?
		SIFIVE_PINMUX_IOF1 : SIFIVE_PINMUX_IOF0;

	return 0;
}

static int pinmux_sifive_pullup(struct device *dev, u32_t pin, u8_t func)
{
	return -ENOTSUP;
}

static int pinmux_sifive_input(struct device *dev, u32_t pin, u8_t func)
{
	return -ENOTSUP;
}

static int pinmux_sifive_init(struct device *dev)
{
	volatile struct pinmux_sifive_regs_t *pinmux = DEV_PINMUX(dev);

	/* Ensure that all pins are disabled initially */
	pinmux->iof_en = 0x0;

	return 0;
}

static const struct pinmux_driver_api pinmux_sifive_driver_api = {
	.set = pinmux_sifive_set,
	.get = pinmux_sifive_get,
	.pullup = pinmux_sifive_pullup,
	.input = pinmux_sifive_input,
};

static const struct pinmux_sifive_config pinmux_sifive_0_config = {
	.base = SIFIVE_PINMUX_0_BASE_ADDR,
};

DEVICE_AND_API_INIT(pinmux_sifive_0, CONFIG_PINMUX_SIFIVE_0_NAME,
		    &pinmux_sifive_init, NULL,
		    &pinmux_sifive_0_config,
		    PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
		    &pinmux_sifive_driver_api);
