/**
 *file    sys_gpio.c
 *brief   
 * 
 *par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 *author  James
 *date    2018-03-20
 *version 
 * 
 *history 
 *  Date        Note
 *  2018-03-20  Original Creation
 * 
 */

#include "drivers.h"
#include "libc.h"
#include "sys_gpio.h"
#include "sys_pd_hook.h"

/** GPIO definitions for function 
 *  引脚  名称              描述                                      有效电平
 *  GPIO0   VCONN1_EN       VCONN1输出使能                              1     
 *  GPIO1   VCONN2_EN       VCONN2输出使能                              1
 *  GPIO2   NA         
 *  GPIO3   MUX_SEL1         MUX1 DP LENE 选择
 *  GPIO4   MUX_XSD1         MUX1 使能管脚                              0     
 *  GPIO5   HPD_OUT_3506     HPD 信号输出，表示有DP设备连接，然后才开始进行DP部分的协商，DP协商完成再打开DP_S1/DP_S2
 *  GPIO6   MUX_SEL2         MUX2 DP LENE 选择
 *  GPIO7   QC_DM0           c1 QC，FCP等功能管脚DM/UART0_TX   
 *  GPIO8   QC_DP0           c1 QC，FCP等功能管脚DP/UART0_RX   
 *  GPIO9   I2C0_SCL         控制8014
 *  GPIO10  I2C0_SDA         控制8014
 *  GPIO12  DP_S2            SBU控制                 
 *  GPIO13  DP_S1            SBU控制                             
 *  GPIO14  MUX_XSD2         MUX2 使能管脚   
 *  GPIO15  USB_SW           USB2.0 EN                                  1
 *  GPIO16  SBUon            SBU开关                                    1
 *  GPIO17  SBUsw            SBU切换,根据CC方向确认切换方向          
 *  GPIO18  I2C1_SCL         通信接口时钟，连子卡
 *  GPIO19  I2C1_SDA         通信接口数据，连子卡   
 *  GPIO20  INT              子卡到主机的中断                 
 *  GPIO21  SC8014_PSTOP     8014升压降压控制                           0                             
 *  GPIO22  SC8014_EN        8014 使能                                  1                          
 *  GPIO28  LED              电源指示灯                                 1                           
 *  GPIO30  USBC_ON          C口输出控制                                1                                             
 *  CSN/CSP                     
 */
/*
 *  SC8014            
 *  引脚        名称            描述    
 *  
 */


