text: /** @file
    This file contains specific GPIO information
  
    Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
  
    SPDX-License-Identifier: BSD-2-Clause-Patent
  **/
  
  #include <Base.h>
  #include <Uefi/UefiBaseType.h>
  #include <Library/IoLib.h>
  #include <Library/DebugLib.h>
  #include <Library/BaseMemoryLib.h>
  #include <SaAccess.h>
  #include <Library/GpioLib.h>
  #include <Library/GpioNativeLib.h>
  #include <Library/PchInfoLib.h>
  #include <Library/SataLib.h>
  #include <Private/Library/GpioPrivateLib.h>
  #include <GpioPinsCnlLp.h>
  #include <GpioPinsCnlH.h>
  #include <Register/PchRegsGpio.h>
  #include <Register/PchRegsGpioCnl.h>
  #include <Register/PchRegsSerialIo.h>
  #include <Register/PchRegsIsh.h>
  #include <Register/PchRegsScs.h>
  #include <Register/PchRegsLpcCnl.h>
  
  #include "GpioNativePrivateLibInternal.h"
  
  //
  // I2C controller pins
  // I2C[controller number][pin: SDA/SCL]
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpI2cGpio [][PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER]=
  {
    {{GPIO_CNL_LP_GPP_C16, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_C17, GpioPadModeNative1}},
    {{GPIO_CNL_LP_GPP_C18, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_C19, GpioPadModeNative1}},
    {{GPIO_CNL_LP_GPP_H4,  GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H5 , GpioPadModeNative1}},
    {{GPIO_CNL_LP_GPP_H6,  GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H7 , GpioPadModeNative1}},
    {{GPIO_CNL_LP_GPP_H8,  GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H9 , GpioPadModeNative1}},
    {{GPIO_CNL_LP_GPP_H10, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H11, GpioPadModeNative1}}
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION  mPchHI2cGpio [][PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER]=
  {
    {{GPIO_CNL_H_GPP_C16, GpioPadModeNative1}, {GPIO_CNL_H_GPP_C17, GpioPadModeNative1}}, // I2C0
    {{GPIO_CNL_H_GPP_C18, GpioPadModeNative1}, {GPIO_CNL_H_GPP_C19, GpioPadModeNative1}}, // I2C1
    {{GPIO_CNL_H_GPP_D13, GpioPadModeNative3}, {GPIO_CNL_H_GPP_D14, GpioPadModeNative3}}, // I2C2
    {{GPIO_CNL_H_GPP_D4,  GpioPadModeNative2}, {GPIO_CNL_H_GPP_D23, GpioPadModeNative2}}  // I2C3
  };
  
  
  /**
    This function provides SerialIo I2C controller pins
  
    @param[in]  SerialIoI2cControllerNumber    I2C controller
  
    @param[out] NativePinsTable                Table with pins
    @param[out] NoOfNativePins                 Number of pins
  **/
  VOID
  GpioGetSerialIoI2cPins (
    IN  UINT32                      SerialIoI2cControllerNumber,
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
    )
  {
    if (IsPchLp ()) {
      if (SerialIoI2cControllerNumber < ARRAY_SIZE (mPchLpI2cGpio)) {
        *NativePinsTable = mPchLpI2cGpio[SerialIoI2cControllerNumber];
        return;
      }
    } else {
      if (SerialIoI2cControllerNumber < ARRAY_SIZE (mPchHI2cGpio)) {
        *NativePinsTable = mPchHI2cGpio[SerialIoI2cControllerNumber];
        return;
      }
    }
    *NativePinsTable = NULL;
    ASSERT (FALSE);
  }
  //
  // UART controller pins
  // UART[controller number][pin: RXD/TXD/RTSB/CTSB]
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpUartGpio [][PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER]=
  {
    { // UART0
      {GPIO_CNL_LP_GPP_C8,  GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_C9,  GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_C10, GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_C11, GpioPadModeNative1}
    },
    { // UART1
      {GPIO_CNL_LP_GPP_C12, GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_C13, GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_C14, GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_C15, GpioPadModeNative1}
    },
    { // UART2
      {GPIO_CNL_LP_GPP_C20, GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_C21, GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_C22, GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_C23, GpioPadModeNative1},
    },
    { // UART0 (2nd pin set)
      {GPIO_CNL_LP_GPP_F5, GpioPadModeNative2},
      {GPIO_CNL_LP_GPP_F6, GpioPadModeNative2},
      {GPIO_CNL_LP_GPP_F4, GpioPadModeNative2},
      {GPIO_CNL_LP_GPP_F7, GpioPadModeNative2}
    }
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHUartGpio [][PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER]=
  {
    { // UART0
      {GPIO_CNL_H_GPP_C8,  GpioPadModeNative1},
      {GPIO_CNL_H_GPP_C9,  GpioPadModeNative1},
      {GPIO_CNL_H_GPP_C10, GpioPadModeNative1},
      {GPIO_CNL_H_GPP_C11, GpioPadModeNative1}
    },
    { // UART1
      {GPIO_CNL_H_GPP_C12, GpioPadModeNative1},
      {GPIO_CNL_H_GPP_C13, GpioPadModeNative1},
      {GPIO_CNL_H_GPP_C14, GpioPadModeNative1},
      {GPIO_CNL_H_GPP_C15, GpioPadModeNative1}
    },
    { // UART2
      {GPIO_CNL_H_GPP_C20, GpioPadModeNative1},
      {GPIO_CNL_H_GPP_C21, GpioPadModeNative1},
      {GPIO_CNL_H_GPP_C22, GpioPadModeNative1},
      {GPIO_CNL_H_GPP_C23, GpioPadModeNative1}
    },
    { // UART0 (2nd pin set)
      {GPIO_CNL_H_GPP_J5, GpioPadModeNative2},
      {GPIO_CNL_H_GPP_J6, GpioPadModeNative2},
      {GPIO_CNL_H_GPP_J4, GpioPadModeNative2},
      {GPIO_CNL_H_GPP_J7, GpioPadModeNative2}
    }
  };
  
  /**
    This function provides SerialIo UART controller pins
  
    @param[in]  SerialIoUartControllerNumber   UART controller
    @param[in]  HardwareFlowControl            Hardware Flow control
    @param[in]  PinMuxing                      UART controller pin muxing
     @param[out] NativePinsTable                Table with pins
    @param[out] NoOfNativePins                 Number of pins
  **/
  VOID
  GpioGetSerialIoUartPins (
    IN  UINT32                      SerialIoUartControllerNumber,
    IN  BOOLEAN                     HardwareFlowControl,
    IN  UINT32                      PinMuxing,
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
    OUT UINT32                      *NoOfNativePins
    )
  {
    UINTN                    UartGpioIndex;
  
    UartGpioIndex = SerialIoUartControllerNumber;
  
    if ((SerialIoUartControllerNumber == 0) && (PinMuxing == 1)) {
      // Last record is for UART0 second pin set
      if (IsPchLp ()) {
        UartGpioIndex = ARRAY_SIZE (mPchLpUartGpio) - 1;
      } else {
        UartGpioIndex = ARRAY_SIZE (mPchHUartGpio) - 1;
      }
    }
  
    if (HardwareFlowControl) {
      *NoOfNativePins = PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER;
    } else {
      *NoOfNativePins = PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER_NO_FLOW_CTRL;
    }
  
    if (IsPchLp ()) {
      if (UartGpioIndex < ARRAY_SIZE (mPchLpUartGpio)) {
        *NativePinsTable = mPchLpUartGpio[UartGpioIndex];
        return;
      }
    } else {
      if (UartGpioIndex < ARRAY_SIZE (mPchHUartGpio)) {
        *NativePinsTable = mPchHUartGpio[UartGpioIndex];
        return;
      }
    }
  
    *NativePinsTable = NULL;
    *NoOfNativePins = 0;
    ASSERT (FALSE);
  }
  
  //
  // SPI controller pins
  // SPI[controller number][pin: CSB/CLK/MISO/MOSI]
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSpiGpio [][PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER]=
  {
    { // SPI0
      {GPIO_CNL_LP_GPP_B15, GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_B16, GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_B17, GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_B18, GpioPadModeNative1}
    },
    { // SPI1
      {GPIO_CNL_LP_GPP_B19, GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_B20, GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_B21, GpioPadModeNative1},
      {GPIO_CNL_LP_GPP_B22, GpioPadModeNative1}
    },
    { // SPI2
      {GPIO_CNL_LP_GPP_D9,  GpioPadModeNative3},
      {GPIO_CNL_LP_GPP_D10, GpioPadModeNative3},
      {GPIO_CNL_LP_GPP_D11, GpioPadModeNative3},
      {GPIO_CNL_LP_GPP_D12, GpioPadModeNative3}
    }
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSpiGpio [][PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER]=
  {
    { // SPI0
      {GPIO_CNL_H_GPP_B15, GpioPadModeNative1},
      {GPIO_CNL_H_GPP_B16, GpioPadModeNative1},
      {GPIO_CNL_H_GPP_B17, GpioPadModeNative1},
      {GPIO_CNL_H_GPP_B18, GpioPadModeNative1}
    },
    { // SPI1
      {GPIO_CNL_H_GPP_B19, GpioPadModeNative1},
      {GPIO_CNL_H_GPP_B20, GpioPadModeNative1},
      {GPIO_CNL_H_GPP_B21, GpioPadModeNative1},
      {GPIO_CNL_H_GPP_B22, GpioPadModeNative1}
    },
    { // SPI2
      {GPIO_CNL_H_GPP_D9,  GpioPadModeNative3},
      {GPIO_CNL_H_GPP_D10, GpioPadModeNative3},
      {GPIO_CNL_H_GPP_D11, GpioPadModeNative3},
      {GPIO_CNL_H_GPP_D12, GpioPadModeNative3}
    }
  };
  
  /**
    This function provides SerialIo SPI controller pins
  
    @param[in]  SerialIoSpiControllerNumber   SPI controller
  
    @param[out] NativePinsTable               Table with pins
    @param[out] NoOfNativePins                Number of pins
  **/
  VOID
  GpioGetSerialIoSpiPins (
    IN  UINT32                      SerialIoSpiControllerNumber,
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
    OUT UINT32                      *NoOfNativePins
    )
  {
    if (IsPchLp ()) {
      if (SerialIoSpiControllerNumber < ARRAY_SIZE (mPchLpSpiGpio)) {
        *NativePinsTable = mPchLpSpiGpio[SerialIoSpiControllerNumber];
        *NoOfNativePins =  ARRAY_SIZE (mPchLpSpiGpio[SerialIoSpiControllerNumber]);
        return;
      }
    } else {
      if (SerialIoSpiControllerNumber < ARRAY_SIZE (mPchHSpiGpio)) {
        *NativePinsTable = mPchHSpiGpio[SerialIoSpiControllerNumber];
        *NoOfNativePins =  ARRAY_SIZE (mPchHSpiGpio[SerialIoSpiControllerNumber]);
        return;
      }
    }
    *NativePinsTable = NULL;
    *NoOfNativePins = 0;
    ASSERT (FALSE);
  }
  
  //
  // ISH GP pin
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpIshGPGpio[] =
  {
    {GPIO_CNL_LP_GPP_A18, GpioPadModeNative1},// ISH_GP_0
    {GPIO_CNL_LP_GPP_A19, GpioPadModeNative1},// ISH_GP_1
    {GPIO_CNL_LP_GPP_A20, GpioPadModeNative1},// ISH_GP_2
    {GPIO_CNL_LP_GPP_A21, GpioPadModeNative1},// ISH_GP_3
    {GPIO_CNL_LP_GPP_A22, GpioPadModeNative1},// ISH_GP_4
    {GPIO_CNL_LP_GPP_A23, GpioPadModeNative1},// ISH_GP_5
    {GPIO_CNL_LP_GPP_A12, GpioPadModeNative2},// ISH_GP_6
    {GPIO_CNL_LP_GPP_A17, GpioPadModeNative2} // ISH_GP_7
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHIshGPGpio[] =
  {
    {GPIO_CNL_H_GPP_A18, GpioPadModeNative1},// ISH_GP_0
    {GPIO_CNL_H_GPP_A19, GpioPadModeNative1},// ISH_GP_1
    {GPIO_CNL_H_GPP_A20, GpioPadModeNative1},// ISH_GP_2
    {GPIO_CNL_H_GPP_A21, GpioPadModeNative1},// ISH_GP_3
    {GPIO_CNL_H_GPP_A22, GpioPadModeNative1},// ISH_GP_4
    {GPIO_CNL_H_GPP_A23, GpioPadModeNative1},// ISH_GP_5
    {GPIO_CNL_H_GPP_A12, GpioPadModeNative2},// ISH_GP_6
    {GPIO_CNL_H_GPP_A17, GpioPadModeNative2} // ISH_GP_7
  };
  
  /**
    This function provides ISH GP pin data
  
    @param[in]  IshGpPinNumber        ISH GP pin number
    @param[out] NativePin             ISH GP pin
  **/
  VOID
  GpioGetIshGpPin (
    IN  UINT32                      IshGpPinNumber,
    OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
    )
  {
    if (IsPchLp ()) {
      if (IshGpPinNumber < ARRAY_SIZE (mPchLpIshGPGpio)) {
        *NativePin = mPchLpIshGPGpio[IshGpPinNumber];
        return;
      }
    } else {
      if (IshGpPinNumber < ARRAY_SIZE (mPchHIshGPGpio)) {
        *NativePin = mPchHIshGPGpio[IshGpPinNumber];
        return;
      }
    }
    *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
    ASSERT (FALSE);
  }
  
  //
  // ISH UART controller pins
  // ISH UART[controller number][pin: RXD/TXD/RTSB/CTSB]
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpIshUartGpio[][PCH_ISH_PINS_PER_UART_CONTROLLER] =
  {
    { // UART0
      {GPIO_CNL_LP_GPP_D13, GpioPadModeNative1},// ISH_UART0_RXD
      {GPIO_CNL_LP_GPP_D14, GpioPadModeNative1},// ISH_UART0_TXD
      {GPIO_CNL_LP_GPP_D15, GpioPadModeNative1},// ISH_UART0_RTS
      {GPIO_CNL_LP_GPP_D16, GpioPadModeNative1} // ISH_UART0_CTS
    },
    { // UART1
      {GPIO_CNL_LP_GPP_C12, GpioPadModeNative2},// ISH_UART1_RXD
      {GPIO_CNL_LP_GPP_C13, GpioPadModeNative2},// ISH_UART1_TXD
      {GPIO_CNL_LP_GPP_C14, GpioPadModeNative2},// ISH_UART1_RTSB
      {GPIO_CNL_LP_GPP_C15, GpioPadModeNative2} // ISH_UART1_CTSB
    }
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHIshUartGpio[][PCH_ISH_PINS_PER_UART_CONTROLLER] =
  {
    { // UART0
      {GPIO_CNL_H_GPP_D13, GpioPadModeNative1},// ISH_UART0_RXD
      {GPIO_CNL_H_GPP_D14, GpioPadModeNative1},// ISH_UART0_TXD
      {GPIO_CNL_H_GPP_D15, GpioPadModeNative1},// ISH_UART0_RTS
      {GPIO_CNL_H_GPP_D16, GpioPadModeNative1} // ISH_UART0_CTS
    },
    { // UART1
      {GPIO_CNL_H_GPP_C12, GpioPadModeNative2},// ISH_UART1_RXD
      {GPIO_CNL_H_GPP_C13, GpioPadModeNative2},// ISH_UART1_TXD
      {GPIO_CNL_H_GPP_C14, GpioPadModeNative2},// ISH_UART1_RTS
      {GPIO_CNL_H_GPP_C15, GpioPadModeNative2} // ISH_UART1_CTS
    }
  };
  
  /**
    This function provides ISH UART controller pins
  
    @param[in]  IshUartControllerNumber   ISH UART controller
  
    @param[out] NativePinsTable           Table with pins
  **/
  VOID
  GpioGetIshUartPins (
    IN  UINT32                      IshUartControllerNumber,
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
    )
  {
    if (IsPchLp ()) {
      if (IshUartControllerNumber < ARRAY_SIZE (mPchLpIshUartGpio)) {
        *NativePinsTable = mPchLpIshUartGpio[IshUartControllerNumber];
        return;
      }
    } else {
      if (IshUartControllerNumber < ARRAY_SIZE (mPchHIshUartGpio)) {
        *NativePinsTable = mPchHIshUartGpio[IshUartControllerNumber];
        return;
      }
    }
    *NativePinsTable = NULL;
    ASSERT (FALSE);
  }
  
  //
  // ISH I2C controller pins
  // ISH I2C[controller number][pin: SDA/SCL]
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpIshI2cGpio[][PCH_ISH_PINS_PER_I2C_CONTROLLER] =
  {
    { // I2C0
      {GPIO_CNL_LP_GPP_D5,  GpioPadModeNative1},// ISH_I2C0_SDA
      {GPIO_CNL_LP_GPP_D6,  GpioPadModeNative1} // ISH_I2C0_SCL
    },
    { // I2C1
      {GPIO_CNL_LP_GPP_D7,  GpioPadModeNative1},// ISH_I2C1_SDA
      {GPIO_CNL_LP_GPP_D8,  GpioPadModeNative1} // ISH_I2C1_SCL
    },
    { // I2C2
      {GPIO_CNL_LP_GPP_H10, GpioPadModeNative2},// ISH_I2C2_SDA
      {GPIO_CNL_LP_GPP_H11, GpioPadModeNative2} // ISH_I2C2_SCL
    },
    { // I2C3
      {GPIO_CNL_LP_GPP_H4,  GpioPadModeNative2},// ISH_I2C3_SDA
      {GPIO_CNL_LP_GPP_H5,  GpioPadModeNative2} // ISH_I2C3_SCL
    },
    { // I2C4
      {GPIO_CNL_LP_GPP_H6,  GpioPadModeNative2},// ISH_I2C4_SDA
      {GPIO_CNL_LP_GPP_H7,  GpioPadModeNative2} // ISH_I2C4_SCL
    },
    { // I2C5
      {GPIO_CNL_LP_GPP_H8,  GpioPadModeNative2},// ISH_I2C5_SDA
      {GPIO_CNL_LP_GPP_H9,  GpioPadModeNative2} // ISH_I2C5_SCL
    }
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHIshI2cGpio[][PCH_ISH_PINS_PER_I2C_CONTROLLER] =
  {
    { // I2C0
      {GPIO_CNL_H_GPP_H19, GpioPadModeNative1},// ISH_I2C0_SDA
      {GPIO_CNL_H_GPP_H20, GpioPadModeNative1} // ISH_I2C0_SCL
    },
    { // I2C1
      {GPIO_CNL_H_GPP_H21, GpioPadModeNative1},// ISH_I2C1_SDA
      {GPIO_CNL_H_GPP_H22, GpioPadModeNative1} // ISH_I2C1_SCL
    },
    { // I2C2
      {GPIO_CNL_H_GPP_D4,  GpioPadModeNative1},// ISH_I2C2_SDA
      {GPIO_CNL_H_GPP_D23, GpioPadModeNative1} // ISH_I2C2_SCL
    }
  };
  
  /**
    This function provides ISH I2C controller pins
  
    @param[in]  IshI2cControllerNumber   ISH I2C controller
  
    @param[out] NativePinsTable          Table with pins
  **/
  VOID
  GpioGetIshI2cPins (
    IN  UINT32                      IshI2cControllerNumber,
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
    )
  {
    if (IsPchLp ()) {
      if (IshI2cControllerNumber < ARRAY_SIZE (mPchLpIshI2cGpio)) {
        *NativePinsTable = mPchLpIshI2cGpio[IshI2cControllerNumber];
        return;
      }
    } else {
      if (IshI2cControllerNumber < ARRAY_SIZE (mPchHIshI2cGpio)) {
        *NativePinsTable = mPchHIshI2cGpio[IshI2cControllerNumber];
        return;
      }
    }
    *NativePinsTable = NULL;
    ASSERT (FALSE);
  }
  
  //
  // ISH SPI controller pins
  // ISH SPI[pin: CSB/CLK/MISO/MOSI]
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpIshSpiGpio[PCH_ISH_PINS_PER_SPI_CONTROLLER] =
  {
    {GPIO_CNL_LP_GPP_D9,  GpioPadModeNative1},// ISH_SPI_CSB
    {GPIO_CNL_LP_GPP_D10, GpioPadModeNative1},// ISH_SPI_CLK
    {GPIO_CNL_LP_GPP_D11, GpioPadModeNative1},// ISH_SPI_MISO
    {GPIO_CNL_LP_GPP_D12, GpioPadModeNative1} // ISH_SPI_MOSI
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHIshSpiGpio[PCH_ISH_PINS_PER_SPI_CONTROLLER] =
  {
    {GPIO_CNL_H_GPP_D9,  GpioPadModeNative1},// ISH_SPI_CSB
    {GPIO_CNL_H_GPP_D10, GpioPadModeNative1},// ISH_SPI_CLK
    {GPIO_CNL_H_GPP_D11, GpioPadModeNative1},// ISH_SPI_MISO
    {GPIO_CNL_H_GPP_D12, GpioPadModeNative1} // ISH_SPI_MOSI
  };
  
  /**
    This function provides ISH SPI controller pins
  
    @param[in]  IshSpiControllerNumber   SPI controller
    @param[out] NativePinsTable          Table with pins
    @param[out] NoOfNativePins           Number of pins
  **/
  VOID
  GpioGetIshSpiPins (
    IN  UINT32                      IshSpiControllerNumber,
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
    OUT UINT32                      *NoOfNativePins
    )
  {
    if (IsPchLp ()) {
      if (IshSpiControllerNumber < ARRAY_SIZE (mPchLpIshSpiGpio)) {
        *NativePinsTable = mPchLpIshSpiGpio;
        *NoOfNativePins = ARRAY_SIZE (mPchLpIshSpiGpio);
        return;
      }
    } else {
      if (IshSpiControllerNumber < ARRAY_SIZE (mPchHIshSpiGpio)) {
        *NativePinsTable = mPchHIshSpiGpio;
        *NoOfNativePins = ARRAY_SIZE (mPchHIshSpiGpio);
        return;
      }
    }
  
    *NoOfNativePins = 0;
    *NativePinsTable = NULL;
    ASSERT (FALSE);
  }
  
  //
  // GPIO pins for SD controller
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpScsSdCardGpio[9] =
  {
    {GPIO_CNL_LP_GPP_A17, GpioPadModeNative1},// SD_PWR_EN_B
    {GPIO_CNL_LP_GPP_G0,  GpioPadModeNative1},// SD_CMD
    {GPIO_CNL_LP_GPP_G1,  GpioPadModeNative1},// SD_DATA_0
    {GPIO_CNL_LP_GPP_G2,  GpioPadModeNative1},// SD_DATA_1
    {GPIO_CNL_LP_GPP_G3,  GpioPadModeNative1},// SD_DATA_2
    {GPIO_CNL_LP_GPP_G4,  GpioPadModeNative1},// SD_DATA_3
    {GPIO_CNL_LP_GPP_G5,  GpioPadModeNative1},// SD_CDB
    {GPIO_CNL_LP_GPP_G6,  GpioPadModeNative1},// SD_CLK
    {GPIO_CNL_LP_GPP_G7,  GpioPadModeNative1} // SD_WP
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHScsSdCardGpio[9] =
  {
    {GPIO_CNL_H_GPP_A17, GpioPadModeNative1},// SD_PWR_EN_B
    {GPIO_CNL_H_GPP_G0,  GpioPadModeNative1},// SD_CMD
    {GPIO_CNL_H_GPP_G1,  GpioPadModeNative1},// SD_DATA_0
    {GPIO_CNL_H_GPP_G2,  GpioPadModeNative1},// SD_DATA_1
    {GPIO_CNL_H_GPP_G3,  GpioPadModeNative1},// SD_DATA_2
    {GPIO_CNL_H_GPP_G4,  GpioPadModeNative1},// SD_DATA_3
    {GPIO_CNL_H_GPP_G5,  GpioPadModeNative1},// SD_CDB
    {GPIO_CNL_H_GPP_G6,  GpioPadModeNative1},// SD_CLK
    {GPIO_CNL_H_GPP_G7,  GpioPadModeNative1} // SD_WP
  };
  
  /**
    This function provides SCS SD CARD controller pins
  
    @param[out] NativePinsTable                Table with pins
    @param[out] NoOfNativePins                 Number of pins
  **/
  VOID
  GpioGetScsSdCardPins (
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
    OUT UINT32                      *NoOfNativePins
    )
  {
    if (IsPchLp ()) {
      *NativePinsTable = mPchLpScsSdCardGpio;
      *NoOfNativePins = ARRAY_SIZE (mPchLpScsSdCardGpio);
    } else {
      *NativePinsTable = mPchHScsSdCardGpio;
      *NoOfNativePins = ARRAY_SIZE (mPchHScsSdCardGpio);
    }
  }
  
  /**
    This function provides SCS SD CARD detect pin
  
    @retval GpioPin             SD CARD Detect pin
  **/
  GPIO_PAD
  GpioGetScsSdCardDetectPin (
    VOID
    )
  {
    if (IsPchLp ()) {
      return GPIO_CNL_LP_VGPIO39;
    } else {
      return GPIO_CNL_H_VGPIO6;
    }
  }
  
  //
  // GPIO pins for eMMC controller
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpScsEmmcGpio[12] =
  {
    {GPIO_CNL_LP_GPP_F11, GpioPadModeNative1},// EMMC_CMD
    {GPIO_CNL_LP_GPP_F12, GpioPadModeNative1},// EMMC_DATA_0
    {GPIO_CNL_LP_GPP_F13, GpioPadModeNative1},// EMMC_DATA_1
    {GPIO_CNL_LP_GPP_F14, GpioPadModeNative1},// EMMC_DATA_2
    {GPIO_CNL_LP_GPP_F15, GpioPadModeNative1},// EMMC_DATA_3
    {GPIO_CNL_LP_GPP_F16, GpioPadModeNative1},// EMMC_DATA_4
    {GPIO_CNL_LP_GPP_F17, GpioPadModeNative1},// EMMC_DATA_5
    {GPIO_CNL_LP_GPP_F18, GpioPadModeNative1},// EMMC_DATA_6
    {GPIO_CNL_LP_GPP_F19, GpioPadModeNative1},// EMMC_DATA_7
    {GPIO_CNL_LP_GPP_F20, GpioPadModeNative1},// EMMC_RCLK
    {GPIO_CNL_LP_GPP_F21, GpioPadModeNative1},// EMMC_CLK
    {GPIO_CNL_LP_GPP_F22, GpioPadModeNative1} // EMMC_RESETB
  };
  
  /**
    This function provides SCS eMMC controller pins
  
    @param[out] NativePinsTable                Table with pins
    @param[out] NoOfNativePins                 Number of pins
  **/
  VOID
  GpioGetScsEmmcPins (
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
    OUT UINT32                      *NoOfNativePins
    )
  {
    if (IsPchLp ()) {
      *NativePinsTable = mPchLpScsEmmcGpio;
      *NoOfNativePins = ARRAY_SIZE (mPchLpScsEmmcGpio);
    } else {
      ASSERT (FALSE);
      return;
    }
  }
  
  //
  // GPIO pins for HD Audio Link [pin: BCLK/RSTB/SYNC/SDO/SDIx]
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaLinkGpio[PCH_GPIO_HDA_LINK_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_LP_HDA_BCLK,  GpioPadModeNative1},// HDA_BCLK
    {GPIO_CNL_LP_HDA_RSTB,  GpioPadModeNative1},// HDA_RSTB
    {GPIO_CNL_LP_HDA_SYNC,  GpioPadModeNative1},// HDA_SYNC
    {GPIO_CNL_LP_HDA_SDO,   GpioPadModeNative1},// HDA_SDO
    {GPIO_CNL_LP_HDA_SDI_0, GpioPadModeNative1},// HDA_SDI_0
    {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative1} // HDA_SDI_1
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaLinkGpio[PCH_GPIO_HDA_LINK_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_H_HDA_BCLK,  GpioPadModeNative1},// HDA_BCLK
    {GPIO_CNL_H_HDA_RSTB,  GpioPadModeNative1},// HDA_RSTB
    {GPIO_CNL_H_HDA_SYNC,  GpioPadModeNative1},// HDA_SYNC
    {GPIO_CNL_H_HDA_SDO,   GpioPadModeNative1},// HDA_SDO
    {GPIO_CNL_H_HDA_SDI_0, GpioPadModeNative1},// HDA_SDI_0
    {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative1} // HDA_SDI_1
  };
  
  /**
    This function provides HD Audio Link pins
  
    @param[out] NativePinsTable                Table with pins
    @param[out] NoOfNativePins                 Number of pins
  **/
  VOID
  GpioGetHdAudioLinkPins (
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
    OUT UINT32                      *NoOfNativePins
    )
  {
    if (IsPchLp ()) {
      *NativePinsTable = mPchLpHdaLinkGpio;
      *NoOfNativePins = ARRAY_SIZE (mPchLpHdaLinkGpio);
    } else {
      *NativePinsTable = mPchHHdaLinkGpio;
      *NoOfNativePins = ARRAY_SIZE (mPchHHdaLinkGpio);
    }
  }
  
  //
  // GPIO pins for HD Audio DMIC [DMIC number][pin: CLK/DATA]
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaDmicGpio[][PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS] =
  {
    { // DMIC0
      {GPIO_CNL_LP_GPP_D19, GpioPadModeNative1},// DMIC_CLK_0
      {GPIO_CNL_LP_GPP_D20, GpioPadModeNative1} // DMIC_DATA_0
    },
    { // DMIC1
      {GPIO_CNL_LP_GPP_D17, GpioPadModeNative1},// DMIC_CLK_1
      {GPIO_CNL_LP_GPP_D18, GpioPadModeNative1} // DMIC_DATA_1
    }
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaDmicGpio[][PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS] =
  {
    { // DMIC0
      {GPIO_CNL_H_GPP_D19, GpioPadModeNative1},// DMIC_CLK_0
      {GPIO_CNL_H_GPP_D20, GpioPadModeNative1} // DMIC_DATA_0
    },
    { // DMIC1
      {GPIO_CNL_H_GPP_D17, GpioPadModeNative1},// DMIC_CLK_1
      {GPIO_CNL_H_GPP_D18, GpioPadModeNative1} // DMIC_DATA_1
    }
  };
  
  /**
    This function provides DMIC interface pins
  
    @param[in]  DmicNumber               DMIC interface
  
    @param[out] NativePinsTable          Table with pins
  **/
  VOID
  GpioGetHdaDmicPins (
    IN  UINT32                      DmicNumber,
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
    )
  {
    if (IsPchLp ()) {
      if (DmicNumber < ARRAY_SIZE (mPchLpHdaDmicGpio)) {
        *NativePinsTable = mPchLpHdaDmicGpio[DmicNumber];
        return;
      }
    } else {
      if (DmicNumber < ARRAY_SIZE (mPchHHdaDmicGpio)) {
        *NativePinsTable = mPchHHdaDmicGpio[DmicNumber];
        return;
      }
    }
    *NativePinsTable = NULL;
    ASSERT (FALSE);
  }
  
  //
  // GPIO pins for HD Audio SSPx/I2Sx interface [SSP number][pin: SCLK/SFRM/TXD/RXD]
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaSspInterfaceGpio[][PCH_GPIO_HDA_SSP_NUMBER_OF_PINS] =
  {
    { // SSP0/I2S0
      {GPIO_CNL_LP_HDA_BCLK,  GpioPadModeNative2},// SSP0_SCLK
      {GPIO_CNL_LP_HDA_SYNC,  GpioPadModeNative2},// SSP0_SFRM
      {GPIO_CNL_LP_HDA_SDO,   GpioPadModeNative2},// SSP0_TXD
      {GPIO_CNL_LP_HDA_SDI_0, GpioPadModeNative2} // SSP0_RXD
    },
    { // SSP1/I2S1
      {GPIO_CNL_LP_HDA_RSTB,  GpioPadModeNative2},// SSP1_SCLK
      {GPIO_CNL_LP_SSP1_SFRM, GpioPadModeNative1},// SSP1_SFRM
      {GPIO_CNL_LP_SSP1_TXD,  GpioPadModeNative1},// SSP1_TXD
      {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative2} // SSP1_RXD
    },
    { // SSP2/I2S2
      {GPIO_CNL_LP_GPP_H0, GpioPadModeNative1},// SSP2_SCLK
      {GPIO_CNL_LP_GPP_H1, GpioPadModeNative1},// SSP2_SFRM
      {GPIO_CNL_LP_GPP_H2, GpioPadModeNative1},// SSP2_TXD
      {GPIO_CNL_LP_GPP_H3, GpioPadModeNative1} // SSP2_RXD
    }
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaSspInterfaceGpio[][PCH_GPIO_HDA_SSP_NUMBER_OF_PINS] =
  {
    { // SSP0/I2S0
      {GPIO_CNL_H_HDA_BCLK,  GpioPadModeNative2},// SSP0_SCLK
      {GPIO_CNL_H_HDA_SYNC,  GpioPadModeNative2},// SSP0_SFRM
      {GPIO_CNL_H_HDA_SDO,   GpioPadModeNative2},// SSP0_TXD
      {GPIO_CNL_H_HDA_SDI_0, GpioPadModeNative2} // SSP0_RXD
    },
    { // SSP1/I2S1
      {GPIO_CNL_H_HDA_RSTB,  GpioPadModeNative2},// SSP1_SCLK
      {GPIO_CNL_H_SSP1_SFRM, GpioPadModeNative1},// SSP1_SFRM
      {GPIO_CNL_H_SSP1_TXD,  GpioPadModeNative1},// SSP1_TXD
      {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative2} // SSP1_RXD
    },
    { // SSP2/I2S2
      {GPIO_CNL_H_GPP_D5, GpioPadModeNative1}, // SSP2_SFRM
      {GPIO_CNL_H_GPP_D6, GpioPadModeNative1}, // SSP2_TXD
      {GPIO_CNL_H_GPP_D7, GpioPadModeNative1}, // SSP2_RXD
      {GPIO_CNL_H_GPP_D8, GpioPadModeNative1}  // SSP2_SCLK
    }
  };
  
  /**
    This function provides SSP/I2S interface pins
  
    @param[in]  SspInterfaceNumber       SSP/I2S interface
  
    @param[out] NativePinsTable          Table with pins
  **/
  VOID
  GpioGetHdaSspPins (
    IN  UINT32                      SspInterfaceNumber,
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
    )
  {
    if (IsPchLp ()) {
      if (SspInterfaceNumber < ARRAY_SIZE (mPchLpHdaSspInterfaceGpio)) {
        *NativePinsTable = mPchLpHdaSspInterfaceGpio[SspInterfaceNumber];
        return;
      }
    } else {
      if (SspInterfaceNumber < ARRAY_SIZE (mPchHHdaSspInterfaceGpio)) {
        *NativePinsTable = mPchHHdaSspInterfaceGpio[SspInterfaceNumber];
        return;
      }
    }
    *NativePinsTable = NULL;
    ASSERT (FALSE);
  }
  
  //
  // GPIO Pin for HD Audio SSP_MCLK/I2S_MCLK
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaSspMasterClockGpio = {GPIO_CNL_LP_GPP_D23, GpioPadModeNative1};
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaSspMasterClockGpio = {GPIO_CNL_H_GPP_B11, GpioPadModeNative1};
  
  /**
    This function sets HDA SSP Master Clock into native mode
  
    @param[in]  none
  
    @retval Status
  **/
  EFI_STATUS
  GpioEnableHdaSspMasterClock (
    VOID
    )
  {
    if (IsPchLp ()) {
      return GpioSetPadMode (mPchLpHdaSspMasterClockGpio.Pad, mPchLpHdaSspMasterClockGpio.Mode);
    } else {
      return GpioSetPadMode (mPchHHdaSspMasterClockGpio.Pad, mPchHHdaSspMasterClockGpio.Mode);
    }
  }
  
  //
  // GPIO pins for HD Audio SoundWire interface [SNDW number][pin: CLK/DATA]
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaSndwGpio[][PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS] =
  {
    { // SNDW1
      {GPIO_CNL_LP_HDA_RSTB,  GpioPadModeNative3},// SNDW1_CLK
      {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative3} // SNDW1_DATA
    },
    { // SNDW2
      {GPIO_CNL_LP_SSP1_SFRM, GpioPadModeNative2},// SNDW2_CLK
      {GPIO_CNL_LP_SSP1_TXD,  GpioPadModeNative2} // SNDW2_DATA
    },
    { // SNDW3
      {GPIO_CNL_LP_GPP_D17,   GpioPadModeNative2},// SNDW3_CLK
      {GPIO_CNL_LP_GPP_D18,   GpioPadModeNative2} // SNDW3_DATA
    },
    { // SNDW4
      {GPIO_CNL_LP_GPP_D19,   GpioPadModeNative2},// SNDW4_CLK
      {GPIO_CNL_LP_GPP_D20,   GpioPadModeNative2} // SNDW4_DATA
    }
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaSndwGpio[][PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS] =
  {
    { // SNDW1
      {GPIO_CNL_H_HDA_RSTB,  GpioPadModeNative3},// SNDW1_CLK
      {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative3} // SNDW1_DATA
    },
    { // SNDW2
      {GPIO_CNL_H_SSP1_SFRM, GpioPadModeNative2},// SNDW2_CLK
      {GPIO_CNL_H_SSP1_TXD,  GpioPadModeNative2} // SNDW2_DATA
    },
    { // SNDW3
      {GPIO_CNL_H_GPP_D17,   GpioPadModeNative2},// SNDW3_CLK
      {GPIO_CNL_H_GPP_D18,   GpioPadModeNative2} // SNDW3_DATA
    },
    { // SNDW4
      {GPIO_CNL_H_GPP_D19,   GpioPadModeNative2},// SNDW4_CLK
      {GPIO_CNL_H_GPP_D20,   GpioPadModeNative2} // SNDW4_DATA
    }
  };
  
  /**
    This function provides SNDW interface pins
  
    @param[in]  SndwInterfaceNumber      SNDWx interface number
  
    @param[out] NativePinsTable          Table with pins
  **/
  VOID
  GpioGetHdaSndwPins (
    IN  UINT32                      SndwInterfaceNumber,
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
    )
  {
    if (IsPchLp ()) {
      if (SndwInterfaceNumber < ARRAY_SIZE (mPchLpHdaSndwGpio)) {
        *NativePinsTable = mPchLpHdaSndwGpio[SndwInterfaceNumber];
        return;
      }
    } else {
      if (SndwInterfaceNumber < ARRAY_SIZE (mPchHHdaSndwGpio)) {
        *NativePinsTable = mPchHHdaSndwGpio[SndwInterfaceNumber];
        return;
      }
    }
    *NativePinsTable = NULL;
    ASSERT (FALSE);
  }
  
  //
  // GPIO pins for SMBUS
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSmbusGpio[PCH_GPIO_SMBUS_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_LP_GPP_C0, GpioPadModeNative1},// SMB_CLK
    {GPIO_CNL_LP_GPP_C1, GpioPadModeNative1} // SMB_DATA
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSmbusGpio[PCH_GPIO_SMBUS_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_H_GPP_C0, GpioPadModeNative1}, // SMB_CLK
    {GPIO_CNL_H_GPP_C1, GpioPadModeNative1}  // SMB_DATA
  };
  
  /**
    This function provides SMBUS interface pins
  
    @param[out] NativePinsTable          Table with pins
  **/
  VOID
  GpioGetSmbusPins (
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
    )
  {
    if (IsPchLp ()) {
      *NativePinsTable = mPchLpSmbusGpio;
    } else {
      *NativePinsTable = mPchHSmbusGpio;
    }
  }
  
  //
  // SMBUS Alert pin
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSmbusAlertGpio = {GPIO_CNL_LP_GPP_C2,  GpioPadModeNative1};
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSmbusAlertGpio = {GPIO_CNL_H_GPP_C2,  GpioPadModeNative1};
  
  /**
    This function sets SMBUS ALERT pin into native mode
  
    @param[in]  none
  
    @retval Status
  **/
  EFI_STATUS
  GpioEnableSmbusAlert (
    VOID
    )
  {
    GPIO_PAD_NATIVE_FUNCTION SmbusAlertGpio;
  
    if (IsPchLp ()) {
      SmbusAlertGpio = mPchLpSmbusAlertGpio;
    } else {
      SmbusAlertGpio = mPchHSmbusAlertGpio;
    }
  
    return GpioSetPadMode (SmbusAlertGpio.Pad, SmbusAlertGpio.Mode);
  }
  
  //
  // SATADevSlpPin to GPIO pin mapping
  // SATA_DEVSLP_x -> GPIO pin y
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSataDevSlpPinToGpioMap[] =
  {
    {GPIO_CNL_LP_GPP_E4, GpioPadModeNative1},
    {GPIO_CNL_LP_GPP_E5, GpioPadModeNative1},
    {GPIO_CNL_LP_GPP_E6, GpioPadModeNative1}
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSataDevSlpPinToGpioMap[] =
  {
    {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F7, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F8, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F9, GpioPadModeNative1}
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata1DevSlpPinToGpioMap[] =
  {
  /// @todo SERVER- update for SATA 1
    {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F7, GpioPadModeNative1}
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata2DevSlpPinToGpioMap[] =
  {
  /// @todo SERVER- update for SATA 2
    {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F7, GpioPadModeNative1}
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata3DevSlpPinToGpioMap[] =
  {
  /// @todo SERVER- update for SATA 3
    {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_F7, GpioPadModeNative1}
  };
  
  /**
    This function provides SATA DevSlp pin data
  
    @param[in]  SataCtrlIndex       SATA controller index
    @param[in]  SataPort            SATA port number
    @param[out] NativePin           SATA DevSlp pin
  **/
  VOID
  GpioGetSataDevSlpPin (
    IN  UINT32                    SataCtrlIndex,
    IN  UINTN                     SataPort,
    OUT GPIO_PAD_NATIVE_FUNCTION  *NativePin
    )
  {
    if (IsCdfPch ()) {
      if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
        if (SataPort < ARRAY_SIZE (mCdfPchSata1DevSlpPinToGpioMap)) {
          *NativePin = mCdfPchSata1DevSlpPinToGpioMap[SataPort];
          return;
        }
      } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
        if (SataPort < ARRAY_SIZE (mCdfPchSata2DevSlpPinToGpioMap)) {
          *NativePin = mCdfPchSata2DevSlpPinToGpioMap[SataPort];
          return;
        }
      } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
        if (SataPort < ARRAY_SIZE (mCdfPchSata3DevSlpPinToGpioMap)) {
          *NativePin = mCdfPchSata3DevSlpPinToGpioMap[SataPort];
          return;
        }
      }
    } else {
      if (IsPchLp ()) {
        if (SataPort < ARRAY_SIZE (mPchLpSataDevSlpPinToGpioMap)) {
          *NativePin = mPchLpSataDevSlpPinToGpioMap[SataPort];
          return;
        }
      } else {
        if (SataPort < ARRAY_SIZE (mPchHSataDevSlpPinToGpioMap)) {
          *NativePin = mPchHSataDevSlpPinToGpioMap[SataPort];
          return;
        }
      }
    }
    *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
    ASSERT (FALSE);
  }
  
  //
  // SATA reset port to GPIO pin mapping
  // SATAGP_x -> GPIO pin y
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSataGpToGpioMap[] =
  {
    {GPIO_CNL_LP_GPP_E0, GpioPadModeNative2},
    {GPIO_CNL_LP_GPP_E1, GpioPadModeNative2},
    {GPIO_CNL_LP_GPP_E2, GpioPadModeNative2}
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSataGpToGpioMap[]  =
  {
    {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F2, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F3, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F4, GpioPadModeNative2}
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata1GpToGpioMap[]  =
  {
  /// @todo SERVER- update for SATA 1
    {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F2, GpioPadModeNative2}
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata2GpToGpioMap[]  =
  {
  /// @todo SERVER- update for SATA 2
    {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F2, GpioPadModeNative2}
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata3GpToGpioMap[]  =
  {
  /// @todo SERVER- update for SATA 3
    {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
    {GPIO_CNL_H_GPP_F2, GpioPadModeNative2}
  };
  
  /**
    This function provides SATA GP pin data
  
    @param[in]  SataCtrlIndex       SATA controller index
    @param[in]  SataPort            SATA port number
    @param[out] NativePin           SATA GP pin
  **/
  VOID
  GpioGetSataGpPin (
    IN  UINT32                    SataCtrlIndex,
    IN  UINTN                     SataPort,
    OUT GPIO_PAD_NATIVE_FUNCTION  *NativePin
    )
  {
    if (IsCdfPch ()) {
      if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
        if (SataPort < ARRAY_SIZE (mCdfPchSata1GpToGpioMap)) {
          *NativePin = mCdfPchSata1GpToGpioMap[SataPort];
          return;
        }
      } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
        if (SataPort < ARRAY_SIZE (mCdfPchSata2GpToGpioMap)) {
          *NativePin = mCdfPchSata2GpToGpioMap[SataPort];
          return;
        }
      } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
        if (SataPort < ARRAY_SIZE (mCdfPchSata3GpToGpioMap)) {
          *NativePin = mCdfPchSata3GpToGpioMap[SataPort];
          return;
        }
      }
    } else {
      if (IsPchLp ()) {
        if (SataPort < ARRAY_SIZE (mPchLpSataGpToGpioMap)) {
          *NativePin = mPchLpSataGpToGpioMap[SataPort];
          return;
        }
      } else {
        if (SataPort < ARRAY_SIZE (mPchHSataGpToGpioMap)) {
          *NativePin = mPchHSataGpToGpioMap[SataPort];
          return;
        }
      }
    }
    *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
    ASSERT (FALSE);
  }
  
  //
  // SATA LED pin
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSataLedGpio = {GPIO_CNL_LP_GPP_E8, GpioPadModeNative1};
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSataLedGpio = {GPIO_CNL_H_GPP_E8, GpioPadModeNative1};
  
  /**
    This function sets SATA LED pin into native mode. SATA LED indicates
    SATA controller activity
  
    @param[in]  none
  
    @retval Status
  **/
  EFI_STATUS
  GpioEnableSataLed (
    VOID
    )
  {
    GPIO_PAD_NATIVE_FUNCTION  SataLedGpio;
  
    if (IsPchLp ()) {
      SataLedGpio = mPchLpSataLedGpio;
    } else {
      SataLedGpio = mPchHSataLedGpio;
    }
  
    return GpioSetPadMode (SataLedGpio.Pad, SataLedGpio.Mode);
  }
  
  //
  // USB2 OC pins
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpUsbOcGpioPins[] =
  {
    {GPIO_CNL_LP_GPP_E9,  GpioPadModeNative1},// USB_OC_0
    {GPIO_CNL_LP_GPP_E10, GpioPadModeNative1},// USB_OC_1
    {GPIO_CNL_LP_GPP_E11, GpioPadModeNative1},// USB_OC_2
    {GPIO_CNL_LP_GPP_E12, GpioPadModeNative1} // USB_OC_3
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHUsbOcGpioPins[] =
  {
    {GPIO_CNL_H_GPP_E9,  GpioPadModeNative1},// USB_OC_0
    {GPIO_CNL_H_GPP_E10, GpioPadModeNative1},// USB_OC_1
    {GPIO_CNL_H_GPP_E11, GpioPadModeNative1},// USB_OC_2
    {GPIO_CNL_H_GPP_E12, GpioPadModeNative1},// USB_OC_3
    {GPIO_CNL_H_GPP_F15, GpioPadModeNative1},// USB_OC_4
    {GPIO_CNL_H_GPP_F16, GpioPadModeNative1},// USB_OC_5
    {GPIO_CNL_H_GPP_F17, GpioPadModeNative1},// USB_OC_6
    {GPIO_CNL_H_GPP_F18, GpioPadModeNative1} // USB_OC_7
  };
  
  /**
    This function enables USB OverCurrent pins by setting
    USB2 OCB pins into native mode
  
    @param[in]  OcPinNumber            USB OC pin number
  
    @retval Status
  **/
  EFI_STATUS
  GpioEnableUsbOverCurrent (
    IN  UINTN   OcPinNumber
    )
  {
    GPIO_PAD_NATIVE_FUNCTION  OcGpio;
  
    if (IsPchLp ()) {
      if (OcPinNumber >= ARRAY_SIZE (mPchLpUsbOcGpioPins)) {
        ASSERT(FALSE);
        return EFI_UNSUPPORTED;
      }
      OcGpio = mPchLpUsbOcGpioPins[OcPinNumber];
    } else {
      if (OcPinNumber >= ARRAY_SIZE (mPchHUsbOcGpioPins)) {
        ASSERT (FALSE);
        return EFI_UNSUPPORTED;
      }
      OcGpio = mPchHUsbOcGpioPins[OcPinNumber];
    }
  
    return GpioSetPadMode (OcGpio.Pad, OcGpio.Mode);
  }
  
  //
  // GPIO pin for PCIE SCRCLKREQB
  // SCRCLKREQB_x -> GPIO pin y
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpPcieSrcClkReqbPinToGpioMap[] =
  {
    {GPIO_CNL_LP_GPP_B5,  GpioPadModeNative1},
    {GPIO_CNL_LP_GPP_B6,  GpioPadModeNative1},
    {GPIO_CNL_LP_GPP_B7,  GpioPadModeNative1},
    {GPIO_CNL_LP_GPP_B8,  GpioPadModeNative1},
    {GPIO_CNL_LP_GPP_B9,  GpioPadModeNative1},
    {GPIO_CNL_LP_GPP_B10, GpioPadModeNative1}
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHPcieSrcClkReqbPinToGpioMap[]  =
  {
    {GPIO_CNL_H_GPP_B5,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_B6,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_B7,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_B8,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_B9,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_B10, GpioPadModeNative1},
    {GPIO_CNL_H_GPP_H0,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_H1,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_H2,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_H3,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_H4,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_H5,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_H6,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_H7,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_H8,  GpioPadModeNative1},
    {GPIO_CNL_H_GPP_H9,  GpioPadModeNative1}
  };
  
  /**
    This function provides PCIe CLKREQ pin data
  
    @param[in]  ClkreqIndex        CLKREQ# number
    @param[out] NativePin          Native pin data
  **/
  VOID
  GpioGetPcieClkReqPin (
    IN  UINT32                      ClkreqIndex,
    OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
    )
  {
    if (IsPchLp ()) {
      if (ClkreqIndex < ARRAY_SIZE (mPchLpPcieSrcClkReqbPinToGpioMap)) {
        *NativePin = mPchLpPcieSrcClkReqbPinToGpioMap[ClkreqIndex];
        return;
      }
    } else {
      if (ClkreqIndex < ARRAY_SIZE (mPchHPcieSrcClkReqbPinToGpioMap)) {
        *NativePin = mPchHPcieSrcClkReqbPinToGpioMap[ClkreqIndex];
        return;
      }
    }
    *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
    ASSERT (FALSE);
  }
  
  //
  // PCHHOTB pin
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpPchHotbPin = {GPIO_CNL_LP_GPP_B23,  GpioPadModeNative2};
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHPchHotbPin = {GPIO_CNL_H_GPP_B23,  GpioPadModeNative2};
  
  /**
    This function sets PCHHOT pin into native mode
  
    @param[in]  none
  
    @retval Status
  **/
  EFI_STATUS
  GpioEnablePchHot (
    VOID
    )
  {
    GPIO_PAD_NATIVE_FUNCTION PchHotbPin;
  
    if (IsPchLp ()) {
      PchHotbPin = mPchLpPchHotbPin;
    } else {
      PchHotbPin = mPchHPchHotbPin;
    }
  
    return GpioSetPadMode (PchHotbPin.Pad, PchHotbPin.Mode);
  }
  
  //
  // VRALERTB pin
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpVrAlertbPin = {GPIO_CNL_LP_GPP_B2, GpioPadModeNative1};
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHVrAlertbPin = {GPIO_CNL_H_GPP_B2, GpioPadModeNative1};
  
  //
  // CPU_C10_GATE pin
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCpuC10GatePin = {GPIO_CNL_LP_GPP_H18, GpioPadModeNative1};
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCpuC10GatePin = {GPIO_CNL_H_GPP_J1, GpioPadModeNative2};
  
  /**
    This function sets VRALERTB pin into native mode
  
    @param[in]  none
  
    @retval Status
  **/
  EFI_STATUS
  GpioEnableVrAlert (
    VOID
    )
  {
    GPIO_PAD_NATIVE_FUNCTION  VrAlertGpio;
  
    if (IsPchLp ()) {
      VrAlertGpio = mPchLpVrAlertbPin;
    } else {
      VrAlertGpio = mPchHVrAlertbPin;
    }
  
    return GpioSetPadMode (VrAlertGpio.Pad, VrAlertGpio.Mode);
  }
  
  /**
  This function sets CPU C10 Gate pins into native mode
  
  @retval Status
  **/
  EFI_STATUS
  GpioEnableCpuC10GatePin (
    VOID
    )
  {
    GPIO_PAD_NATIVE_FUNCTION  CpuC10GateGpio;
  
    if (IsPchLp ()) {
      CpuC10GateGpio = mPchLpCpuC10GatePin;
    } else {
      CpuC10GateGpio = mPchHCpuC10GatePin;
    }
  
    return GpioSetPadMode (CpuC10GateGpio.Pad, CpuC10GateGpio.Mode);
  }
  
  //
  // CPU GP pins
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCpuGpPinMap[PCH_GPIO_CPU_GP_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_LP_GPP_E3, GpioPadModeNative1}, // CPU_GP_0
    {GPIO_CNL_LP_GPP_E7, GpioPadModeNative1}, // CPU_GP_1
    {GPIO_CNL_LP_GPP_B3, GpioPadModeNative1}, // CPU_GP_2
    {GPIO_CNL_LP_GPP_B4, GpioPadModeNative1}, // CPU_GP_3
  };
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCpuGpPinMap[PCH_GPIO_CPU_GP_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_H_GPP_E3, GpioPadModeNative1}, // CPU_GP_0
    {GPIO_CNL_H_GPP_E7, GpioPadModeNative1}, // CPU_GP_1
    {GPIO_CNL_H_GPP_B3, GpioPadModeNative1}, // CPU_GP_2
    {GPIO_CNL_H_GPP_B4, GpioPadModeNative1}, // CPU_GP_3
  };
  
  /**
    This function sets CPU GP pins into native mode
  
    @param[in]  CpuGpPinNum               CPU GP pin number
  
    @retval Status
  **/
  EFI_STATUS
  GpioEnableCpuGpPin (
    IN  UINT32                            CpuGpPinNum
    )
  {
    GPIO_PAD_NATIVE_FUNCTION CpuGpPin;
  
    if (IsPchLp ()) {
      if (CpuGpPinNum >= ARRAY_SIZE (mPchLpCpuGpPinMap)) {
        ASSERT (FALSE);
        return EFI_UNSUPPORTED;
      }
      CpuGpPin = mPchLpCpuGpPinMap[CpuGpPinNum];
    } else {
      if (CpuGpPinNum >= ARRAY_SIZE (mPchHCpuGpPinMap)) {
        ASSERT(FALSE);
        return EFI_UNSUPPORTED;
      }
      CpuGpPin = mPchHCpuGpPinMap[CpuGpPinNum];
    }
  
    return GpioSetPadMode (CpuGpPin.Pad, CpuGpPin.Mode);
  }
  
  //
  // DDSP_HPD pins
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpDdspHpdPins[] =
  {
    {GPIO_CNL_LP_GPP_E13, GpioPadModeNative1},// DDSP_HPD_0
    {GPIO_CNL_LP_GPP_E14, GpioPadModeNative1},// DDSP_HPD_1
    {GPIO_CNL_LP_GPP_E15, GpioPadModeNative1},// DDSP_HPD_2
    {GPIO_CNL_LP_GPP_E16, GpioPadModeNative1} // DDSP_HPD_3
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHDdspHpdPins[] =
  {
    {GPIO_CNL_H_GPP_I0, GpioPadModeNative1},// DDSP_HPD_0
    {GPIO_CNL_H_GPP_I1, GpioPadModeNative1},// DDSP_HPD_1
    {GPIO_CNL_H_GPP_I2, GpioPadModeNative1},// DDSP_HPD_2
    {GPIO_CNL_H_GPP_I3, GpioPadModeNative1} // DDSP_HPD_3
  };
  
  /**
    This function sets DDSP_HPDx pin into native mode
  
    @param[in]  DdspHpdPin     DDSP_HPDx pin
  
    @retval Status
  **/
  EFI_STATUS
  GpioEnableDpHotPlugDetect (
    IN GPIO_DDSP_HPD  DdspHpdPin
    )
  {
    GPIO_PAD_NATIVE_FUNCTION  DdspHpdGpio;
    UINT32                    DdspHpdPinIndex;
  
    if (DdspHpdPin > GpioDdspHpd3) {
      return EFI_UNSUPPORTED;
    }
  
    DdspHpdPinIndex = DdspHpdPin - GpioDdspHpd0;
  
    if (IsPchLp ()) {
      if (DdspHpdPinIndex >= ARRAY_SIZE (mPchLpDdspHpdPins)) {
        goto Error;
      }
      DdspHpdGpio = mPchLpDdspHpdPins[DdspHpdPinIndex];
    } else {
      if (DdspHpdPinIndex >= ARRAY_SIZE (mPchHDdspHpdPins)) {
        goto Error;
      }
      DdspHpdGpio = mPchHDdspHpdPins[DdspHpdPinIndex];
    }
  
    return GpioSetPadMode (DdspHpdGpio.Pad, DdspHpdGpio.Mode);
  Error:
    ASSERT (FALSE);
    return EFI_UNSUPPORTED;
  }
  
  //
  // EDP HPD, VDD and BKLT pins
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpEdpPins[PCH_GPIO_EDP_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_LP_GPP_E17,         GpioPadModeNative1},// EDP_HPD
    {GPIO_CNL_LP_HVMOS_L_VDDEN,   GpioPadModeNative1},// VDDEN
    {GPIO_CNL_LP_HVMOS_L_BKLTEN,  GpioPadModeNative1},// BKLTEN
    {GPIO_CNL_LP_HVMOS_L_BKLTCTL, GpioPadModeNative1} // BKLTCTL
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHEdpPins[PCH_GPIO_EDP_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_H_GPP_I4,  GpioPadModeNative1},// EDP_HPD
    {GPIO_CNL_H_GPP_F19, GpioPadModeNative1},// VDDEN
    {GPIO_CNL_H_GPP_F20, GpioPadModeNative1},// BKLTEN
    {GPIO_CNL_H_GPP_F21, GpioPadModeNative1} // BKLTCTL
  };
  
  /**
    This function provides eDP pins
  
    @param[out] NativePinsTable                Table with pins
    @param[out] NoOfNativePins                 Number of pins
  **/
  VOID
  GpioGetEdpPins (
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
    OUT UINT32                      *NoOfNativePins
    )
  {
    if (IsPchLp ()) {
      *NativePinsTable = mPchLpEdpPins;
      *NoOfNativePins = ARRAY_SIZE (mPchLpEdpPins);
    } else {
      *NativePinsTable = mPchHEdpPins;
      *NoOfNativePins = ARRAY_SIZE (mPchHEdpPins);
    }
  }
  
  //
  // DDPB/C/D/F  CTRLCLK and CTRLDATA pins
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpDdpInterfacePins[PCH_GPIO_DDP_NUMBER_OF_INTERFACES][PCH_GPIO_DDP_NUMBER_OF_PINS] =
  {
    {// DDPB
      {GPIO_CNL_LP_GPP_E18, GpioPadModeNative1},// DDPB_CTRLCLK
      {GPIO_CNL_LP_GPP_E19, GpioPadModeNative1} // DDPB_CTRLDATA
    },
    {// DDPC
      {GPIO_CNL_LP_GPP_E20, GpioPadModeNative1},// DDPC_CTRLCLK
      {GPIO_CNL_LP_GPP_E21, GpioPadModeNative1} // DDPC_CTRLDATA
    },
    {// DDPD
      {GPIO_CNL_LP_GPP_E22, GpioPadModeNative1},// DDPD_CTRLCLK
      {GPIO_CNL_LP_GPP_E23, GpioPadModeNative1} // DDPD_CTRLDATA
    },
    {// DDPF
      {GPIO_CNL_LP_GPP_H16, GpioPadModeNative1},// DDPF_CTRLCLK
      {GPIO_CNL_LP_GPP_H17, GpioPadModeNative1} // DDPF_CTRLDATA
    }
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHDdpInterfacePins[PCH_GPIO_DDP_NUMBER_OF_INTERFACES][PCH_GPIO_DDP_NUMBER_OF_PINS] =
  {
    {// DDPB
      {GPIO_CNL_H_GPP_I5,  GpioPadModeNative1}, // DDPB_CTRLCLK
      {GPIO_CNL_H_GPP_I6,  GpioPadModeNative1}, // DDPB_CTRLDATA
    },
    {// DDPC
      {GPIO_CNL_H_GPP_I7,  GpioPadModeNative1}, // DDPC_CTRLCLK
      {GPIO_CNL_H_GPP_I8,  GpioPadModeNative1}, // DDPC_CTRLDATA
    },
    {// DDPD
      {GPIO_CNL_H_GPP_I9,  GpioPadModeNative1}, // DDPD_CTRLCLK
      {GPIO_CNL_H_GPP_I10, GpioPadModeNative1}, // DDPD_CTRLDATA
    },
    {// DDPF
      {GPIO_CNL_H_GPP_F22, GpioPadModeNative1}, // DDPF_CTRLCLK
      {GPIO_CNL_H_GPP_F23, GpioPadModeNative1}, // DDPF_CTRLDATA
    }
  };
  
  /**
    This function provides DDPx interface pins
  
    @param[in]  DdpInterface   DDPx interface
  
    @param[out] NativePinsTable          Table with pins
  **/
  VOID
  GpioGetDdpPins (
    IN  GPIO_DDP                    DdpInterface,
    OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
    )
  {
    UINT32  DdpInterfaceIndex;
  
    switch (DdpInterface) {
      case GpioDdpB:
      case GpioDdpC:
      case GpioDdpD:
        DdpInterfaceIndex = DdpInterface - GpioDdpB;
        break;
      case GpioDdpF:
        DdpInterfaceIndex = 3;
        break;
      default:
        goto Error;
    }
  
    if (IsPchLp ()) {
      if (DdpInterfaceIndex < ARRAY_SIZE (mPchLpDdpInterfacePins)) {
        *NativePinsTable = mPchLpDdpInterfacePins[DdpInterfaceIndex];
        return;
      }
    } else {
      if (DdpInterfaceIndex < ARRAY_SIZE (mPchHDdpInterfacePins)) {
        *NativePinsTable = mPchHDdpInterfacePins[DdpInterfaceIndex];
        return;
      }
    }
  Error:
    *NativePinsTable = NULL;
    ASSERT(FALSE);
  }
  
  /**
    This function enables CNVi RF Reset pin
  **/
  VOID
  GpioEnableCnviRfResetPin (
    VOID
    )
  {
    EFI_STATUS      Status;
    GPIO_PAD        GpioPad;
    GPIO_PAD_MODE   PadMode;
  
    if (IsPchLp ()) {
      GpioPad = GPIO_CNL_LP_GPP_H1;
      PadMode = GpioPadModeNative3;
    } else {
      GpioPad = GPIO_CNL_H_GPP_D5;
      PadMode = GpioPadModeNative3;
    }
  
    Status = GpioSetPadMode (GpioPad, PadMode);
    ASSERT_EFI_ERROR (Status);
  }
  
  /**
    This function enables CNVi MODEM CLKREQ pin
  **/
  VOID
  GpioEnableCnviModemClkReqPin (
    VOID
    )
  {
    EFI_STATUS      Status;
    GPIO_PAD        GpioPad;
    GPIO_PAD_MODE   PadMode;
  
    if (IsPchLp ()) {
      GpioPad = GPIO_CNL_LP_GPP_H2;
      PadMode = GpioPadModeNative3;
    } else {
      GpioPad = GPIO_CNL_H_GPP_D6;
      PadMode = GpioPadModeNative3;
    }
  
    Status = GpioSetPadMode (GpioPad, PadMode);
    ASSERT_EFI_ERROR (Status);
  }
  
  
  /**
    This function provides CNVi BT interface select pin
  
    @retval GpioPad          GPIO pad for CNVi BT interface select
  **/
  GPIO_PAD
  GpioGetCnviBtIfSelectPin (
    VOID
    )
  {
    if (IsPchLp ()) {
      return GPIO_CNL_LP_VGPIO5;
    } else {
      return GPIO_CNL_H_VGPIO7;
    }
  }
  
  /**
    This function provides CNVi BT Charging pin
  
    @retval GpioPad          GPIO pad for CNVi BT Charging select
  **/
  GPIO_PAD
  GpioGetCnviBtChargingPin (
    VOID
    )
  {
    if (IsPchLp ()) {
      return GPIO_CNL_LP_VGPIO3;
    } else {
      return GPIO_CNL_H_VGPIO3;
    }
  }
  
  /**
    This function provides CNVi A4WP pin
  
    @param[out] GpioNativePad       GPIO native pad for CNVi A4WP
  **/
  VOID
  GpioGetCnviA4WpPin (
    OUT GPIO_PAD_NATIVE_FUNCTION  *GpioNativePad
    )
  {
    GpioNativePad->Mode = GpioPadModeNative1;
    if (IsPchLp ()) {
      GpioNativePad->Pad = GPIO_CNL_LP_GPP_F23;
    } else {
      GpioNativePad->Pad = GPIO_CNL_H_GPP_J11;
    }
  }
  
  /**
    This function provides CNVi BT host wake int pin
  
    @retval GpioPad          GPIO pad BT host wake int
  **/
  GPIO_PAD
  GpioGetCnviBtHostWakeIntPin (
    VOID
    )
  {
    if (IsPchLp ()) {
      return GPIO_CNL_LP_VGPIO4;
    } else {
      return GPIO_CNL_H_VGPIO4;
    }
  }
  
  //
  // CNVi Bluetooth UART pads
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVCnviBtUartGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
  {
    GPIO_CNL_LP_VGPIO6, // vCNV_BT_UART_TXD
    GPIO_CNL_LP_VGPIO7, // vCNV_BT_UART_RXD
    GPIO_CNL_LP_VGPIO8, // vCNV_BT_UART_CTS_B
    GPIO_CNL_LP_VGPIO9  // vCNV_BT_UART_RTS_B
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVCnviBtUartGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
  {
    GPIO_CNL_H_VGPIO8, // vCNV_BT_UART_TXD
    GPIO_CNL_H_VGPIO9, // vCNV_BT_UART_RXD
    GPIO_CNL_H_VGPIO10,// vCNV_BT_UART_CTS_B
    GPIO_CNL_H_VGPIO11 // vCNV_BT_UART_RTS_B
  };
  
  //
  // vUART for Bluetooth
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVUartForCnviBtGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
  {
    GPIO_CNL_LP_VGPIO18, // vUART0_TXD
    GPIO_CNL_LP_VGPIO19, // vUART0_RXD
    GPIO_CNL_LP_VGPIO20, // vUART0_CTS_B
    GPIO_CNL_LP_VGPIO21  // vUART0_RTS_B
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVUartForCnviBtGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
  {
    GPIO_CNL_H_VGPIO20, // vUART0_TXD
    GPIO_CNL_H_VGPIO21, // vUART0_RXD
    GPIO_CNL_H_VGPIO22, // vUART0_CTS_B
    GPIO_CNL_H_VGPIO23  // vUART0_RTS_B
  };
  
  /**
    This function provides CNVi BT UART pins
  
    @param[in]  ConnectionType           CNVi BT UART connection type
    @param[out] VCnviBtUartPad           Table with vCNV_BT_UARTx pads
    @param[out] VCnviBtUartPadMode       vCNV_BT_UARTx pad mode
    @param[out] VUartForCnviBtPad        Table with vUART0 pads
    @param[out] VUartForCnviBtPadMode    vUART0 pad mode
  **/
  VOID
  GpioGetCnviBtUartPins (
    IN  VGPIO_CNVI_BT_UART_CONNECTION_TYPE  ConnectionType,
    OUT GPIO_PAD                            **VCnviBtUartPad,
    OUT GPIO_PAD_MODE                       *VCnviBtUartPadMode,
    OUT GPIO_PAD                            **VUartForCnviBtPad,
    OUT GPIO_PAD_MODE                       *VUartForCnviBtPadMode
    )
  {
    if (IsPchLp ()) {
      *VCnviBtUartPad = mPchLpVCnviBtUartGpioPad;
      *VUartForCnviBtPad = mPchLpVUartForCnviBtGpioPad;
    } else {
      *VCnviBtUartPad = mPchHVCnviBtUartGpioPad;
      *VUartForCnviBtPad = mPchHVUartForCnviBtGpioPad;
    }
  
    switch (ConnectionType) {
      case GpioCnviBtUartToSerialIoUart0:
        *VCnviBtUartPadMode = GpioPadModeNative1;
        *VUartForCnviBtPadMode = GpioPadModeNative1;
        break;
      case GpioCnviBtUartToIshUart0:
        *VCnviBtUartPadMode = GpioPadModeNative2;
        *VUartForCnviBtPadMode = GpioPadModeNative1;
        break;
      case GpioCnviBtUartNotConnected:
      case GpioCnviBtUartToExternalPads:
        *VCnviBtUartPadMode = GpioPadModeGpio;
        *VUartForCnviBtPadMode = GpioPadModeGpio;
        break;
      default:
        ASSERT (FALSE);
        return;
    }
  }
  
  //
  // CNVi Bluetooth UART external pads
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCnviBtUartExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_LP_GPP_C8,  GpioPadModeNative2}, // CNV_BT_UART_0_RXD
    {GPIO_CNL_LP_GPP_C9,  GpioPadModeNative2}, // CNV_BT_UART_0_TXD
    {GPIO_CNL_LP_GPP_C10, GpioPadModeNative2}, // CNV_BT_UART_0_RTS
    {GPIO_CNL_LP_GPP_C11, GpioPadModeNative2}  // CNV_BT_UART_0_CTS
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCnviBtUartExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_H_GPP_C8,  GpioPadModeNative2}, // CNV_BT_UART_0_RXD
    {GPIO_CNL_H_GPP_C9,  GpioPadModeNative2}, // CNV_BT_UART_0_TXD
    {GPIO_CNL_H_GPP_C10, GpioPadModeNative2}, // CNV_BT_UART_0_RTS
    {GPIO_CNL_H_GPP_C11, GpioPadModeNative2}  // CNV_BT_UART_0_CTS
  };
  
  /**
    This function provides CNVi BT UART external pads
  
    @param[out] NativePinsTable          Table with pins
  **/
  VOID
  GpioGetCnviBtUartExternalPins (
    OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
    )
  {
    if (IsPchLp ()) {
      *NativePinsTable = mPchLpCnviBtUartExternalPads;
    } else {
      *NativePinsTable = mPchHCnviBtUartExternalPads;
    }
  }
  
  //
  // CNVi Bluetooth I2S pads
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVCnviBtI2sGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
  {
    GPIO_CNL_LP_VGPIO30, // vCNV_BT_I2S_BCLK
    GPIO_CNL_LP_VGPIO31, // vCNV_BT_I2S_WS_SYNC
    GPIO_CNL_LP_VGPIO32, // vCNV_BT_I2S_SDO
    GPIO_CNL_LP_VGPIO33  // vCNV_BT_I2S_SDI
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVCnviBtI2sGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
  {
    GPIO_CNL_H_VGPIO32, // vCNV_BT_I2S_BCLK
    GPIO_CNL_H_VGPIO33, // vCNV_BT_I2S_WS_SYNC
    GPIO_CNL_H_VGPIO34, // vCNV_BT_I2S_SDO
    GPIO_CNL_H_VGPIO35  // vCNV_BT_I2S_SDI
  };
  
  //
  // vSSP for Bluetooth
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVSspForCnviBtGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
  {
    GPIO_CNL_LP_VGPIO34, // vSSP2_SCLK
    GPIO_CNL_LP_VGPIO35, // vSSP2_SFRM
    GPIO_CNL_LP_VGPIO36, // vSSP2_TXD
    GPIO_CNL_LP_VGPIO37  // vSSP2_RXD
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVSspForCnviBtGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
  {
    GPIO_CNL_H_VGPIO36, // vSSP2_SCLK
    GPIO_CNL_H_VGPIO37, // vSSP2_SFRM
    GPIO_CNL_H_VGPIO38, // vSSP2_TXD
    GPIO_CNL_H_VGPIO39  // vSSP2_RXD
  };
  
  /**
    This function provides CNVi BT I2S pins
  
    @param[in]  ConnectionType          CNVi BT I2S connection type
    @param[out] VCnviBtI2sPad           Table with vCNV_BT_I2Sx pads
    @param[out] VCnviBtI2sPadMode       vCNV_BT_I2Sx pad mode
    @param[out] VSspForCnviBtPad        Table with vSSP2 pads
    @param[out] VSspForCnviBtPadMode    vSSP2 pad mode
  **/
  VOID
  GpioGetCnviBtI2sPins (
    IN  VGPIO_CNVI_BT_I2S_CONNECTION_TYPE  ConnectionType,
    OUT GPIO_PAD                 **VCnviBtI2sPad,
    OUT GPIO_PAD_MODE            *VCnviBtI2sPadMode,
    OUT GPIO_PAD                 **VSspForCnviBtPad,
    OUT GPIO_PAD_MODE            *VSspForCnviBtPadMode
    )
  {
    if (IsPchLp ()) {
      *VCnviBtI2sPad = mPchLpVCnviBtI2sGpioPad;
      *VSspForCnviBtPad = mPchLpVSspForCnviBtGpioPad;
    } else {
      *VCnviBtI2sPad = mPchHVCnviBtI2sGpioPad;
      *VSspForCnviBtPad = mPchHVSspForCnviBtGpioPad;
    }
  
    switch (ConnectionType) {
      case GpioCnviBtI2sToSsp0:
        *VCnviBtI2sPadMode = GpioPadModeNative1;
        *VSspForCnviBtPadMode = GpioPadModeNative1;
        break;
      case GpioCnviBtI2sToSsp1:
        *VCnviBtI2sPadMode = GpioPadModeNative2;
        *VSspForCnviBtPadMode = GpioPadModeNative1;
        break;
      case GpioCnviBtI2sToSsp2:
        *VCnviBtI2sPadMode = GpioPadModeNative3;
        *VSspForCnviBtPadMode = GpioPadModeNative1;
        break;
      case GpioCnviBtI2sNotConnected:
      case GpioCnviBtI2sToExternalPads:
        *VCnviBtI2sPadMode = GpioPadModeGpio;
        *VSspForCnviBtPadMode = GpioPadModeGpio;
        break;
      default:
        ASSERT (FALSE);
        return;
    }
  }
  
  //
  // CNVi Bluetooth I2S external pads
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCnviBtI2sExternalPads[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_LP_GPP_H0, GpioPadModeNative2}, // CNV_BT_I2S_WS_SYNC
    {GPIO_CNL_LP_GPP_H1, GpioPadModeNative2}, // CNV_BT_I2S_BCLK
    {GPIO_CNL_LP_GPP_H2, GpioPadModeNative2}, // CNV_BT_I2S_SDI
    {GPIO_CNL_LP_GPP_H3, GpioPadModeNative2}  // CNV_BT_I2S_SDO
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCnviBtI2sExternalPads[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_H_GPP_D8, GpioPadModeNative2}, // CNV_BT_I2S_WS_SYNC
    {GPIO_CNL_H_GPP_D5, GpioPadModeNative2}, // CNV_BT_I2S_BCLK
    {GPIO_CNL_H_GPP_D6, GpioPadModeNative2}, // CNV_BT_I2S_SDI
    {GPIO_CNL_H_GPP_D7, GpioPadModeNative2}  // CNV_BT_I2S_SDO
  };
  
  /**
    This function provides CNVi BT I2S external pads
  
    @param[out] NativePinsTable          Table with pins
  **/
  VOID
  GpioGetCnviBtI2sExternalPins (
    OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
    )
  {
    if (IsPchLp ()) {
      *NativePinsTable = mPchLpCnviBtI2sExternalPads;
    } else {
      *NativePinsTable = mPchHCnviBtI2sExternalPads;
    }
  }
  
  //
  // CNVi MFUART1 pads
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
  {
    GPIO_CNL_LP_VGPIO10, // vCNV_MFUART1_TXD
    GPIO_CNL_LP_VGPIO11, // vCNV_MFUART1_RXD
    GPIO_CNL_LP_VGPIO12, // vCNV_MFUART1_CTS_B
    GPIO_CNL_LP_VGPIO13  // vCNV_MFUART1_RTS_B
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
  {
    GPIO_CNL_H_VGPIO12, // vCNV_MFUART1_TXD
    GPIO_CNL_H_VGPIO13, // vCNV_MFUART1_RXD
    GPIO_CNL_H_VGPIO14, // vCNV_MFUART1_CTS_B
    GPIO_CNL_H_VGPIO15  // vCNV_MFUART1_RTS_B
  };
  
  //
  // vUART for MFUART1
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVUartForCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
  {
    GPIO_CNL_LP_VGPIO22, // vISH_UART0_TXD
    GPIO_CNL_LP_VGPIO23, // vISH_UART0_RXD
    GPIO_CNL_LP_VGPIO24, // vISH_UART0_CTS_B
    GPIO_CNL_LP_VGPIO25  // vISH_UART0_RTS_B
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVUartForCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
  {
    GPIO_CNL_H_VGPIO24, // vISH_UART0_TXD
    GPIO_CNL_H_VGPIO25, // vISH_UART0_RXD
    GPIO_CNL_H_VGPIO26, // vISH_UART0_CTS_B
    GPIO_CNL_H_VGPIO27  // vISH_UART0_RTS_B
  };
  
  /**
    This function provides CNVi MFUART1 pins
  
    @param[in]  ConnectionType          CNVi MFUART1 connection type
    @param[out] VCnviBtI2sPad           Table with vCNV_MFUART1x pads
    @param[out] VCnviBtI2sPadMode       vCNV_MFUART1x pad mode
    @param[out] VSspForCnviBtPad        Table with vISH_UART0 pads
    @param[out] VSspForCnviBtPadMode    vISH_UART0 pad mode
  **/
  VOID
  GpioGetCnviMfUart1Pins (
    IN  VGPIO_CNVI_MF_UART1_CONNECTION_TYPE  ConnectionType,
    OUT GPIO_PAD                 **VCnviMfUart1Pad,
    OUT GPIO_PAD_MODE            *VCnviMfUart1PadMode,
    OUT GPIO_PAD                 **VUartForCnviMfUart1Pad,
    OUT GPIO_PAD_MODE            *VUartForCnviMfUart1PadMode
    )
  {
    if (IsPchLp ()) {
      *VCnviMfUart1Pad = mPchLpVCnviMfUart1GpioPad;
      *VUartForCnviMfUart1Pad = mPchLpVUartForCnviMfUart1GpioPad;
    } else {
      *VCnviMfUart1Pad = mPchHVCnviMfUart1GpioPad;
      *VUartForCnviMfUart1Pad = mPchHVUartForCnviMfUart1GpioPad;
    }
  
    switch (ConnectionType) {
      case GpioCnviMfUart1ToSerialIoUart2:
        *VCnviMfUart1PadMode = GpioPadModeNative2;
        *VUartForCnviMfUart1PadMode = GpioPadModeNative1;
        break;
      case GpioCnviMfUart1ToIshUart0:
        *VCnviMfUart1PadMode = GpioPadModeNative1;
        *VUartForCnviMfUart1PadMode = GpioPadModeNative1;
        break;
      case GpioCnviMfUart1NotConnected:
      case GpioCnviMfUart1ToExternalPads:
        *VCnviMfUart1PadMode = GpioPadModeGpio;
        *VUartForCnviMfUart1PadMode = GpioPadModeGpio;
        break;
      default:
        ASSERT (FALSE);
        return;
    }
  }
  
  //
  // CNVi MFUART1 external pads
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCnviMfUart1ExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_LP_GPP_C12, GpioPadModeNative3}, // CNV_MFUART1_RXD
    {GPIO_CNL_LP_GPP_C13, GpioPadModeNative3}, // CNV_MFUART1_TXD
    {GPIO_CNL_LP_GPP_C14, GpioPadModeNative3}, // CNV_MFUART1_RTS
    {GPIO_CNL_LP_GPP_C15, GpioPadModeNative3}  // CNV_MFUART1_CTS
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCnviMfUart1ExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_H_GPP_C12, GpioPadModeNative3}, // CNV_MFUART1_RXD
    {GPIO_CNL_H_GPP_C13, GpioPadModeNative3}, // CNV_MFUART1_TXD
    {GPIO_CNL_H_GPP_C14, GpioPadModeNative3}, // CNV_MFUART1_RTS
    {GPIO_CNL_H_GPP_C15, GpioPadModeNative3}  // CNV_MFUART1_CTS
  };
  
  /**
    This function provides CNVi MFUART1 external pads
  
    @param[out] NativePinsTable          Table with pins
  **/
  VOID
  GpioGetCnviMfUart1ExternalPins (
    OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
    )
  {
    if (IsPchLp ()) {
      *NativePinsTable = mPchLpCnviMfUart1ExternalPads;
    } else {
      *NativePinsTable = mPchHCnviMfUart1ExternalPads;
    }
  }
  
  /**
    This function provides CNVi Bluetooth Enable pad
  
    @retval GpioPad           CNVi Bluetooth Enable pad
  **/
  GPIO_PAD
  GpioGetCnviBtEnablePin (
    VOID
    )
  {
    if (IsPchLp ()) {
      return GPIO_CNL_LP_VGPIO0;
    } else {
      return GPIO_CNL_H_VGPIO0;
    }
  }
  
  //
  // CNVi BRI (Bluetooth Radio Interface) and RGI (Radio Generic Interface) buses from Pulsar to CRF (Companion RF)
  //
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCnviBriRgiGpioPad[PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_LP_GPP_F4, GpioPadModeNative1}, // CNV_BRI_DT
    {GPIO_CNL_LP_GPP_F5, GpioPadModeNative1}, // CNV_BRI_RSP
    {GPIO_CNL_LP_GPP_F6, GpioPadModeNative1}, // CNV_RGI_DT
    {GPIO_CNL_LP_GPP_F7, GpioPadModeNative1}  // CNV_RGI_RSP
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCnviBriRgiGpioPad[PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_H_GPP_J4, GpioPadModeNative1}, // CNV_BRI_DT
    {GPIO_CNL_H_GPP_J5, GpioPadModeNative1}, // CNV_BRI_RSP
    {GPIO_CNL_H_GPP_J6, GpioPadModeNative1}, // CNV_RGI_DT
    {GPIO_CNL_H_GPP_J7, GpioPadModeNative1}  // CNV_RGI_RSP
  };
  
  /**
    This function provides CNVi BRI RGI GPIO pads
  
    @param[out] NativePinsTable          Table with pins
  **/
  VOID
  GpioGetCnvBriRgiPins (
    OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
    )
  {
    if (IsPchLp ()) {
      *NativePinsTable = mPchLpCnviBriRgiGpioPad;
    } else {
      *NativePinsTable = mPchHCnviBriRgiGpioPad;
    }
  }
  
  
  /**
    This function sets CNVi WiFi mode
  
    @param[in] Value                CNVi WiFi Mode value
                                    GpioCnviWiFiAuto: WiFi is automatically enabled/disabled by WiFi core
                                    GpioCnviWiFiEnabled: WiFi is enabled regardless of WiFi core decision
    @retval Status
  **/
  EFI_STATUS
  GpioSetCnviWifiMode (
    IN  VGPIO_CNVI_WIFI_MODE  WiFiMode
    )
  {
    EFI_STATUS  Status;
    GPIO_PAD    CnviWifiModePad;
    GPIO_CONFIG PadConfig;
  
    ZeroMem (&PadConfig, sizeof (PadConfig));
  
    PadConfig.PadMode = GpioPadModeGpio;
    PadConfig.Direction = GpioDirOut;
    if (WiFiMode == GpioCnviWiFiEnabled) {
      PadConfig.OutputState = GpioOutHigh;
    } else {
      PadConfig.OutputState = GpioOutLow;
    }
  
    if (IsPchLp ()) {
      CnviWifiModePad = GPIO_CNL_LP_VGPIO2;
    } else {
      CnviWifiModePad = GPIO_CNL_H_VGPIO2;
    }
  
    Status = GpioSetPadConfig (CnviWifiModePad, &PadConfig);
    ASSERT_EFI_ERROR (Status);
  
    return EFI_SUCCESS;
  }
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpImguClkOutGpioPad[SA_GPIO_IMGUCLK_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_LP_GPP_D4,  GpioPadModeNative1}, // IMGCLKOUT_0
    {GPIO_CNL_LP_GPP_H20, GpioPadModeNative1}, // IMGCLKOUT_1
  };
  
  GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHImguClkOutGpioPad[SA_GPIO_IMGUCLK_NUMBER_OF_PINS] =
  {
    {GPIO_CNL_H_GPP_K22, GpioPadModeNative1}, // IMGCLKOUT_0
    {GPIO_CNL_H_GPP_K23, GpioPadModeNative1}, // IMGCLKOUT_1
  };
  
  /**
    This function provides IMGCLKOUT pins
  
    @param[out] NativePinsTable          Table with pins
    @param[out] NoOfNativePins            Number of pins
  **/
  VOID
  GpioGetImgClkOutPins (
    OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable,
    OUT UINT32                   *NoOfNativePins
    )
  {
    if (IsPchLp ()) {
      *NativePinsTable = mPchLpImguClkOutGpioPad;
      *NoOfNativePins = ARRAY_SIZE (mPchLpImguClkOutGpioPad);
    } else {
      *NativePinsTable = mPchHImguClkOutGpioPad;
      *NoOfNativePins = ARRAY_SIZE (mPchHImguClkOutGpioPad);
    }
  }
  
  /**
    This function provides PWRBTN pin
  
    @retval GpioPad          PWRTBTN pin
  **/
  GPIO_PAD
  GpioGetPwrBtnPin (
    VOID
    )
  {
    if (IsPchLp ()) {
      return GPIO_CNL_LP_GPD3;
    } else {
      return GPIO_CNL_H_GPD3;
    }
  }
  
  /**
    This function provides LPC pin
  
    @retval GpioPad          LPC pin
  **/
  GPIO_PAD
  GpioGetLpcPin (
    VOID
    )
  {
    if (PchGetLpcDid () == V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A305_SKU) {
      return GPIO_CNL_H_GPP_A8;
    } else {
      return 0;
    }
  }
  