/**
 * @file hv_pm51_app_Pinshare.c
 * @brief Init standby Pinshare of Project.
 *
 * @verbatim
 * ==============================================================================
 *                        ##### How to use #####
 * ==============================================================================
 *
 *
 @ endverbatim
 *
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2024-06-18
 */
#include "hv_pm51_Base.h"
#include "hv_pm51_Setting.h"
#include "hv_pm51_driver_Reg.h"
#include "hv_pm51_driver_GPIO.h"

#define CHIP_REG_MAX_BIT_NUM   32
#define HV_GPIO_STBY_PIN_MAX_NUM           (8)

static xdata ULONG32 PinshareArray[][4] = {
    {0x11008400, 22, 22, 0x1},//reg_stby_gp0_func_sel
    {0x1100841c, 16, 23, 0x29},//reg_stby_gp0_io_ctrl
    {0x11008400, 23, 23, 0x0},//reg_stby_gp1_func_sel
    {0x11008404, 22, 23, 0x0},//reg_stby_gpio_i_in_sel
    {0x1100841c, 24, 28, 0x19},//reg_stby_gp1_io_ctrl
    {0x11008400, 24, 24, 0x1},//reg_stby_gp2_func_sel
    {0x11008424, 10, 11, 0x2},//reg_uart_rxd_i_use_sel
    {0x11008404, 24, 25, 0x0},//reg_uart_rxd_i_in_sel
    {0x11008420, 0, 4, 0x18},//reg_stby_gp2_io_ctrl
    {0x11008400, 25, 26, 0x1},//reg_stby_gp3_func_sel
    {0x11008420, 5, 9, 0x9},//reg_stby_gp3_io_ctrl
    {0x11008400, 27, 27, 0x1},//reg_stby_gp4_func_sel
    {0x11008420, 16, 23, 0x0},//reg_stby_gp4_io_ctrl
    {0x11008400, 5, 5, 0x1},//reg_stby_gp5_func_sel
    {0x11008420, 24, 31, 0x0},//reg_stby_gp5_io_ctrl
    {0x11008400, 28, 29, 0x0},//reg_dp_rx1_hpd_func_sel
    {0x1100840c, 8, 15, 0x29},//reg_dp_rx1_hpd_io_ctrl
    {0x11008400, 4, 4, 0x1},//reg_dp_rx1_cable_func_sel
    {0x1100840c, 0, 7, 0x58},//reg_dp_rx1_cable_io_ctrl
    {0x11008404, 2, 3, 0x0},//reg_dp1_cable_in_sel
    {0x11008424, 16, 16, 0x0},//reg_stby_gp6_func_sel
    {0x11008424, 27, 27, 0x1},//reg_stby_gpio_i6_use_sel
    {0x11008424, 0, 4, 0x19},//reg_stby_gp6_io_ctrl
    {0x11008424, 19, 20, 0x0},//reg_hdmi_rx0_ddc1_func_sel
    {0x11008404, 12, 13, 0x0},//reg_hdmi_rx0_ddc1_in_in_sel
    {0x11008410, 5, 9, 0x19},//reg_hdmi_rx0_ddc1_io_ctrl
    {0x11008400, 9, 9, 0x0},//reg_hdmi_rx0_ddc0_func_sel
    {0x11008404, 10, 11, 0x0},//reg_hdmi_rx0_ddc0_in_in_sel
    {0x11008410, 0, 4, 0x18},//reg_hdmi_rx0_ddc0_io_ctrl
    {0x11008400, 7, 8, 0x0},//reg_hdmi_rx0_cec_func_sel
    {0x11008404, 8, 9, 0x0},//reg_hdmi_rx0_cec_in_in_sel
    {0x1100840c, 21, 25, 0x19},//reg_hdmi_rx0_cec_io_ctrl
    {0x11008424, 17, 17, 0x0},//reg_stby_gp7_func_sel
    {0x11008424, 5, 9, 0x19},//reg_stby_gp7_io_ctrl
    {0x11008424, 21, 22, 0x0},//reg_hdmi_rx1_ddc1_func_sel
    {0x11008404, 18, 19, 0x0},//reg_hdmi_rx1_ddc1_in_in_sel
    {0x11008414, 5, 9, 0x19},//reg_hdmi_rx1_ddc1_io_ctrl
    {0x11008400, 13, 13, 0x0},//reg_hdmi_rx1_ddc0_func_sel
    {0x11008404, 16, 17, 0x0},//reg_hdmi_rx1_ddc0_in_in_sel
    {0x11008414, 0, 4, 0x18},//reg_hdmi_rx1_ddc0_io_ctrl
    {0x11008400, 11, 12, 0x2},//reg_hdmi_rx1_cec_func_sel
    {0x11008424, 23, 23, 0x0},//reg_stby_gpio_i2_use_sel
    {0x11008410, 15, 19, 0x19},//reg_hdmi_rx1_cec_io_ctrl
    {0x11008400, 10, 10, 0x1},//reg_hdmi_rx1_cable_det_func_sel
    {0x11008404, 6, 7, 0x0},//reg_hdmi1_rx_cable_det_in_sel
    {0x11008410, 10, 14, 0x18},//reg_hdmi_rx1_cable_det_io_ctrl
};