void sys_gpio_init()
{
    // clean default pull-down PINs
    DRV_REG_SET(GPIO_PD_REG, 0);
#if  0
    // POWER ON PIN, high effective
    //drv_gpio_val_set(SYS_IO_POWER_ON,0);
    //drv_gpio_oe_set(SYS_IO_POWER_ON,1);
    //drv_gpio_en_set(SYS_IO_POWER_ON,1);
#endif
    drv_gpio_val_set(SYS_IO_CHIP_EN,1);
    drv_gpio_oe_set(SYS_IO_CHIP_EN,1);
    drv_gpio_en_set(SYS_IO_CHIP_EN,1);
    // PSTOP PIN, high effective
    drv_gpio_val_set(SYS_IO_PSTOP_EN,0);
    drv_gpio_oe_set(SYS_IO_PSTOP_EN,1);
    drv_gpio_en_set(SYS_IO_PSTOP_EN,1);

    // USBC ON PIN, high effective
    drv_gpio_val_set(SYS_IO_USBC_ON,0);
    drv_gpio_oe_set(SYS_IO_USBC_ON,1);
    drv_gpio_en_set(SYS_IO_USBC_ON,1);

    // USBC ON PIN, high effective
    drv_gpio_val_set(SYS_IO_POWER_LED,0);
    drv_gpio_oe_set(SYS_IO_POWER_LED,1);
    drv_gpio_en_set(SYS_IO_POWER_LED,1);
#if 0
    //sc8701 sta indicate
    drv_gpio_oe_set(SYS_IO_DCDC_STAT_DET,0);
    drv_gpio_en_set(SYS_IO_DCDC_STAT_DET,1);
#endif
    //hpd signal output
    drv_gpio_oe_set(SYS_IO_HPD_OUT,0);
    drv_gpio_en_set(SYS_IO_HPD_OUT,1);

    // KEY: input
    drv_gpio_oe_set(SYS_IO_HPD_OUT,0);
    drv_gpio_en_set(SYS_IO_HPD_OUT,1);
    // 初始化：抓沿
    drv_gpio_intr_type_set(SYS_IO_HPD_OUT, 1);
    // 设置下降沿
    drv_gpio_intr_polar_set(SYS_IO_HPD_OUT, 0);
    // 设置 GPIO 中断回调函数
    //drv_gpio_intr_handler_set(SYS_IO_HPD_OUT, sys_gpio_key_isr);
    drv_gpio_intr_mask_set(SYS_IO_HPD_OUT, FALSE);
    // 使能 GPIO0 中断
    drv_gpio_intr_en_set(SYS_IO_HPD_OUT, FALSE);
    
    //sbu on ctr 
    drv_gpio_val_set(SYS_IO_SBU_ON,1);
    drv_gpio_oe_set(SYS_IO_SBU_ON,1);
    drv_gpio_en_set(SYS_IO_SBU_ON,1);
    //sbu switch ctr
    drv_gpio_val_set(SYS_IO_SBU_SW,0);
    drv_gpio_oe_set(SYS_IO_SBU_SW,1);
    drv_gpio_en_set(SYS_IO_SBU_SW,1);

    //dp s2
    drv_gpio_val_set(SYS_IO_DP_S2,1);
    drv_gpio_oe_set(SYS_IO_DP_S2,1);
    drv_gpio_en_set(SYS_IO_DP_S2,1);

    //dp s1
    drv_gpio_val_set(SYS_IO_DP_S1,0);
    drv_gpio_oe_set(SYS_IO_DP_S1,1);
    drv_gpio_en_set(SYS_IO_DP_S1,1);
    
    //mux sel1 
    drv_gpio_val_set(SYS_IO_MUX_SEL1,0);
    drv_gpio_oe_set(SYS_IO_MUX_SEL1,1);
    drv_gpio_en_set(SYS_IO_MUX_SEL1,1);

    //mux sel2
    drv_gpio_val_set(SYS_IO_MUX_SEL2,0);
    drv_gpio_oe_set(SYS_IO_MUX_SEL2,1);
    drv_gpio_en_set(SYS_IO_MUX_SEL2,1);

    //mux xsd1
    drv_gpio_val_set(SYS_IO_MUX_XSD1,1);
    drv_gpio_oe_set(SYS_IO_MUX_XSD1,1);
    drv_gpio_en_set(SYS_IO_MUX_XSD1,1);

    //mux xsd2
    drv_gpio_val_set(SYS_IO_MUX_XSD2,1);
    drv_gpio_oe_set(SYS_IO_MUX_XSD2,1);
    drv_gpio_en_set(SYS_IO_MUX_XSD2,1);

  
    //zika int
    drv_gpio_oe_set(SYS_IO_INT,0);
    drv_gpio_en_set(SYS_IO_INT,1);

#if SYS_VCONN_ENABLED
    // VCONN1 EN PIN, high effective
    drv_gpio_val_set(SYS_IO_VCONN1_EN,0);
    drv_gpio_oe_set(SYS_IO_VCONN1_EN,1);
    drv_gpio_en_set(SYS_IO_VCONN1_EN,1);

    // VCONN2 EN PIN, high effective
    drv_gpio_val_set(SYS_IO_VCONN2_EN,0);
    drv_gpio_oe_set(SYS_IO_VCONN2_EN,1);
    drv_gpio_en_set(SYS_IO_VCONN2_EN,1);
#endif /* SYS_VCONN_ENABLED */

#if ((SYS_LED_ENABLED)&&(SYS_LED_C1_CTR))

    // LED1 PIN
    drv_gpio_val_set(SYS_IO_LED1,SYS_LED_IO_LOW_EFFECTIVE);
    drv_gpio_oe_set(SYS_IO_LED1,1);
    drv_gpio_en_set(SYS_IO_LED1,1);
    // LED2 PIN
    drv_gpio_val_set(SYS_IO_LED2,SYS_LED_IO_LOW_EFFECTIVE);
    drv_gpio_oe_set(SYS_IO_LED2,1);
    drv_gpio_en_set(SYS_IO_LED2,1);
    // LED3 PIN
    drv_gpio_val_set(SYS_IO_LED3,SYS_LED_IO_LOW_EFFECTIVE);
    drv_gpio_oe_set(SYS_IO_LED3,1);
    drv_gpio_en_set(SYS_IO_LED3,1);
    // LED4 PIN
    drv_gpio_val_set(SYS_IO_LED4,SYS_LED_IO_LOW_EFFECTIVE);
    drv_gpio_oe_set(SYS_IO_LED4,1);
    drv_gpio_en_set(SYS_IO_LED4,1);
#if (5==SYS_LED_NUM)
    // LED5 PIN
    drv_gpio_val_set(SYS_IO_LED5,SYS_LED_IO_LOW_EFFECTIVE);
    drv_gpio_oe_set(SYS_IO_LED5,1);
    drv_gpio_en_set(SYS_IO_LED5,1);
#endif    
#if 0  /* deleted by James Gan - 2020-04-16 */
    // PD/QC LED PIN
    drv_gpio_val_set(SYS_IO_QC_PD_LED,SYS_LED_IO_LOW_EFFECTIVE);
    drv_gpio_oe_set(SYS_IO_QC_PD_LED,1);
    drv_gpio_en_set(SYS_IO_QC_PD_LED,1);
#endif /* #if 0 */

#endif

#if SYS_HUB_ENABLED
    // HUB CTL PIN, high effective
    drv_gpio_val_set(SYS_IO_HUB_ON,0);
    drv_gpio_oe_set(SYS_IO_HUB_ON,1);
    drv_gpio_en_set(SYS_IO_HUB_ON,1);

#if SYS_HUB_LED_ENABLED
    // HUB LED PIN, high effective
    drv_gpio_val_set(SYS_IO_HUB_LED,SYS_LED_IO_LOW_EFFECTIVE);
    drv_gpio_oe_set(SYS_IO_HUB_LED,1);
    drv_gpio_en_set(SYS_IO_HUB_LED,1);
#endif /* SYS_HUB_LED_ENABLED */
#endif /* SYS_HUB_ENABLED */

#if 0//SYS_POWER_BANK_ENABLED
    // Power check, low effective, need to pull-up
    drv_gpio_pu_set(SYS_IO_POWER_CHECK,1);
    drv_gpio_oe_set(SYS_IO_POWER_CHECK,0);
    drv_gpio_en_set(SYS_IO_POWER_CHECK,1);
#endif

#if SYS_USBA_ENABLED
    // USBA DC CHIP EN PIN, high effective
    drv_gpio_val_set(SYS_IO_USBA_DC_EN,0);
    drv_gpio_oe_set(SYS_IO_USBA_DC_EN,1);
    drv_gpio_en_set(SYS_IO_USBA_DC_EN,1);

    // USBA QC ON PIN, high effective
    drv_gpio_val_set(SYS_IO_USBA_QC_ON,0);
    drv_gpio_oe_set(SYS_IO_USBA_QC_ON,1);
    drv_gpio_en_set(SYS_IO_USBA_QC_ON,1);

    // USBA1 POWER ON PIN, high effective
    drv_gpio_val_set(SYS_IO_USB_A1_ON,0);
    drv_gpio_oe_set(SYS_IO_USB_A1_ON,1);
    drv_gpio_en_set(SYS_IO_USB_A1_ON,1);

    // USBA2 POWER ON PIN, high effective
    //drv_gpio_val_set(SYS_IO_USB_A2_ON,0);
    //drv_gpio_oe_set(SYS_IO_USB_A2_ON,1);
    //drv_gpio_en_set(SYS_IO_USB_A2_ON,1);

    // USBA1 VBUS ADC PIN, input
    drv_gpio_val_set(SYS_IO_USB_A1_VBUS_ADC_ID,1);
    drv_gpio_oe_set(SYS_IO_USB_A1_VBUS_ADC_ID,1);
    drv_gpio_en_set(SYS_IO_USB_A1_VBUS_ADC_ID,1);

    // USBA2 VBUS ADC PIN, input
   // drv_gpio_val_set(SYS_IO_USB_A2_VBUS_ADC_ID,1);
   // drv_gpio_oe_set(SYS_IO_USB_A2_VBUS_ADC_ID,1);
    //drv_gpio_en_set(SYS_IO_USB_A2_VBUS_ADC_ID,1);
    
#endif

#if 0
    // Enable UART1
    drv_gpio_en_set(SYS_IO_UART1_TX,0);
    drv_gpio_en_set(SYS_IO_UART1_RX,0);
    //uart int
    drv_gpio_oe_set(SYS_IO_UART1_INT,0);
    drv_gpio_en_set(SYS_IO_UART1_INT,1);
#endif
    
    drv_chip_dp0_500kohm_pull_down_set(TRUE);
    //drv_chip_dp1_500kohm_pull_down_set(TRUE);
}

