/*
 * Copyright 2021 NXP
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 */

#include <common/debug.h>
#include <lib/mmio.h>
#include <nxp_gpio.h>

static gpio_init_info_t *gpio_init_info;

void gpio_init(gpio_init_info_t *gpio_init_data)
{
	gpio_init_info = gpio_init_data;
}

/* This function set GPIO pin for raising POVDD. */
int set_gpio_bit(uint32_t *gpio_base_addr,
		 uint32_t bit_num)
{
	uint32_t val = 0U;
	uint32_t *gpdir = NULL;
	uint32_t *gpdat = NULL;

	if (gpio_init_info == NULL) {
		ERROR("GPIO is not initialized.\n");
		return GPIO_FAILURE;
	}
	/* Divide by 4 since we're operating on 32-bit pointer addresses. */
	gpdir = gpio_base_addr + (GPDIR_REG_OFFSET >> 2);
	gpdat = gpio_base_addr + (GPDAT_REG_OFFSET >> 2);

	/*
	 * Set the corresponding bit in direction register
	 * to configure the GPIO as output.
	 */
	val = gpio_read32(gpdir);
	val = val | bit_num;
	gpio_write32(gpdir, val);

	/* Set the corresponding bit in GPIO data register */
	val = gpio_read32(gpdat);
	val = val | bit_num;
	gpio_write32(gpdat, val);

	val = gpio_read32(gpdat);

	if ((val & bit_num) == 0U) {
		return GPIO_FAILURE;
	}

	return GPIO_SUCCESS;
}

/* This function reset GPIO pin set for raising POVDD. */
int clr_gpio_bit(uint32_t *gpio_base_addr, uint32_t bit_num)
{
	uint32_t val = 0U;
	uint32_t *gpdir = NULL;
	uint32_t *gpdat = NULL;


	if (gpio_init_info == NULL) {
		ERROR("GPIO is not initialized.\n");
		return GPIO_FAILURE;
	}

	/* Divide by 4 since we're operating on 32-bit pointer addresses. */
	gpdir = gpio_base_addr + (GPDIR_REG_OFFSET >> 2);
	gpdat = gpio_base_addr + (GPDAT_REG_OFFSET >> 2);

	/*
	 * Reset the corresponding bit in direction and data register
	 * to configure the GPIO as input.
	 */
	val = gpio_read32(gpdat);
	val = val & ~(bit_num);
	gpio_write32(gpdat, val);

	val = gpio_read32(gpdat);

	val = gpio_read32(gpdir);
	val = val & ~(bit_num);
	gpio_write32(gpdir, val);

	val = gpio_read32(gpdat);

	if ((val & bit_num) != 0U) {
		return GPIO_FAILURE;
	}

	return GPIO_SUCCESS;
}

uint32_t *select_gpio_n_bitnum(uint32_t povdd_gpio, uint32_t *bit_num)
{
	uint32_t *ret_gpio;
	uint32_t povdd_gpio_val = 0U;
	uint32_t gpio_num = 0U;

	if (gpio_init_info == NULL) {
		ERROR("GPIO is not initialized.\n");
	}
	/*
	 * Subtract 1 from fuse_hdr povdd_gpio value as
	 * for 0x1 value, bit 0 is to be set
	 * for 0x20 value i.e 32, bit 31 i.e. 0x1f is to be set.
	 * 0x1f - 0x00 : GPIO_1
	 * 0x3f - 0x20 : GPIO_2
	 * 0x5f - 0x40 : GPIO_3
	 * 0x7f - 0x60 : GPIO_4
	 */
	povdd_gpio_val = (povdd_gpio - 1U) & GPIO_SEL_MASK;

	/* Right shift by 5 to divide by 32 */
	gpio_num = povdd_gpio_val >> GPIO_ID_BASE_ADDR_SHIFT;
	*bit_num = 1U << (GPIO_BITS_PER_BASE_REG
			  - (povdd_gpio_val & GPIO_BIT_MASK)
			  - 1U);

	switch (gpio_num) {
	case GPIO_0:
		ret_gpio = (uint32_t *) gpio_init_info->gpio1_base_addr;
		break;
	case GPIO_1:
		ret_gpio = (uint32_t *) gpio_init_info->gpio2_base_addr;
		break;
	case GPIO_2:
		ret_gpio = (uint32_t *) gpio_init_info->gpio3_base_addr;
		break;
	case GPIO_3:
		ret_gpio = (uint32_t *) gpio_init_info->gpio4_base_addr;
		break;
	default:
		ret_gpio = NULL;
	}

	if (ret_gpio == NULL) {
		INFO("GPIO_NUM = %d doesn't exist.\n", gpio_num);
	}

	return ret_gpio;
}