static xdata UCHAR8 GpioConfig[][3] =
{
   //index, directiton, default level
   {162,0,0},
   {186,1,0},
   {191,1,0},
   {194,0,0},
};

static xdata UCHAR8 s_GpioSdbyPinMap[HV_GPIO_STBY_PIN_MAX_NUM][2] =
{
    {161,},
    {162,},
    {163,194},
    {164,195},
    {165,182},
    {166,185},
    {186,189},
    {191,}
};

static UCHAR8 StbyPinMapIndex(UCHAR8 ucPinIdx)
{
    UCHAR8 ucGpioIdx = 0;

    for (ucGpioIdx = 0; ucGpioIdx < HV_GPIO_STBY_PIN_MAX_NUM; ucGpioIdx++)
    {
        if ((s_GpioSdbyPinMap[ucGpioIdx][0] == ucPinIdx) || (s_GpioSdbyPinMap[ucGpioIdx][1] == ucPinIdx))
        {
            return ucGpioIdx;
        }
    }

    return 0xff;
}

/**
 * @brief initialize pinshare.
 */
void Hv_PM51_Pinshare_Init(void)
{
    UCHAR8 ucArrayNum = 0;
    UCHAR8 ucLoop = 0;
	  GpioEn ucGpioNum = 0;
	  GpioDirEn ucGpioDir = GPIO_INPUT;
	  GpioLevelEn ucGpioLevel = GPIO_LEVEL_HIGH;

    /*Gpio Default Config*/
    ucArrayNum = sizeof (GpioConfig) / sizeof (GpioConfig[0]);
    for (ucLoop = 0; ucLoop < ucArrayNum; ucLoop++)
    {
		ucGpioNum = StbyPinMapIndex(GpioConfig[ucLoop][0]);
		if (0xff == ucGpioNum)
		{
			continue;
		}
		ucGpioDir = GpioConfig[ucLoop][1]?GPIO_OUTPUT:GPIO_INPUT;
		ucGpioLevel = (GpioLevelEn)GpioConfig[ucLoop][2]?GPIO_LEVEL_HIGH:GPIO_LEVEL_LOW;
        Hv_PM51_Gpio_SetOutputLevel(ucGpioNum,ucGpioLevel);
        Hv_PM51_Gpio_SetIODirection(ucGpioNum, ucGpioDir);
    }

    /*Pinshare Config*/
    ucArrayNum = sizeof (PinshareArray) / sizeof (PinshareArray[0]);

    for (ucLoop = 0; ucLoop < ucArrayNum; ucLoop++)
    {
        Hv_PM51_Reg_WriteMask(PinshareArray[ucLoop][0], PinshareArray[ucLoop][1], PinshareArray[ucLoop][2], PinshareArray[ucLoop][3]);
    }

    return;
}