/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/


/**
 * @file HDMI customization file:
 *
 * @author josh.pan@mediatek.com
 */
#include "x_gpio.h"
#include "x_printf.h"

#include "hw_vdoin.h"
#include "hw_pdwnc.h"
#include "drv_mhl.h"
#include "drv_hdmi2.h"
#include "drv_video.h"
#include "drv_adcset.h"

#include "sv_const.h"
#include "source_table.h"


#define HDMI_GPIO_HPD0 (253)
#define HDMI_GPIO_HPD1 (265)
#define HDMI_GPIO_HPD2 (225)
#define HDMI_GPIO_HPD3 (229)

#define HDMI_GPIO_PWR0 (252)
#define HDMI_GPIO_PWR1 (262)
#define HDMI_GPIO_PWR2 (226)
#define HDMI_GPIO_PWR3 (259)

extern HdmiRxPort eActiveHdmiPort[2];
//====================//
void vHDMIHPDHigh(HdmiRxPort eSwitch)
{
    vHDMI2SetHpdPulse(eSwitch, 1);

    switch(eSwitch)
    {
#ifdef HDMI_GPIO_HPD0
        case HDMI_RX_PORT_1:
            if(!fgMHL3GetMhlCableStatus())
            {
                GPIO_GetIn(HDMI_GPIO_HPD0);
            }
            break;
#endif
#ifdef HDMI_GPIO_HPD1
        case HDMI_RX_PORT_2:
            GPIO_SetOut(HDMI_GPIO_HPD1,0);
            break;
#endif
#ifdef HDMI_GPIO_HPD2
        case HDMI_RX_PORT_3:
            GPIO_SetOut(HDMI_GPIO_HPD2,0);
            break;
#endif
#ifdef HDMI_GPIO_HPD3
        case HDMI_RX_PORT_4:
            GPIO_SetOut(HDMI_GPIO_HPD3,0);
            break;
#endif
        default: /* disable all */
            break;
    }
}

//====================//
void vHDMIHPDLow(HdmiRxPort eSwitch)
{
    INT32 i4Val = 1;
    vHDMI2SetHpdPulse(eSwitch, 0);

    switch(eSwitch)
    {
#ifdef HDMI_GPIO_HPD0
        case HDMI_RX_PORT_1:
            if(!fgMHL3GetMhlCableStatus())
            {
                GPIO_SetOut(HDMI_GPIO_HPD0, 0);
            }
            break;
#endif
#ifdef HDMI_GPIO_HPD1
        case HDMI_RX_PORT_2:
            GPIO_SetOut(HDMI_GPIO_HPD1, i4Val);
            break;
#endif
#ifdef HDMI_GPIO_HPD2
        case HDMI_RX_PORT_3:
            GPIO_SetOut(HDMI_GPIO_HPD2, i4Val);
            break;
#endif
#ifdef HDMI_GPIO_HPD3
        case HDMI_RX_PORT_4:
            GPIO_SetOut(HDMI_GPIO_HPD3, i4Val);
            break;
#endif
        default: /* disable all */
            break;
    }
}

//====================//
UINT8 bHDMIPort5VStatus(HdmiRxPort ePort)
{
    UINT32 input = 0;

    if (u1HDMI2IsHpdPulse(ePort) == 1)
    {
        // hpd pulse period
        return (input);
    }

    switch(ePort)
    {
#ifdef HDMI_GPIO_HPD0
        case HDMI_RX_PORT_1:
            if(fgMHL3GetMhlCableStatus())
            {
                input = 1;
            }
            else
            {
                input = GPIO_GetIn(HDMI_GPIO_PWR0);
            }
            break;
#endif
#ifdef HDMI_GPIO_HPD1
        case HDMI_RX_PORT_2:
             input = GPIO_GetIn(HDMI_GPIO_PWR1);
             break;
#endif
#ifdef HDMI_GPIO_HPD2
        case HDMI_RX_PORT_3:
             input = GPIO_GetIn(HDMI_GPIO_PWR2);
             break;
#endif
#ifdef HDMI_GPIO_HPD3
        case HDMI_RX_PORT_4:
             input = GPIO_GetIn(HDMI_GPIO_PWR3);
             break;
#endif
      default:
             break;
    }

    return input;
}
//====================//
void vHDMISwitchInit(void)
{
}

//====================//
void vHDMISetSwitch(HdmiRxPort eSwitch,UINT8 u1Type)
{
    HdmiRxPort eHdmiRx;
    UINT8 u1PwOnInit = 0;

    // port mapping here
#ifdef CC_HDMI_PORTID_PHY_VIR_MAPPING
    eHdmiRx = eHDMIGetPhysicalPortId(eSwitch);
#else
    eHdmiRx = eSwitch;
#endif

    if (eActiveHdmiPort[u1Type] == HDMI_RX_PORT_Init)
	{
		u1PwOnInit = 1;
	}

    if ((eHDMICurrSwitch != eHdmiRx) || (eActiveHdmiPort[u1Type] != eHdmiRx))
    {
        eHDMICurrSwitch = eHdmiRx;
        eActiveHdmiPort[u1Type] = eHdmiRx;

        if (u1IsHDMI2Stable(eActiveHdmiPort[u1Type])) //xiongfeng modify for cbus disconnect when change source to MHL
        {
            vSetHdmi2FastSw(eActiveHdmiPort[u1Type], 1);
        }
        else
        {
            vSetHdmi2FastSw(eActiveHdmiPort[u1Type], 0);
        }

        vHDMI2PortSel(eActiveHdmiPort[u1Type],u1Type);
        vHDMI2PllSel(eActiveHdmiPort[u1Type],u1Type);

        if (u1IsHdmi2FastSw(eActiveHdmiPort[u1Type]) == 0)
        {
            if (u1PwOnInit == 0)
            {
                  vHDMI2SetStateMachine(eActiveHdmiPort[u1Type],HDMI_NOSIGNAL_STATE);
            }
        }
        else
        {
            vHDMI2SetStateMachine(eActiveHdmiPort[u1Type],HDMI_WAIT_STABLE_STATE);
        }
    }
}

void vHDMISetARCSwitch(UINT8 u1Port)
{
    return;
}

