/* 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 pinmux.c
 *  pinmux.c contains functions to do pin selection & gpio setup.
 */


//-------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
#include "x_bim.h"
#include "x_pdwnc.h"
#include "x_pinmux.h"
#include "x_printf.h"
#include "x_hal_5381.h"
#include "x_assert.h"
#include "drvcust_if.h"
#include "x_debug.h"

#ifdef DEFINE_IS_LOG
#undef DEFINE_IS_LOG
#endif
#ifdef CC_MTK_LOADER
#define DEFINE_IS_LOG(level, fmt...)   Printf(fmt)
#else /* CC_MTK_LOADER */
#define DEFINE_IS_LOG   IR_IsLog
#endif /* CC_MTK_LOADER */

//-------------------------------------------------------------------
// Configurations
//-------------------------------------------------------------------

//-------------------------------------------------------------------
// Constant definitions
//-------------------------------------------------------------------

//-------------------------------------------------------------------
// Macro definitions
//-----------------------------------------------------------------------------

//-------------------------------------------------------------------
// Static variables
//-----------------------------------------------------------------------------
extern UINT32 HalCriticalStart(void);
extern void HalCriticalEnd(UINT32 u4Flags);

static const UINT32 _au4PinmuxReg[TOTAL_PIN_REG + 1] =
{
    0, // not a pinmux register
    CKGEN_PMUX0,
    CKGEN_PMUX1,
    CKGEN_PMUX2,
    CKGEN_PMUX3,
    CKGEN_PMUX4,
    CKGEN_PMUX5,
    CKGEN_PMUX6,
    CKGEN_PMUX7,
    CKGEN_PMUX8,
    PDWNC_PINMUX0,
    PDWNC_PINMUX1,
    PDWNC_PINMUX2,
    PDWNC_PINMUX3,
    PDWNC_PINMUX4,
};