void sys_gpio_uart0_enable_set(bool_t en)
{
    bool_t old = drv_gpio_en_get(UART_RXD) ? FALSE : TRUE;
    if (old != en)
    {
        if (en)
        {
            drv_gpio_en_set(UART_TXD,FALSE);
            drv_gpio_pd_set(UART_TXD,FALSE);
            drv_gpio_pu_set(UART_TXD,FALSE);

            drv_gpio_en_set(UART_RXD,FALSE);
            drv_gpio_pd_set(UART_RXD,FALSE);
            drv_gpio_pu_set(UART_RXD,FALSE);

#if SYS_QUICK_CHARGE_ENABLED
            if (!usbpd_cfg_port_quick_charge_en_get())
            {
                drv_chip_dp0_dm0_short_set(FALSE);
                drv_chip_dp0_20kohm_pull_down_set(FALSE);
            }
#else
            drv_chip_dp0_dm0_short_set(FALSE);
            drv_chip_dp0_20kohm_pull_down_set(FALSE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
        }
        else {
            drv_gpio_en_set(UART_TXD,TRUE);
            drv_gpio_oe_set(UART_TXD,FALSE);

            drv_gpio_en_set(UART_RXD,TRUE);
            drv_gpio_oe_set(UART_RXD,FALSE);

#if SYS_QUICK_CHARGE_ENABLED
            if (!usbpd_cfg_port_quick_charge_en_get())
            {
                drv_chip_dp0_dm0_short_set(TRUE);
                drv_chip_dp0_20kohm_pull_down_set(TRUE);
            }
#else
            drv_chip_dp0_dm0_short_set(TRUE);
            drv_chip_dp0_20kohm_pull_down_set(TRUE);
#endif /* SYS_QUICK_CHARGE_ENABLED */
        }
    }
}

void sys_gpio_uart1_enable_set(bool_t en)
{
    bool_t old = drv_gpio_en_get(SEC_UART_RXD) ? FALSE : TRUE;
    if (old != en)
    {
        if (en)
        {
            drv_gpio_en_set(SEC_UART_TXD,FALSE);
            drv_gpio_pd_set(SEC_UART_TXD,FALSE);
            drv_gpio_pu_set(SEC_UART_TXD,FALSE);

            drv_gpio_en_set(SEC_UART_RXD,FALSE);
            drv_gpio_pd_set(SEC_UART_RXD,FALSE);
            drv_gpio_pu_set(SEC_UART_RXD,FALSE);
        }
        else {
            drv_gpio_en_set(SEC_UART_TXD,TRUE);
            drv_gpio_oe_set(SEC_UART_TXD,FALSE);

            drv_gpio_en_set(SEC_UART_RXD,TRUE);
            drv_gpio_oe_set(SEC_UART_RXD,FALSE);
        }
    }
}

#if ((SYS_LED_ENABLED)&&(!SYS_SMG_DISPLAY_ENABLED)&&(SYS_LED_C1_CTR))

// IO map for battery capacity LEDs
#if (5==SYS_LED_NUM)
const u8_t bat_cap_led_iomap[SYS_LED_NUM] = {SYS_IO_LED1,SYS_IO_LED2,SYS_IO_LED3,SYS_IO_LED4,SYS_IO_LED5};
#else
const u8_t bat_cap_led_iomap[SYS_LED_NUM] = {SYS_IO_LED1,SYS_IO_LED2,SYS_IO_LED3,SYS_IO_LED4};
#endif
void sys_gpio_bat_cap_led_control(u32_t bitmap)
{
#if 1  /* modified by James Gan - 2019-07-09, for out of sequence */
    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_BAT_CAP_LED_1))
    {
        drv_gpio_val_set(bat_cap_led_iomap[SYS_GPIO_BAT_CAP_LED_1],SYS_LED_IO_HIGH_EFFECTIVE);
    }
    else {
        drv_gpio_val_set(bat_cap_led_iomap[SYS_GPIO_BAT_CAP_LED_1],SYS_LED_IO_LOW_EFFECTIVE);
    }

    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_BAT_CAP_LED_2))
    {
        drv_gpio_val_set(bat_cap_led_iomap[SYS_GPIO_BAT_CAP_LED_2],SYS_LED_IO_HIGH_EFFECTIVE);
    }
    else {
        drv_gpio_val_set(bat_cap_led_iomap[SYS_GPIO_BAT_CAP_LED_2],SYS_LED_IO_LOW_EFFECTIVE);
    }

    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_BAT_CAP_LED_3))
    {
        drv_gpio_val_set(bat_cap_led_iomap[SYS_GPIO_BAT_CAP_LED_3],SYS_LED_IO_HIGH_EFFECTIVE);
    }
    else {
        drv_gpio_val_set(bat_cap_led_iomap[SYS_GPIO_BAT_CAP_LED_3],SYS_LED_IO_LOW_EFFECTIVE);
    }

    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_BAT_CAP_LED_4))
    {
        drv_gpio_val_set(bat_cap_led_iomap[SYS_GPIO_BAT_CAP_LED_4],SYS_LED_IO_HIGH_EFFECTIVE);
    }
    else {
        drv_gpio_val_set(bat_cap_led_iomap[SYS_GPIO_BAT_CAP_LED_4],SYS_LED_IO_LOW_EFFECTIVE);
    }

