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

#ifndef MTK_HDMI_H
#define MTK_HDMI_H

#include "drv_hdmi2.h"
#include "drvcust_if.h"
#ifdef CC_HDMI_POH_SUPPORT
static HDMI_POH_CONFIG_T _arPOHConfig[HDMI_SWITCH_MAX - 1] =
{
    //Driver Port ID,        Enable      pwr_en_gpio           poh_det_gpio      ocp_det_gpio
    {HDMI_SWITCH_1,    FALSE,       0,           0,            0},
    {HDMI_SWITCH_2,    TRUE,        214,         215,          235},
    {HDMI_SWITCH_3,    FALSE,       0,           0,            0},
    {HDMI_SWITCH_4,    FALSE,       0,           0,            0},
};
#endif

static HDMI_PORT_INFO_T _arHDMIPortInfo[HDMI_SWITCH_MAX - 1] = {
// UI PortID,      Driver Port ID,        Enable      CEC Support         ARC Support
    {1,     HDMI_SWITCH_1,      TRUE,       TRUE,           TRUE},
    {2,     HDMI_SWITCH_2,      TRUE,       TRUE,           FALSE},
    {3,     HDMI_SWITCH_3,      TRUE,       TRUE,           FALSE},
    {4,     HDMI_SWITCH_4,      TRUE,       TRUE,           FALSE},
};

#ifdef CC_HDMI_POH_SUPPORT
//-----------------------------------------------------------------------------
/*Reserve for run-time POH config
*/
//-----------------------------------------------------------------------------
void vHDMIPohConfigInit(void)
{
    return;
}

BOOL fgHDMIPohEnabled(E_HDMI_SWITCH_NUM ePort)
{
    if(ePort > HDMI_SWITCH_4)
    {
        return FALSE;
    }
    return _arPOHConfig[ePort-1].fgEnable;
}

void vHDMIGetPohConfig(E_HDMI_SWITCH_NUM ePort,HDMI_POH_CONFIG_T *prPohConfig)
{
    if((ePort > HDMI_SWITCH_4) || (NULL == prPohConfig))
    {
        return;
    }
    x_memcpy(prPohConfig,&_arPOHConfig[ePort-1],sizeof(HDMI_POH_CONFIG_T));
}
#endif

//====================//
//-----------------------------------------------------------------------------
/** vHDMIPortInfoInit
 *  descritpion:use this function to customize HDMI port info, You can change the _arHDMIPortInfo in this function.
 *  This function will be called when HDMI EDID init.
 *  @param  void
 *  @retval  void
 */
//-----------------------------------------------------------------------------
void vHDMIPortInfoInit(void)
{
    UINT8 u1Tmp, u1Count;
    UINT32 u4Port = 0;
    for(u1Count = 0; u1Count < (HDMI_SWITCH_MAX - 1); u1Count++)
    {
        if(EEPROM_Read((UINT64)(HDMIEEPROM_PORTINFO_OFFSET + u1Count), (UPTR)(&u4Port), 0x1))
        {
            Printf("[HDMI]Port Info Init fail!\n");
            break;
        }
        u1Tmp = u4Port&0x7;
        if((u1Tmp < HDMI_SWITCH_MAX)&&(u1Tmp > 0))
        {
            _arHDMIPortInfo[u1Tmp-1].u1DriverPortId = u1Count+1;
            if(u4Port&0x80)
            {
                _arHDMIPortInfo[u1Tmp-1].bARCSupport = TRUE;
            }
            else
            {
                _arHDMIPortInfo[u1Tmp-1].bARCSupport = FALSE;
            }
        }
        else
        {
            Printf("[HDMI]Port Info error!\n");
            break;
        }
    }
    return;

}

void vHDMIGetPortsInfo(HDMI_PORTS_INFO_T* prPortsInfo)
{
    UINT8 u1HDMIPortNum, u1Count;
    if(prPortsInfo == NULL)
    {
        return;
    }

    x_memcpy(&prPortsInfo->rHdmiPortInfo[0], _arHDMIPortInfo, sizeof(HDMI_PORT_INFO_T) * (HDMI_SWITCH_MAX - 1));

    //calculate hdmi port number
    u1HDMIPortNum = 0;
    for(u1Count = 0; u1Count < (HDMI_SWITCH_MAX - 1); u1Count++)
    {
        if(_arHDMIPortInfo[u1Count].bEnable == TRUE)
        {
            u1HDMIPortNum++;
        }
    }
    prPortsInfo->u1PortNum = u1HDMIPortNum;
}

E_HDMI_SWITCH_NUM eHDMIGetPhysicalPortId(E_HDMI_SWITCH_NUM eVirPort)
{
    UINT8 u1Index;

    if(eVirPort >= HDMI_SWITCH_MAX)
    {
        return HDMI_SWITCH_1;
    }
    if(eVirPort == HDMI_SWITCH_INIT)
    {
        return HDMI_SWITCH_1;
    }

    u1Index = eVirPort - HDMI_SWITCH_1;
    if(_arHDMIPortInfo[u1Index].bEnable == TRUE)
    {
        return (E_HDMI_SWITCH_NUM)_arHDMIPortInfo[u1Index].u1DriverPortId;
    }

    return HDMI_SWITCH_INIT;
}

E_HDMI_SWITCH_NUM eHDMIGetVirtualPortId(E_HDMI_SWITCH_NUM ePhyPort)
{
    UINT8 u1Index;

    if(ePhyPort >= HDMI_SWITCH_MAX)
    {
        return HDMI_SWITCH_INIT;
    }

    for(u1Index=HDMI_SWITCH_1; u1Index<HDMI_SWITCH_MAX; u1Index++)
    {
        if((E_HDMI_SWITCH_NUM)_arHDMIPortInfo[u1Index - HDMI_SWITCH_1].u1DriverPortId == ePhyPort)
        {
            break;
        }
    }

    if(u1Index < HDMI_SWITCH_MAX)
    {
        return (E_HDMI_SWITCH_NUM)u1Index;
    }

    return HDMI_SWITCH_1;
}

#endif /* MTK_AUD_H */

