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

#define DT_DRV_COMPAT sifive_iof

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

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

struct pinmux_sifive_config {
	uintptr_t base;
};

struct pinmux_sifive_regs_t {
	uint32_t iof_en;
	uint32_t iof_sel;
};

#define DEV_PINMUX(dev)						\
	((struct pinmux_sifive_regs_t *)			\
	 ((const struct pinmux_sifive_config * const)(dev->config))->base)

static int pinmux_sifive_set(const struct device *dev, uint32_t pin,
			     uint32_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(const struct device *dev, uint32_t pin,
			     uint32_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(const struct device *dev, uint32_t pin,
				uint8_t func)
{
	return -ENOTSUP;
}

static int pinmux_sifive_input(const struct device *dev, uint32_t pin,
			       uint8_t func)
{
	return -ENOTSUP;
}

static int pinmux_sifive_init(const 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 = DT_INST_REG_ADDR(0),
};

DEVICE_DT_INST_DEFINE(0,
		    &pinmux_sifive_init, NULL, NULL,
		    &pinmux_sifive_0_config,
		    PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
		    &pinmux_sifive_driver_api);
