/* 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_hdmi.h"
#include "hw_pdwnc.h"

#include "drv_hdmi.h"
#include "drv_video.h"
#include "drv_adcset.h"

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

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

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

extern E_HDMI_SWITCH_NUM eActiveHdmiPort;
//====================//
void vHDMIHPDHigh(E_HDMI_SWITCH_NUM eSwitch)
{ 
	vHdmiSetHpdStatus(eSwitch, 0);
       
	switch(eSwitch)
	{
#ifdef HDMI_GPIO_HPD0
		case HDMI_SWITCH_1:
			if(_bIsMhlDevice == 0)
			{
				GPIO_GetIn(HDMI_GPIO_HPD0);
			}
			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;
	}
}

//====================//
void vHDMIHPDLow(E_HDMI_SWITCH_NUM eSwitch)
{
	INT32 i4Val = 1;
    vHdmiSetHpdStatus(eSwitch, 1);
       
	switch(eSwitch)
	{
#ifdef HDMI_GPIO_HPD0
		case HDMI_SWITCH_1:			
			if(_bIsMhlDevice == 0)
			{
				GPIO_SetOut(HDMI_GPIO_HPD0, 0);
			}
			break;
#endif			
#ifdef HDMI_GPIO_HPD1
		case HDMI_SWITCH_2:	
 			GPIO_SetOut(HDMI_GPIO_HPD1, i4Val);
			break;
#endif			
#ifdef HDMI_GPIO_HPD2
		case HDMI_SWITCH_3:		
 			GPIO_SetOut(HDMI_GPIO_HPD2, i4Val);
			break;
#endif			
#ifdef HDMI_GPIO_HPD3
		case HDMI_SWITCH_4:
 			GPIO_SetOut(HDMI_GPIO_HPD3, i4Val);
			break;
#endif			
		default: /* disable all */
			break;
	}
}

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

    if (u1IsHdmiHpdPulse(ePort) == 1)
    {
        // hpd pulse period
        return (input);
    }
    
    switch(ePort)
    {
#ifdef HDMI_GPIO_HPD0
        case HDMI_SWITCH_1: 
			if(_bIsMhlDevice == 1)
			{
				input = 1;
				_bIsMhlDevice = 1;
			}
			else
			{
				_bIsMhlDevice = 0;
				input = GPIO_GetIn(HDMI_GPIO_PWR0); 				
			}
	        break;
#endif
#ifdef HDMI_GPIO_HPD1
        case HDMI_SWITCH_2: 
	          input = GPIO_GetIn(HDMI_GPIO_PWR1);
	         break;
#endif
#ifdef HDMI_GPIO_HPD2
        case HDMI_SWITCH_3: 
	          input = GPIO_GetIn(HDMI_GPIO_PWR2);
	         break;
#endif
#ifdef HDMI_GPIO_HPD3
        case HDMI_SWITCH_4: 
	          input = GPIO_GetIn(HDMI_GPIO_PWR3);
	         break;
#endif
	  default:
	         break;
	}
    
    return input;
}
//====================//
void vHDMISwitchInit(void)
{    
}

//====================//
void vHDMISetSwitch(E_HDMI_SWITCH_NUM eSwitch)
{
    E_HDMI_SWITCH_NUM i = HDMI_SWITCH_INIT;
    E_HDMI_SWITCH_NUM eHdmiRx;
	UINT8 u1PwOnInit = 0;

      // port mapping here 
      switch(eSwitch)
      {
          case HDMI_SWITCH_1:
                   eHdmiRx = HDMI_SWITCH_1;
  		break;
  				
          case HDMI_SWITCH_2:
                   eHdmiRx = HDMI_SWITCH_2;
  	       break;

          case HDMI_SWITCH_3:
                   eHdmiRx = HDMI_SWITCH_3;
  	       break;

          case HDMI_SWITCH_4:
                   eHdmiRx = HDMI_SWITCH_4;
  	       break;
  	       
          default:
          	      eHdmiRx = eSwitch;
  		break;
      }
	  
    if (eHDMICurrSwitch == HDMI_SWITCH_INIT)       
	{          		
		u1PwOnInit = 1;              
	}	
	if(((eActiveHdmiPort == HDMI_SWITCH_1) && (eHdmiRx != HDMI_SWITCH_1))
		|| ((eActiveHdmiPort != HDMI_SWITCH_1) && (eHdmiRx == HDMI_SWITCH_1)))
	{
		u1FlgHdmiMhlSrcChged = 1;//MHL -> HDMI ->MHL, set to 1
	}
	if (eHDMICurrSwitch != eHdmiRx)
	{	
		eHDMICurrSwitch = eHdmiRx;
              eActiveHdmiPort = eHdmiRx;
		
              if (u1IsHdmiResStable(eActiveHdmiPort) && u1IsHdmiRxShared(eActiveHdmiPort) == 0)
              {
                  vSetHdmiFastSw(eActiveHdmiPort, 1);
              }
		else
		{
		    vSetHdmiFastSw(eActiveHdmiPort, 0);
		    if (u1PwOnInit == 0)
			{
				vHDMIHPDLow(eActiveHdmiPort);
			}

		}
		
              vHDMISel(eHdmiRx);

		// HPD high for unselected ports, support CEC feature.
		for ( i = HDMI_SWITCH_1 ; i <= HDMI_SWITCH_4 ; i++) 
		{
			if (i != eHdmiRx)
			{
				vHDMIHPDHigh(i);
			}
		}
		
		#if MUTE_TEMP
		vHDMIVideoOutOff();
		#endif
		
        if (u1IsHdmiFastSw(eActiveHdmiPort) == 0)
        {
            if (u1PwOnInit == 0)
			{
	      		vSetHdmiState(HDMI_STATE_INIT);
            }

        }
         else
        {
	      vSetHdmiState(HDMI_STATE_SCDT);
        }

	}
}

void vHDMISetARCSwitch(UINT8 u1Port)
{
    return;
}