#if (5==SYS_LED_NUM)
    if (SAL_IS_BIT_SET(bitmap,SYS_GPIO_BAT_CAP_LED_5))
    {
        drv_gpio_val_set(bat_cap_led_iomap[SYS_GPIO_BAT_CAP_LED_5],SYS_LED_IO_HIGH_EFFECTIVE);
    }
    else {
        drv_gpio_val_set(bat_cap_led_iomap[SYS_GPIO_BAT_CAP_LED_5],SYS_LED_IO_LOW_EFFECTIVE);
    }
#endif /* (5==SYS_LED_NUM) */
#else
    
#endif /* #if 1 */
}


#endif




void sys_gpio_uart0_disable(void)
{
    if((dpm_vbus_volt_get() > 2500U)&&
       (drv_flash_firmware_is_unbroken()))
    {
        drv_gpio_en_set(UART_TXD,TRUE);
        drv_gpio_pd_set(UART_TXD,FALSE);
        drv_gpio_oe_set(UART_TXD,FALSE);

        drv_gpio_en_set(UART_RXD,TRUE);
        drv_gpio_pd_set(UART_RXD,FALSE);
        drv_gpio_oe_set(UART_RXD,FALSE);
        drv_chip_dp0_dm0_short_set(TRUE);
        drv_chip_dp0_20kohm_pull_down_set(TRUE);

    }
    
}

void sys_gpio_uart0_enable(void)
{
    drv_gpio_en_set(UART_TXD,FALSE);
    drv_gpio_pd_set(UART_TXD,FALSE);
    drv_gpio_pu_set(UART_TXD,FALSE);

    drv_gpio_en_set(UART_RXD,FALSE);
    drv_gpio_pd_set(UART_RXD,FALSE);
    drv_gpio_pu_set(UART_RXD,FALSE);
    drv_chip_dp0_dm0_short_set(FALSE);
    drv_chip_dp0_20kohm_pull_down_set(FALSE);
}


