/* 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.
 *
 *****************************************************************************/


//----------------------------------------------------------------------------
// Check direct compile this file
//----------------------------------------------------------------------------
#ifndef NO_IMP
#define NO_IMP
#include "drvcust_lib.c"
#define IMP_HDMI_CONF_C
#endif  /* NO_IMP */
#include "macro_helper.h"

/**
 * @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)

//----------------------------------------------------------------------------
// Check direct compile this file
//----------------------------------------------------------------------------
#ifdef IMP_HDMI_CONF_C
#undef NO_IMP
#include "macro_helper.h"
#endif  /* IMP_HDMI_CONF_C */
//No more #include after this point!!

extern E_HDMI_SWITCH_NUM eActiveHdmiPort[2];
//====================//
FUN_MACRO(void vHDMIHPDHigh(E_HDMI_SWITCH_NUM eSwitch))
#ifdef IMP_HDMI_CONF_C
{
    vHDMI2SetHpdPulse(eSwitch, 1);

    switch(eSwitch)
    {
#ifdef HDMI_GPIO_HPD0
        case HDMI_SWITCH_1:
            if(!fgMHL3GetMhlCableStatus())
            {
                GPIO_GetIn(HDMI_GPIO_HPD0);
            }
            break;
#endif
#ifdef HDMI_GPIO_HPD1
        case HDMI_SWITCH_2:
            GPIO_GetIn(HDMI_GPIO_HPD1);
            break;
#endif
#ifdef HDMI_GPIO_HPD2
        case HDMI_SWITCH_3:
            GPIO_GetIn(HDMI_GPIO_HPD2);
            break;
#endif
#ifdef HDMI_GPIO_HPD3
        case HDMI_SWITCH_4:
            GPIO_GetIn(HDMI_GPIO_HPD3);
            break;
#endif
        default: /* disable all */
            break;
    }
}
#endif  /* IMP_HDMI_CONF_C */

//====================//
FUN_MACRO(void vHDMIHPDLow(E_HDMI_SWITCH_NUM eSwitch))
#ifdef IMP_HDMI_CONF_C
{
    vHDMI2SetHpdPulse(eSwitch, 0);

    switch(eSwitch)
    {
#ifdef HDMI_GPIO_HPD0
        case HDMI_SWITCH_1:
            if(!fgMHL3GetMhlCableStatus())
            {
                GPIO_SetOut(HDMI_GPIO_HPD0, 0);
            }
            break;
#endif
#ifdef HDMI_GPIO_HPD1
        case HDMI_SWITCH_2:
            GPIO_SetOut(HDMI_GPIO_HPD1, 0);
            break;
#endif
#ifdef HDMI_GPIO_HPD2
        case HDMI_SWITCH_3:
             GPIO_SetOut(HDMI_GPIO_HPD2, 0);
            break;
#endif
#ifdef HDMI_GPIO_HPD3
        case HDMI_SWITCH_4:
             GPIO_SetOut(HDMI_GPIO_HPD3, 0);
            break;
#endif
        default: /* disable all */
            break;
    }
}
#endif  /* IMP_HDMI_CONF_C */

//====================//
FUN_MACRO(UINT8 bHDMIPort5VStatus(E_HDMI_SWITCH_NUM ePort))
#ifdef IMP_HDMI_CONF_C
{
    UINT32 input = 0;

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

    switch(ePort)
    {
#ifdef HDMI_GPIO_PWR0
        case HDMI_SWITCH_1:
            if(fgMHL3GetMhlCableStatus())
            {
                input = 1;
            }
            else
            {
                input = GPIO_GetIn(HDMI_GPIO_PWR0);
            }
            break;
#endif
#ifdef HDMI_GPIO_PWR1
        case HDMI_SWITCH_2:
              input = GPIO_GetIn(HDMI_GPIO_PWR1);
             break;
#endif
#ifdef HDMI_GPIO_PWR2
        case HDMI_SWITCH_3:
              input = GPIO_GetIn(HDMI_GPIO_PWR2);
             break;
#endif
#ifdef HDMI_GPIO_PWR3
        case HDMI_SWITCH_4:
            input = GPIO_GetIn(HDMI_GPIO_PWR3);
            break;
#endif
      default:
             break;
    }

    return input;
}
#endif  /* IMP_HDMI_CONF_C */

//====================//
FUN_MACRO(void vHDMISwitchInit(void))
#ifdef IMP_HDMI_CONF_C
{
}
#endif  /* IMP_HDMI_CONF_C */

//====================//
FUN_MACRO(void vHDMISetSwitch(E_HDMI_SWITCH_NUM eSwitch,UINT8 u1Type))
#ifdef IMP_HDMI_CONF_C
{
    E_HDMI_SWITCH_NUM eHdmiRx;
    UINT8 u1PwOnInit = 0;

    // port mapping here
    eHdmiRx = eHDMIGetPhysicalPortId(eSwitch);

    if (eActiveHdmiPort[u1Type] == HDMI_SWITCH_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);
        }
    }
}
#endif  /* IMP_HDMI_CONF_C */

FUN_MACRO(void vHDMISetARCSwitch(UINT8 u1Port))
#ifdef IMP_HDMI_CONF_C
{
    return;
}
#endif  /* IMP_HDMI_CONF_C */