/* The gpio pin selection information.*/
// DO NOT EDIT
static const UINT32 _aau1GpioSelFunc[TOTAL_NORMAL_GPIO_NUM][2] =
{
    {PIN_GPIO0, PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - GPIO 0
    {PIN_GPIO1, PINMUX_FUNCTION0 },//GPIO 1
    {PIN_GPIO2, PINMUX_FUNCTION0 },//GPIO 2
    {PIN_GPIO3, PINMUX_FUNCTION0 },//GPIO 3
    {PIN_GPIO4, PINMUX_FUNCTION0 },//GPIO 4
    {PIN_GPIO5, PINMUX_FUNCTION0 },//GPIO 5
    {PIN_GPIO6, PINMUX_FUNCTION0 },//GPIO 6
    {PIN_GPIO7, PINMUX_FUNCTION0 },//GPIO 7
    {PIN_GPIO8, PINMUX_FUNCTION0 },//GPIO 8
    {PIN_GPIO9, PINMUX_FUNCTION0 },//GPIO 9
    {PIN_GPIO10,	PINMUX_FUNCTION0 },//GPIO 10
    {PIN_GPIO11,	PINMUX_FUNCTION0 },//GPIO 11
    {PIN_GPIO12,	PINMUX_FUNCTION0 },//GPIO 12
    {PIN_GPIO13,	PINMUX_FUNCTION0 },//GPIO 13
    {PIN_GPIO14,	PINMUX_FUNCTION0 },//GPIO 14
    {PIN_GPIO15,	PINMUX_FUNCTION0 },//GPIO 15
    {PIN_GPIO16,	PINMUX_FUNCTION0 },//GPIO 16
    {PIN_GPIO17,	PINMUX_FUNCTION0 },//GPIO 17
    {PIN_GPIO18,	PINMUX_FUNCTION0 },//GPIO 18
    {PIN_GPIO19,	PINMUX_FUNCTION0 },//GPIO 19
    {PIN_GPIO20,	PINMUX_FUNCTION0 },//GPIO 20
    {PIN_GPIO21,	PINMUX_FUNCTION0 },//GPIO 21
    {PIN_GPIO22,	PINMUX_FUNCTION0 },//GPIO 22
    {PIN_GPIO23,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION6 - GPIO 23
    {PIN_GPIO24,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION6 - GPIO 24
    {PIN_GPIO25,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION4 , PINMUX_FUNCTION6 - GPIO 25
    {PIN_GPIO26,	PINMUX_FUNCTION0 },//GPIO 26
    {PIN_GPIO27,	PINMUX_FUNCTION0 },//GPIO 27
    {PIN_GPIO28,	PINMUX_FUNCTION0 },//GPIO 28
    {PIN_GPIO29,	PINMUX_FUNCTION0 },//GPIO 29
    {PIN_GPIO30,	PINMUX_FUNCTION0 },//GPIO 30
    {PIN_GPIO31,	PINMUX_FUNCTION0 },//GPIO 31
    {PIN_GPIO32,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - GPIO 32
    {PIN_GPIO33,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - GPIO 33
    {PIN_GPIO34,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - GPIO 34
    {PIN_GPIO35,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - GPIO 35
    {PIN_GPIO36,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - GPIO 36
    {PIN_GPIO37,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - GPIO 37
    {PIN_GPIO38,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - GPIO 38
    {PIN_GPIO39,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - GPIO 39
    {PIN_GPIO40,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - GPIO 40
    {PIN_GPIO41,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - GPIO 41
    {PIN_GPIO42,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION5 - GPIO 42
    {PIN_GPIO43,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION5 - GPIO 43
    {PIN_GPIO44,	PINMUX_FUNCTION0 },//GPIO 44
    {PIN_GPIO45,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 , PINMUX_FUNCTION4 - GPIO 45
    {PIN_GPIO46,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 , PINMUX_FUNCTION4 - GPIO 46
    {PIN_GPIO47,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION4 - GPIO 47
    {PIN_GPIO48,	PINMUX_FUNCTION0 },//GPIO 48
    {PIN_GPIO49,	PINMUX_FUNCTION0 },//GPIO 49
    {PIN_GPIO50,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION2 , PINMUX_FUNCTION6 - GPIO 50
    {PIN_GPIO51,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION2 , PINMUX_FUNCTION3 - GPIO 51
    {PIN_GPIO52,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 , PINMUX_FUNCTION5 - GPIO 52
    {PIN_GPIO53,	PINMUX_FUNCTION0 },//GPIO 53
    {PIN_GPIO54,	PINMUX_FUNCTION0 },//GPIO 54
    {PIN_GPIO55,	PINMUX_FUNCTION0 },//GPIO 55
    {PIN_GPIO56,	PINMUX_FUNCTION1 },//GPIO 56
    {PIN_GPIO57,	PINMUX_FUNCTION1 },//GPIO 57
    {PIN_GPIO58,	PINMUX_FUNCTION1 },//GPIO 58
    {PIN_GPIO59,	PINMUX_FUNCTION1 },//PINMUX_FUNCTION3 - GPIO 59
    {PIN_GPIO60,	PINMUX_FUNCTION1 },//PINMUX_FUNCTION3 - GPIO 60
    {PIN_GPIO61,	PINMUX_FUNCTION0 },//GPIO 61
    {PIN_GPIO62,	PINMUX_FUNCTION0 },//GPIO 62
    {PIN_GPIO63,	PINMUX_FUNCTION0 },//GPIO 63
    {PIN_GPIO64,	PINMUX_FUNCTION0 },//GPIO 64
    {PIN_GPIO65, 	PINMUX_FUNCTION0 },//GPIO 65
    {PIN_GPIO66,	PINMUX_FUNCTION0 },//GPIO 66
    {PIN_SD_CMD,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - GPIO 67
    {PIN_SD_CLK,	PINMUX_FUNCTION0 },//GPIO 68
    {PIN_SD_D0, PINMUX_FUNCTION0 },//GPIO 69
    {PIN_SD_D1, PINMUX_FUNCTION0 },//GPIO 70
    {PIN_SD_D2, PINMUX_FUNCTION0 },//GPIO 71
    {PIN_SD_D3, PINMUX_FUNCTION0 },//GPIO 72
    {PIN_PVR_TSCLK, PINMUX_FUNCTION0 },//GPIO 73
    {PIN_PVR_TSVAL, PINMUX_FUNCTION0 },//GPIO 74
    {PIN_PVR_TSSYNC,	PINMUX_FUNCTION0 },//GPIO 75
    {PIN_PVR_TSDATA0,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION5 - GPIO 76
    {PIN_PVR_TSDATA1,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION5 - GPIO 77
    {PIN_SPI_CLK,	PINMUX_FUNCTION0 },//GPIO 78
    {PIN_SPI_CLK1,	PINMUX_FUNCTION0 },//GPIO 79
    {PIN_SPI_DATA,	PINMUX_FUNCTION0 },//GPIO 80
    {PIN_SPI_CLE,	PINMUX_FUNCTION0 },//GPIO 81
    {PIN_DEMOD_RST,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION1 - GPIO 82
    {PIN_CI_INT,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION1 - GPIO 83
    {PIN_OPWM3, PINMUX_FUNCTION0 },//PINMUX_FUNCTION1 , PINMUX_FUNCTION2 - GPIO 84
    {PIN_OPWM4, PINMUX_FUNCTION0 },//PINMUX_FUNCTION1 , PINMUX_FUNCTION2 - GPIO 85
    {PIN_OPWM0, PINMUX_FUNCTION0 },//GPIO 86
    {PIN_OPWM1, PINMUX_FUNCTION0 },//GPIO 87
    {PIN_OPWM2, PINMUX_FUNCTION0 },//GPIO 88
    {PIN_U1RX,	PINMUX_FUNCTION0 },//GPIO 89
    {PIN_U1TX,	PINMUX_FUNCTION0 },//GPIO 90
    {PIN_OSDA0, PINMUX_FUNCTION0 },//GPIO 91
    {PIN_OSCL0, PINMUX_FUNCTION0 },//GPIO 92
    {PIN_OSDA1, PINMUX_FUNCTION0 },//GPIO 93
    {PIN_OSCL1, PINMUX_FUNCTION0 },//GPIO 94
    {PIN_ALIN,	PINMUX_FUNCTION0 },//GPIO 95
    {PIN_ASPDIF0,	PINMUX_FUNCTION0 },//GPIO 96
    {PIN_ASPDIF1,	PINMUX_FUNCTION0 },//GPIO 97
    {PIN_AOMCLK,	PINMUX_FUNCTION0 },//GPIO 98
    {PIN_AOLRCK,	PINMUX_FUNCTION0 },//GPIO 99
    {PIN_AOBCK, PINMUX_FUNCTION0 },//GPIO 100
    {PIN_AOSDATA0,	PINMUX_FUNCTION0 },//GPIO 101
    {PIN_AOSDATA1,	PINMUX_FUNCTION0 },//GPIO 102
    {PIN_AOSDATA2,	PINMUX_FUNCTION0 },//GPIO 103
    {PIN_AOSDATA3,	PINMUX_FUNCTION0 },//GPIO 104
    {PIN_AOSDATA4,	PINMUX_FUNCTION0 },//GPIO 105
    {PIN_IF_AGC,	PINMUX_FUNCTION0 },//GPIO 106
    {PIN_RF_AGC,	PINMUX_FUNCTION0 },//GPIO 107
    {PIN_OSDA2, PINMUX_FUNCTION0 },//GPIO 108
    {PIN_OSCL2, PINMUX_FUNCTION0 },//GPIO 109
    {PIN_DEMOD_TSCLK,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION2 - GPIO 110
    {PIN_DEMOD_TSVAL,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION2 - GPIO 111
    {PIN_DEMOD_TSSYNC,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION2 - GPIO 112
    {PIN_DEMOD_TSDATA0, PINMUX_FUNCTION0 },//GPIO 113
    {PIN_DEMOD_TSDATA1, PINMUX_FUNCTION0 },//GPIO 114
    {PIN_DEMOD_TSDATA2, PINMUX_FUNCTION0 },//PINMUX_FUNCTION5 - GPIO 115
    {PIN_DEMOD_TSDATA3, PINMUX_FUNCTION0 },//PINMUX_FUNCTION5 - GPIO 116
    {PIN_DEMOD_TSDATA4, PINMUX_FUNCTION0 },//PINMUX_FUNCTION5 - GPIO 117
    {PIN_DEMOD_TSDATA5, PINMUX_FUNCTION0 },//GPIO 118
    {PIN_DEMOD_TSDATA6, PINMUX_FUNCTION0 },//GPIO 119
    {PIN_DEMOD_TSDATA7, PINMUX_FUNCTION0 },//GPIO 120
    {PIN_CI_TSCLK,	PINMUX_FUNCTION0 },//GPIO 121
    {PIN_CI_TSVAL,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION4 - GPIO 122
    {PIN_CI_TSSYNC, PINMUX_FUNCTION0 },//PINMUX_FUNCTION4 - GPIO 123
    {PIN_CI_TSDATA0,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION4 - GPIO 124
    {PIN_OPWM5, PINMUX_FUNCTION0 },//PINMUX_FUNCTION1 , PINMUX_FUNCTION2 - GPIO 125
    {PIN_OPWM6, PINMUX_FUNCTION0 },//PINMUX_FUNCTION1 , PINMUX_FUNCTION2 , PINMUX_FUNCTION3 - GPIO 126
    {PIN_OPWM7, PINMUX_FUNCTION0 },//GPIO 127
    {PIN_OPWM8, PINMUX_FUNCTION0 },//GPIO 128
    {PIN_EMMC_RST,	PINMUX_FUNCTION0 },//GPIO 129
    {PIN_POCE0_,	PINMUX_FUNCTION1 },//GPIO 130
    {PIN_POOE_, PINMUX_FUNCTION1 },//GPIO 131
    {PIN_PDD0,	PINMUX_FUNCTION1 },//GPIO 132
    {PIN_PDD1,	PINMUX_FUNCTION1 },//GPIO 133
    {PIN_POCE1_,	PINMUX_FUNCTION1 },//GPIO 134
    {PIN_PARB_, PINMUX_FUNCTION1 },//GPIO 135
    {PIN_POWE_, PINMUX_FUNCTION1 },//GPIO 136
    {PIN_PAALE, PINMUX_FUNCTION1 },//GPIO 137
    {PIN_PACLE, PINMUX_FUNCTION1 },//GPIO 138
    {PIN_PDD2,	PINMUX_FUNCTION1 },//GPIO 139
    {PIN_PDD3,	PINMUX_FUNCTION1 },//GPIO 140
    {PIN_PDD4,	PINMUX_FUNCTION1 },//GPIO 141
    {PIN_PDD5,	PINMUX_FUNCTION1 },//GPIO 142
    {PIN_PDD6,	PINMUX_FUNCTION1 },//GPIO 143
    {PIN_PDD7,	PINMUX_FUNCTION1 },//GPIO 144
    {PIN_EMMC_CLK,	PINMUX_FUNCTION0 },//GPIO 145
    {PIN_USB_DM_P2, PINMUX_FUNCTION0 },//GPIO 146
    {PIN_USB_DP_P2, PINMUX_FUNCTION0 },//GPIO 147
    {PIN_USB_DP_P3, PINMUX_FUNCTION0 },//GPIO 148
    {PIN_USB_DM_P3, PINMUX_FUNCTION0 },//GPIO 149
    {PIN_USB_DM_P1, PINMUX_FUNCTION0 },//GPIO 150
    {PIN_USB_DP_P1, PINMUX_FUNCTION0 },//GPIO 151
    {PIN_USB_DM_P0, PINMUX_FUNCTION0 },//GPIO 152
    {PIN_USB_DP_P0, PINMUX_FUNCTION0 },//GPIO 153
    {PIN_FAKE, PINMUX_FUNCTION0 },//GPIO 154 is not exist
    {PIN_FAKE, PINMUX_FUNCTION0 },//GPIO 155 is not exist
    {PIN_FAKE, PINMUX_FUNCTION0 },//GPIO 156 is not exist
    {PIN_FAKE, PINMUX_FUNCTION0 },//GPIO 157 is not exist
    {PIN_FAKE, PINMUX_FUNCTION0 },//GPIO 158 is not exist
    {PIN_FAKE, PINMUX_FUNCTION0 },//GPIO 159 is not exist
    {PIN_BE4P,	PINMUX_FUNCTION1 },//GPIO 160
    {PIN_BE4N,	PINMUX_FUNCTION1 },//GPIO 161
    {PIN_BE3P,	PINMUX_FUNCTION1 },//GPIO 162
    {PIN_BE3N,	PINMUX_FUNCTION1 },//GPIO 163
    {PIN_BECKP, PINMUX_FUNCTION1 },//GPIO 164
    {PIN_BECKN, PINMUX_FUNCTION1 },//GPIO 165
    {PIN_BE2P,	PINMUX_FUNCTION1 },//GPIO 166
    {PIN_BE2N,	PINMUX_FUNCTION1 },//GPIO 167
    {PIN_BE1P,	PINMUX_FUNCTION1 },//GPIO 168
    {PIN_BE1N,	PINMUX_FUNCTION1 },//GPIO 169
    {PIN_BE0P,	PINMUX_FUNCTION1 },//GPIO 170
    {PIN_BE0N,	PINMUX_FUNCTION1 },//GPIO 171
    {PIN_BO4P,	PINMUX_FUNCTION1 },//GPIO 172
    {PIN_BO4N,	PINMUX_FUNCTION1 },//GPIO 173
    {PIN_BO3P,	PINMUX_FUNCTION1 },//GPIO 174
    {PIN_BO3N,	PINMUX_FUNCTION1 },//GPIO 175
    {PIN_BOCKP, PINMUX_FUNCTION1 },//GPIO 176
    {PIN_BOCKN, PINMUX_FUNCTION1 },//GPIO 177
    {PIN_BO2P,	PINMUX_FUNCTION1 },//GPIO 178
    {PIN_BO2N,	PINMUX_FUNCTION1 },//GPIO 179
    {PIN_BO1P,	PINMUX_FUNCTION1 },//GPIO 180
    {PIN_BO1N,	PINMUX_FUNCTION1 },//GPIO 181
    {PIN_BO0P,	PINMUX_FUNCTION1 },//GPIO 182
    {PIN_BO0N,	PINMUX_FUNCTION1 },//GPIO 183
};

// DO NOT EDIT
static const UINT32  _aau1OpctrlSelFunc[TOTAL_OPCTRL_NUM][2] =
{
    {PIN_OPCTRL0,	PINMUX_FUNCTION0 },//OPCTRL(200)
    {PIN_OPCTRL1,	PINMUX_FUNCTION0 },//OPCTRL(201)
    {PIN_OPCTRL2,	PINMUX_FUNCTION0 },//OPCTRL(202)
    {PIN_OPCTRL3,	PINMUX_FUNCTION0 },//OPCTRL(203)
    {PIN_OPCTRL4,	PINMUX_FUNCTION0 },//OPCTRL(204)
    {PIN_OPCTRL5,	PINMUX_FUNCTION0 },//OPCTRL(205)
    {PIN_OPCTRL6,	PINMUX_FUNCTION0 },//OPCTRL(206)
    {PIN_OPCTRL7,	PINMUX_FUNCTION0 },//OPCTRL(207)
    {PIN_OPCTRL8,	PINMUX_FUNCTION0 },//OPCTRL(208)
    {PIN_OPCTRL9,	PINMUX_FUNCTION0 },//OPCTRL(209)
    {PIN_OPCTRL10,	PINMUX_FUNCTION0 },//OPCTRL(210)
    {PIN_OPCTRL11,	PINMUX_FUNCTION0 },//OPCTRL(211)
    {PIN_OPCTRL12,	PINMUX_FUNCTION0 },//OPCTRL(212)
    {PIN_OPCTRL13,	PINMUX_FUNCTION0 },//OPCTRL(213)
    {PIN_OPCTRL14,	PINMUX_FUNCTION0 },//OPCTRL(214)
    {PIN_OPCTRL15,	PINMUX_FUNCTION0 },//OPCTRL(215)
    {PIN_OPCTRL16,	PINMUX_FUNCTION0 },//OPCTRL(216)
    {PIN_OPCTRL17,	PINMUX_FUNCTION0 },//OPCTRL(217)
    {PIN_OPCTRL18,	PINMUX_FUNCTION0 },//OPCTRL(218)
    {PIN_OPCTRL19,	PINMUX_FUNCTION0 },//OPCTRL(219)
    {PIN_OPCTRL20,	PINMUX_FUNCTION0 },//OPCTRL(220)
    {PIN_HDMI_1_HPD,	PINMUX_FUNCTION0 },//OPCTRL(221)
    {PIN_HDMI_1_PWR5V,	PINMUX_FUNCTION0 },//OPCTRL(222)
    {PIN_HDMI_1_SDA,	PINMUX_FUNCTION0 },//OPCTRL(223)
    {PIN_HDMI_1_SCL,	PINMUX_FUNCTION0 },//OPCTRL(224)
    {PIN_HDMI_2_HPD,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION1 - OPCTRL(225)
    {PIN_HDMI_2_PWR5V,	PINMUX_FUNCTION0 },//OPCTRL(226)
    {PIN_HDMI_2_SDA,	PINMUX_FUNCTION0 },//OPCTRL(227)
    {PIN_HDMI_2_SCL,	PINMUX_FUNCTION0 },//OPCTRL(228)
    {PIN_HDMI_3_HPD,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION1 - OPCTRL(229)
    {PIN_ADIN1,	PINMUX_FUNCTION1 },//OPCTRL(230)
    {PIN_ADIN2,	PINMUX_FUNCTION1 },//OPCTRL(231)
    {PIN_ADIN3,	PINMUX_FUNCTION1 },//OPCTRL(232)
    {PIN_ADIN4,	PINMUX_FUNCTION1 },//OPCTRL(233)
    {PIN_ADIN5,	PINMUX_FUNCTION1 },//OPCTRL(234)
    {PIN_ADIN6,	PINMUX_FUNCTION1 },//OPCTRL(235)
    {PIN_ADIN7,	PINMUX_FUNCTION1 },//OPCTRL(236)
    {PIN_ADIN8,	PINMUX_FUNCTION1 },//OPCTRL(237)
    {PIN_ADIN9,	PINMUX_FUNCTION1 },//OPCTRL(238)
    {PIN_STB_SDA,	PINMUX_FUNCTION0 },//OPCTRL(239)
    {PIN_STB_SCL,	PINMUX_FUNCTION0 },//OPCTRL(240)
    {PIN_U0TX,	PINMUX_FUNCTION2 },//OPCTRL(241)
    {PIN_U0RX,	PINMUX_FUNCTION2 },//OPCTRL(242)
    {PIN_PHYLED0,	PINMUX_FUNCTION0 },//OPCTRL(243)
    {PIN_PHYLED1,	PINMUX_FUNCTION0 },//OPCTRL(244)
    {PIN_HDMI_3_SDA,	PINMUX_FUNCTION0 },//OPCTRL(245)
    {PIN_HDMI_3_SCL,	PINMUX_FUNCTION0 },//OPCTRL(246)
    {PIN_OPWRSB,	PINMUX_FUNCTION1 },//OPCTRL(247)
    {PIN_OIRI,	PINMUX_FUNCTION1 },//OPCTRL(248)
    {PIN_HDMI_0_SDA,	PINMUX_FUNCTION0 },//OPCTRL(249)
    {PIN_HDMI_0_SCL,	PINMUX_FUNCTION0 },//OPCTRL(250)
    {PIN_HDMI_CEC,	PINMUX_FUNCTION0 },//OPCTRL(251)
    {PIN_HDMI_0_PWR5V,	PINMUX_FUNCTION0 },//OPCTRL(252)
    {PIN_HDMI_0_HPD_CBUS,	PINMUX_FUNCTION0 },//OPCTRL(253)
    {PIN_LED_PWM0,	PINMUX_FUNCTION0 },//OPCTRL(254)
    {PIN_LED_PWM1,	PINMUX_FUNCTION0 },//OPCTRL(255)
    {PIN_LED_PWM2,	PINMUX_FUNCTION0 },//OPCTRL(256)
    {PIN_LED_PWM3,	PINMUX_FUNCTION0 },//OPCTRL(257)
    {PIN_MHL_SENSE,	PINMUX_FUNCTION1 },//OPCTRL(258)
    {PIN_HDMI_3_PWR5V,	PINMUX_FUNCTION0 },//OPCTRL(259)
    {PIN_VGA_SDA,	PINMUX_FUNCTION0 },//OPCTRL(260)
    {PIN_VGA_SCL,	PINMUX_FUNCTION0 },//OPCTRL(261)
    {PIN_TCON0,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - OPCTRL(262)
    {PIN_TCON1,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - OPCTRL(263)
    {PIN_TCON2,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - OPCTRL(264)
    {PIN_TCON3,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - OPCTRL(265)
    {PIN_TCON4,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - OPCTRL(266)
    {PIN_TCON5,	PINMUX_FUNCTION0 },//PINMUX_FUNCTION3 - OPCTRL(267)
    {PIN_TCON6,	PINMUX_FUNCTION0 },//OPCTRL(268)
    {PIN_TCON7,	PINMUX_FUNCTION0 },//OPCTRL(269)
    {PIN_TCON8,	PINMUX_FUNCTION0 },//OPCTRL(270)
    {PIN_TCON9,	PINMUX_FUNCTION0 },//OPCTRL(271)
    {PIN_TCON10,	PINMUX_FUNCTION0 },//OPCTRL(272)
    {PIN_TCON11,	PINMUX_FUNCTION0 },//OPCTRL(273)
    {PIN_TCON12,	PINMUX_FUNCTION0 },//OPCTRL(274)
};

//-----------------------------------------------------------------------------
// Static functions
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// Public functions
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
/** BSP_PinSet() to set pinmux data
 *  @param u4PinSel is the bit group of pinmuxers
 *  @param i4Func is the function we want to select
 *  @retval 0 is successful, otherwise failed.
 */
//-----------------------------------------------------------------------------
INT32 BSP_PinSet(UINT32 u4PinSel, INT32 i4Func)
{
    UINT32 u4HiReg, u4HiMask, u4HiBits, u4Crit;
    UINT32 u4LoReg, u4LoMask, u4LoBits;
    UINT32 u4OldRegSet;
    UNUSED(u4Crit);

    // for Oryx ES1 and ES2 PAD_OPWM1 and OPWM2
    if (u4PinSel == PIN_OPWM1)
    {
        if (i4Func == PINMUX_FUNCTION0)
        {
            IO_WRITE32_CLEAR(CKGEN_PMUX8, 0, 23);
            IO_WRITE32_CLEAR(CKGEN_PMUX0, 0, 12);
            IO_WRITE32_CLEAR(CKGEN_PMUX0, 0, 13);
        }
        else if (i4Func == PINMUX_FUNCTION1)
        {
            IO_WRITE32_CLEAR(CKGEN_PMUX8, 0, 23);
            IO_WRITE32_SET(CKGEN_PMUX0, 0, 12);
            IO_WRITE32_CLEAR(CKGEN_PMUX0, 0, 13);
        }
        else if (i4Func == PINMUX_FUNCTION2)
        {
            IO_WRITE32_CLEAR(CKGEN_PMUX8, 0, 23);
            IO_WRITE32_CLEAR(CKGEN_PMUX0, 0, 12);
            IO_WRITE32_SET(CKGEN_PMUX0, 0, 13);
        }
        else if (i4Func == PINMUX_FUNCTION3)
        {
            IO_WRITE32_SET(CKGEN_PMUX8, 0, 23);
            IO_WRITE32_SET(CKGEN_PMUX0, 0, 12);
            IO_WRITE32_SET(CKGEN_PMUX0, 0, 13);
        }
        else if (i4Func == PINMUX_FUNCTION4)
        {
            IO_WRITE32_CLEAR(CKGEN_PMUX8, 0, 23);
            IO_WRITE32_SET(CKGEN_PMUX0, 0, 12);
            IO_WRITE32_SET(CKGEN_PMUX0, 0, 13);
        }
        return 0;
    }

    if (u4PinSel == PIN_OPWM2)
    {
        if (i4Func == PINMUX_FUNCTION0)
        {
            IO_WRITE32_CLEAR(CKGEN_PMUX8, 0, 24);
            IO_WRITE32_CLEAR(CKGEN_PMUX0, 0, 14);
            IO_WRITE32_CLEAR(CKGEN_PMUX0, 0, 15);
        }
        else if (i4Func == PINMUX_FUNCTION1)
        {
            IO_WRITE32_CLEAR(CKGEN_PMUX8, 0, 24);
            IO_WRITE32_SET(CKGEN_PMUX0, 0, 14);
            IO_WRITE32_CLEAR(CKGEN_PMUX0, 0, 15);
        }
        else if (i4Func == PINMUX_FUNCTION2)
        {
            IO_WRITE32_CLEAR(CKGEN_PMUX8, 0, 24);
            IO_WRITE32_CLEAR(CKGEN_PMUX0, 0, 14);
            IO_WRITE32_SET(CKGEN_PMUX0, 0, 15);
        }
        else if (i4Func == PINMUX_FUNCTION3)
        {
            IO_WRITE32_SET(CKGEN_PMUX8, 0, 24);
            IO_WRITE32_SET(CKGEN_PMUX0, 0, 14);
            IO_WRITE32_SET(CKGEN_PMUX0, 0, 15);
        }
        else if (i4Func == PINMUX_FUNCTION4)
        {
            IO_WRITE32_CLEAR(CKGEN_PMUX8, 0, 24);
            IO_WRITE32_SET(CKGEN_PMUX0, 0, 14);
            IO_WRITE32_SET(CKGEN_PMUX0, 0, 15);
        }
        return 0;
    }
    // for Oryx ES1 and ES2 PAD_OPWM1 and OPWM2

    if ((!IS_VALID_MUX_REG(u4PinSel)) ||
        (i4Func < 0) ||
        (i4Func > MAX_FUNC(u4PinSel)))
    {
        return -1;
    }

    u4HiReg = HI_MUX_REG(u4PinSel);
    u4LoReg = LO_MUX_REG(u4PinSel);
    if ((u4HiReg > TOTAL_PIN_REG) ||
        (u4LoReg > TOTAL_PIN_REG))
    {
        return -1;
    }

    u4HiMask = 0;
    u4HiBits = 0;
    if (u4HiReg != 0)  // with high pinmux bits
    {
        u4HiReg = _au4PinmuxReg[u4HiReg];
        u4HiMask = HI_MASK(u4PinSel);
        u4HiBits = HI_BIT_OFFSET(u4PinSel);
    }
    u4LoReg = _au4PinmuxReg[u4LoReg];
    u4LoMask = LO_MASK(u4PinSel);
    u4LoBits = LO_BIT_OFFSET(u4PinSel);
#ifndef CC_UBOOT
    u4Crit = HalCriticalStart();
#endif
    if (u4HiReg != 0)
    {
        u4OldRegSet = u4IO32Read4B(u4HiReg);
        vIO32Write4B(u4HiReg, (u4IO32Read4B(u4HiReg) & (~(u4HiMask << u4HiBits))) |
                     ((UINT32)((i4Func >> (MASK_TO_BITNUM(u4LoMask) + 1)) & u4HiMask) << u4HiBits));

        if (u4OldRegSet != u4IO32Read4B(u4HiReg))
        {
            LOG(5, "Change pinmux register 0x%8x change (old: 0x%8x, new: 0x%8x)\n", u4HiReg, u4OldRegSet, u4IO32Read4B(u4HiReg));
        }
    }
    u4OldRegSet = u4IO32Read4B(u4LoReg);
    vIO32Write4B(u4LoReg, (u4IO32Read4B(u4LoReg) & (~(u4LoMask << u4LoBits))) |
                 ((UINT32)(i4Func & u4LoMask) << u4LoBits));
    if (u4OldRegSet != u4IO32Read4B(u4LoReg))
    {
        LOG(5, "Change pinmux register 0x%8x (old: 0x%8x, new: 0x%8x)\n", u4LoReg, u4OldRegSet, u4IO32Read4B(u4LoReg));
    }
#ifndef CC_UBOOT
    HalCriticalEnd(u4Crit);
#endif
    return 0;
}

//-----------------------------------------------------------------------------
/** BSP_PinGet() to get pinmux data
 *  @param u4PinSel is the bit group of pinmuxers
 *  @retval the function we select now.
 */
//-----------------------------------------------------------------------------
INT32 BSP_PinGet(UINT32 u4PinSel)
{
    UINT32 u4HiReg, u4HiMask, u4HiBits, u4HiVal, u4Crit;
    UINT32 u4LoReg, u4LoMask, u4LoBits, u4LoVal, u4Func;

    UNUSED(u4Crit);
    if (!IS_VALID_MUX_REG(u4PinSel))
    {
        return -1;
    }

    u4HiReg = HI_MUX_REG(u4PinSel);
    u4LoReg = LO_MUX_REG(u4PinSel);
    if ((u4HiReg > TOTAL_PIN_REG) ||
        (u4LoReg > TOTAL_PIN_REG))
    {
        return -1;
    }

    u4HiMask = 0;
    u4HiBits = 0;
    if (u4HiReg != 0)  // with high pinmux bits
    {
        u4HiReg = _au4PinmuxReg[u4HiReg];
        u4HiMask = HI_MASK(u4PinSel);
        u4HiBits = HI_BIT_OFFSET(u4PinSel);
    }
    u4LoReg = _au4PinmuxReg[u4LoReg];
    u4LoMask = LO_MASK(u4PinSel);
    u4LoBits = LO_BIT_OFFSET(u4PinSel);

#ifndef CC_UBOOT
    u4Crit = HalCriticalStart();
#endif
    u4LoVal = u4IO32Read4B(u4LoReg);
    u4Func = (u4LoVal >> u4LoBits) & u4LoMask;
    if (u4HiReg != 0)
    {
        u4HiVal = u4IO32Read4B(u4HiReg);
        u4Func += ((u4HiVal >> u4HiBits) & u4HiMask) << (MASK_TO_BITNUM(u4LoMask) + 1);
    }
#ifndef CC_UBOOT
    HalCriticalEnd(u4Crit);
#endif
    return (INT32)u4Func;
}

//for multi gpio, more than one function is gpio
UINT32 BSP_PinGpioCheck(UINT32 u4Pinmux)
{
    UINT32 u4Sel;

    u4Sel = BSP_PinGet(u4Pinmux);
    switch (u4Pinmux)
    {
        case PIN_OSDA2:
            if (u4Sel == PINMUX_FUNCTION3)
            {
                return 1;
            }
            break;
        default:
            break;
    }
    return 0;
}

//-----------------------------------------------------------------------------
/** BSP_PinGpioSel() to set the pin of the gpio number at gpio function.
 *  @param i4Gpio the gpio number we want to enable to gpio function.
 *  @retval 0 is successful, otherwise failed.
 */
//-----------------------------------------------------------------------------
INT32 BSP_PinGpioSel(INT32 i4Gpio)
{
    UINT32 u4GpioSel;

    if ((i4Gpio < 0) || (i4Gpio > MAX_GPIO_NUM))
    {
        return -1;
    }

    // Skip JTAG pinmux
    if ((i4Gpio >= GPIO_JTDO) && (i4Gpio <= GPIO_JTRST_))
    {
        return 0;
    }
    if ((i4Gpio >= ADIN0) && (i4Gpio <= ADIN9))//[400, 409]
    {
        UINT32 u4Idx;
        if (i4Gpio == ADIN0)
        {
#if !defined(CC_MTK_LOADER)
            LOG(2, "(%s)error servoAD 0 have no gpio function!\n", __FUNCTION__);
#endif
            return -1;
        }
        else
        {
            u4Idx = (i4Gpio - SERVO_0_ALIAS) + ((SERVO_GPIO1 - 1) - OPCTRL(0));
        }
        u4GpioSel = _aau1OpctrlSelFunc[u4Idx][0];
        if ((u4GpioSel & MULTI_GPIO_FLAG) && (BSP_PinGpioCheck(u4GpioSel)))
        {
            return 0;
        }
        if (BSP_PinGet(u4GpioSel) == _aau1OpctrlSelFunc[u4Idx][1])
        {
            return 0;
        }
        return BSP_PinSet(_aau1OpctrlSelFunc[u4Idx][0], _aau1OpctrlSelFunc[u4Idx][1]);
    }
    else if ((i4Gpio >= OPCTRL0) && (i4Gpio < (OPCTRL0 + TOTAL_OPCTRL_NUM)))//[200, 275]
    {
        u4GpioSel = _aau1OpctrlSelFunc[i4Gpio - OPCTRL0][0];

        if ((i4Gpio >= 247) && (i4Gpio <= 257))
        {
            //null, we cann't return o before call BSP_PinSet()
        }
        else
        {
            if ((u4GpioSel & MULTI_GPIO_FLAG) && (BSP_PinGpioCheck(u4GpioSel)))
            {
                return 0;
            }
            if (BSP_PinGet(u4GpioSel) == _aau1OpctrlSelFunc[i4Gpio - OPCTRL0][1])
            {
                return 0;
            }
        }
        return BSP_PinSet(_aau1OpctrlSelFunc[i4Gpio - OPCTRL0][0], _aau1OpctrlSelFunc[i4Gpio - OPCTRL0][1]);
    }
    else if (i4Gpio < TOTAL_NORMAL_GPIO_NUM)//[0, 199]
    {
        u4GpioSel = _aau1GpioSelFunc[i4Gpio][0];
        if ((u4GpioSel & MULTI_GPIO_FLAG) && (BSP_PinGpioCheck(u4GpioSel)))
        {
            return 0;
        }
        if (BSP_PinGet(u4GpioSel) == _aau1GpioSelFunc[i4Gpio][1])
        {
            return 0;
        }
        return BSP_PinSet(_aau1GpioSelFunc[i4Gpio][0], _aau1GpioSelFunc[i4Gpio][1]);
    }
    return -1;
}

//-----------------------------------------------------------------------------
/** BSP_PinGpioGet() to Get the original function of selected gpio pin.
 *  @param i4Gpio the gpio number we want to enable to gpio function.
 *  @param pi4PinSel  return of logical gpio mapping physical pin.
 *  @retval the function we select now.
 */
//-----------------------------------------------------------------------------
INT32 BSP_PinGpioGet(INT32 i4Gpio, UINT32* pu4PinSel)
{
    if ((i4Gpio < 0) || (i4Gpio > MAX_GPIO_NUM))
    {
        return -1;
    }

    if (pu4PinSel == NULL)
    {
        return -1;
    }

    if ((i4Gpio >= ADIN0) && (i4Gpio <= ADIN9))
    {
        UINT32 u4Idx;
        if (i4Gpio == ADIN0)
        {
#if !defined(CC_MTK_LOADER)
            LOG(2, "(%s)error servoAD 0 have no gpio function!\n", __FUNCTION__);
#endif
            return -1;
        }
        else
        {
            u4Idx = (i4Gpio - SERVO_0_ALIAS) + ((SERVO_GPIO1 - 1) - OPCTRL(0));
        }
        *pu4PinSel =  _aau1OpctrlSelFunc[u4Idx][0];
        return BSP_PinGet(_aau1OpctrlSelFunc[u4Idx][0]);
    }
    else if ((i4Gpio >= OPCTRL0) && (i4Gpio < (OPCTRL0 + TOTAL_OPCTRL_NUM)))
    {
        *pu4PinSel =  _aau1OpctrlSelFunc[i4Gpio - OPCTRL0][0];
        return BSP_PinGet(_aau1OpctrlSelFunc[i4Gpio - OPCTRL0][0]);
    }
    else if (i4Gpio < TOTAL_NORMAL_GPIO_NUM)
    {
        *pu4PinSel =  _aau1GpioSelFunc[i4Gpio][0];
        return BSP_PinGet(_aau1GpioSelFunc[i4Gpio][0]);
    }
    return -1;
}

