/*
 * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or
 * an affiliate of Cypress Semiconductor Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @brief Pin control driver for Infineon CAT1 MCU family.
 */

#include <zephyr/drivers/pinctrl.h>
#include <cyhal_gpio.h>
#include <cy_gpio.h>

#define GPIO_PORT_OR_NULL(node_id) \
	COND_CODE_1(DT_NODE_EXISTS(node_id), ((GPIO_PRT_Type *)DT_REG_ADDR(node_id)), (NULL))

/* @brief Array containing pointers to each GPIO port.
 *
 * Entries will be NULL if the GPIO port is not enabled.
 */
static GPIO_PRT_Type *const gpio_ports[] = {
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt0)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt1)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt2)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt3)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt4)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt5)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt6)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt7)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt8)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt9)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt10)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt11)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt12)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt13)),
	GPIO_PORT_OR_NULL(DT_NODELABEL(gpio_prt14))
};

/* @brief This function returns gpio drive mode, according to.
 * bias and drive mode params defined in pinctrl node.
 *
 * @param flags - bias and drive mode flags from pinctrl node.
 */
static uint32_t soc_gpio_get_drv_mode(uint32_t flags)
{
	uint32_t drv_mode = CY_GPIO_DM_ANALOG;
	uint32_t _flags;

	_flags = ((flags & SOC_GPIO_FLAGS_MASK) >> SOC_GPIO_FLAGS_POS);

	if (_flags & SOC_GPIO_OPENDRAIN) {
		/* drive_open_drain */
		drv_mode = (_flags & SOC_GPIO_INPUTENABLE) ? CY_GPIO_DM_OD_DRIVESLOW
							   : CY_GPIO_DM_OD_DRIVESLOW_IN_OFF;

	} else if (_flags & SOC_GPIO_OPENSOURCE) {
		/* drive_open_source */
		drv_mode = (_flags & SOC_GPIO_INPUTENABLE) ? CY_GPIO_DM_OD_DRIVESHIGH
							   : CY_GPIO_DM_OD_DRIVESHIGH_IN_OFF;

	} else if (_flags & SOC_GPIO_PUSHPULL) {
		/* drive_push_pull */
		drv_mode = (_flags & SOC_GPIO_INPUTENABLE) ? CY_GPIO_DM_STRONG
							   : CY_GPIO_DM_STRONG_IN_OFF;

	} else if ((_flags & SOC_GPIO_PULLUP) && (_flags & SOC_GPIO_PULLDOWN)) {
		/* bias_pull_up and bias_pull_down */
		drv_mode = (_flags & SOC_GPIO_INPUTENABLE) ? CY_GPIO_DM_PULLUP_DOWN
							   : CY_GPIO_DM_PULLUP_DOWN_IN_OFF;

	} else if (_flags & SOC_GPIO_PULLUP) {
		/* bias_pull_up */
		drv_mode = (_flags & SOC_GPIO_INPUTENABLE) ? CY_GPIO_DM_PULLUP
							   : CY_GPIO_DM_PULLUP_IN_OFF;

	} else if (_flags & SOC_GPIO_PULLDOWN) {
		/* bias_pull_down */
		drv_mode = (_flags & SOC_GPIO_INPUTENABLE) ? CY_GPIO_DM_PULLDOWN
							   : CY_GPIO_DM_PULLDOWN_IN_OFF;
	} else if ((_flags & SOC_GPIO_HIGHZ) | (_flags & SOC_GPIO_INPUTENABLE)) {
		/* bias_pull_down */
		drv_mode = CY_GPIO_DM_HIGHZ;
	} else {
		/* nothing do here */
	}

	return drv_mode;
}

int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
{
	ARG_UNUSED(reg);

	for (uint8_t i = 0U; i < pin_cnt; i++) {
		uint32_t drv_mode = soc_gpio_get_drv_mode(pins[i].pincfg);
		uint32_t hsiom = CAT1_PINMUX_GET_HSIOM_FUNC(pins[i].pinmux);
		uint32_t port_num = CAT1_PINMUX_GET_PORT_NUM(pins[i].pinmux);
		uint32_t pin_num = CAT1_PINMUX_GET_PIN_NUM(pins[i].pinmux);

		/* Initialize pin */
		Cy_GPIO_Pin_FastInit(gpio_ports[port_num], pin_num, drv_mode, 1, hsiom);

		/* Force output to enable pulls */
		switch (drv_mode) {
		case CY_GPIO_DM_PULLUP:
			Cy_GPIO_Write(gpio_ports[port_num], pin_num, 1);
			break;
		case CY_GPIO_DM_PULLDOWN:
			Cy_GPIO_Write(gpio_ports[port_num], pin_num, 0);
			break;
		default:
			/* do nothing */
			break;
		}
	}

	return 0;
}
