/*
 * Copyright (c) 2016 Open-RnD Sp. z o.o.
 * Copyright (c) 2021 Linaro Limited
 * Copyright (c) 2021 Nordic Semiconductor ASA
 * Copyright (c) 2021 Microchip Technology Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT microchip_xec_pinctrl

#include <drivers/pinctrl.h>
#include <soc.h>

/* Microchip XEC: each GPIO pin has two 32-bit control register.
 * The first 32-bit register contains all pin features except
 * slew rate and driver strength in the second control register.
 * We compute the register index from the beginning of the GPIO
 * control address space which is the same range of the PINCTRL
 * parent node.
 */

static void config_drive_slew(struct gpio_regs * const regs, uint32_t idx, uint32_t conf)
{
	uint32_t slew = conf & (MCHP_XEC_OSPEEDR_MASK << MCHP_XEC_OSPEEDR_POS);
	uint32_t drvstr = conf & (MCHP_XEC_ODRVSTR_MASK << MCHP_XEC_ODRVSTR_POS);
	uint32_t val = 0;
	uint32_t mask = 0;

	if (slew != MCHP_XEC_OSPEEDR_NO_CHG) {
		mask |= MCHP_GPIO_CTRL2_SLEW_MASK;
		if (slew == MCHP_XEC_OSPEEDR_FAST) {
			val |= MCHP_GPIO_CTRL2_SLEW_FAST;
		}
	}
	if (drvstr != MCHP_XEC_ODRVSTR_NO_CHG) {
		mask |= MCHP_GPIO_CTRL2_DRV_STR_MASK;
		val |= (drvstr << MCHP_GPIO_CTRL2_DRV_STR_POS);
	}

	if (!mask) {
		return;
	}

	regs->CTRL2[idx] = (regs->CTRL2[idx] & ~mask) | (val & mask);
}

/* Configure pin by writing GPIO Control and Control2 registers.
 * NOTE: Disable alternate output feature since the GPIO driver does.
 * While alternate output is enabled (default state of pin) HW does not
 * ignores writes to the parallel output bit for the pin. To set parallel
 * output value we must keep pin direction as input, set alternate output
 * disable, program pin value to parallel output bit, and then disable
 * alternate output mode.
 */
static int xec_config_pin(uint32_t portpin, uint32_t conf, uint32_t altf)
{
	struct gpio_regs * const regs = (struct gpio_regs * const)DT_INST_REG_ADDR(0);
	uint32_t port = MCHP_XEC_PINMUX_PORT(portpin);
	uint32_t pin = (uint32_t)MCHP_XEC_PINMUX_PIN(portpin);
	uint32_t msk = MCHP_GPIO_CTRL_AOD_MASK;
	uint32_t val = MCHP_GPIO_CTRL_AOD_DIS;
	uint32_t idx = 0u;
	uint32_t temp = 0u;

	if (port >= NUM_MCHP_GPIO_PORTS) {
		return -EINVAL;
	}

	/* MCHP XEC family is 32 pins per port */
	idx = (port * 32U) + pin;

	config_drive_slew(regs, idx, conf);

	/* default input pad enabled, buffer type push-pull, no internal pulls */
	msk |= (BIT(MCHP_GPIO_CTRL_INPAD_DIS_POS) | MCHP_GPIO_CTRL_BUFT_MASK |
			MCHP_GPIO_CTRL_PUD_MASK | MCHP_GPIO_CTRL_DIR_MASK |
			MCHP_GPIO_CTRL_MUX_MASK);

	if (conf & BIT(MCHP_XEC_PIN_LOW_POWER_POS)) {
		msk |= MCHP_GPIO_CTRL_PWRG_MASK;
		val |= MCHP_GPIO_CTRL_PWRG_OFF;
	}

	temp = (conf & MCHP_XEC_PUPDR_MASK) >> MCHP_XEC_PUPDR_POS;
	switch (temp) {
	case MCHP_XEC_PULL_UP:
		val |= MCHP_GPIO_CTRL_PUD_PU;
		break;
	case MCHP_XEC_PULL_DOWN:
		val |= MCHP_GPIO_CTRL_PUD_PD;
		break;
	case MCHP_XEC_REPEATER:
		val |= MCHP_GPIO_CTRL_PUD_RPT;
		break;
	default:
		val |= MCHP_GPIO_CTRL_PUD_NONE;
		break;
	}

	if ((conf >> MCHP_XEC_OTYPER_POS) & MCHP_XEC_OTYPER_MASK) {
		val |= MCHP_GPIO_CTRL_BUFT_OPENDRAIN;
	}

	regs->CTRL[idx] = (regs->CTRL[idx] & ~msk) | val;

	temp = (conf >> MCHP_XEC_OVAL_POS) & MCHP_XEC_OVAL_MASK;
	if (temp) {
		if (temp == MCHP_XEC_OVAL_DRV_HIGH) {
			regs->PAROUT[port] |= BIT(pin);
		} else {
			regs->PAROUT[port] &= ~BIT(pin);
		}

		regs->CTRL[idx] |= MCHP_GPIO_CTRL_DIR_OUTPUT;
	}

	val = (uint32_t)((altf & MCHP_GPIO_CTRL_MUX_MASK0) << MCHP_GPIO_CTRL_MUX_POS);
	regs->CTRL[idx] |= val;

	return 0;
}

int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
			   uintptr_t reg)
{
	uint32_t portpin, mux, cfg, func;
	int ret;

	ARG_UNUSED(reg);

	for (uint8_t i = 0U; i < pin_cnt; i++) {
		mux = pins[i].pinmux;

		func = MCHP_XEC_PINMUX_FUNC(mux);
		if (func >= MCHP_AFMAX) {
			return -EINVAL;
		}

		cfg = pins[i].pincfg;
		portpin = MEC_XEC_PINMUX_PORT_PIN(mux);

		ret = xec_config_pin(portpin, cfg, func);
		if (ret < 0) {
			return ret;
		}
	}

	return 0;
}
