/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <baseboard/gpio.h>
#include <baseboard/variants.h>
#include <commonlib/helpers.h>
#include <soc/gpio.h>
#include <vendorcode/google/chromeos/chromeos.h>

/* Pad configuration in ramstage */
static const struct pad_config override_gpio_table[] = {
	/* GPP_A12 : [NF1: SATAXPCIE1 NF2: SATAGP1 NF4: SRCCLKREQ9B# NF6: USB_C_GPP_A12] ==> KBL_DET(reserve) */
	PAD_NC(GPP_A12, NONE),
	/* GPP_A14 : [NF1: USB_OC1# NF2: DDSP_HPD3 NF4: DISP_MISC3 NF6: USB_C_GPP_A14] ==> NC */
	PAD_NC(GPP_A14, NONE),
	/* GPP_A15 : [NF1: USB_OC2# NF2: DDSP_HPD4 NF4: DISP_MISC4 NF6: USB_C_GPP_A15] ==> NC */
	PAD_NC(GPP_A15, NONE),
	/* GPP_A17 : [NF4: DISP_MISCC NF6: USB_C_GPP_A17] ==> WWAN_TRANSMIT_OFF(WAN_RF_DISABLE_ODL) */
	PAD_CFG_GPO(GPP_A17, 1, DEEP),
	/* GPP_A21 : [NF1: DDPC_CTRLCLK NF6: USB_C_GPP_A21] ==> WWAN_ASPM_EXIT(WWAN_PERST_L) */
	PAD_CFG_GPO(GPP_A21, 1, DEEP),

	/* GPP_D4 : [NF1: IMGCLKOUT0 NF2: BK4 NF5: SBK4 NF6: USB_C_GPP_D4] ==> WWAN_GPS_XMIT_OFF */
	PAD_CFG_GPO(GPP_D4, 0, DEEP),
	/* GPP_D5 : SRCCLKREQ0_L ==> SSD_CLKREQ_ODL */
	PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1),
	/* GPP_D7 : SRCCLKREQ2_L ==> PCIE_CLKREQ_LAN */
	PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1),
	/* GPP_D8 : [NF1: SRCCLKREQ3# NF6: USB_C_GPP_D8] ==> PCH_FP_BOOT0 */
	PAD_CFG_GPO_LOCK(GPP_D8, 0, LOCK_CONFIG),
	/* GPP_D9 : [NF1: ISH_SPI_CS# NF2: DDP3_CTRLCLK NF4: TBT_LSX2_TXD NF5: BSSB_LS2_RX NF6: USB_C_GPP_D9 NF7: GSPI2_CS0#] ==> FP_RST_ODL */
	PAD_CFG_GPO_LOCK(GPP_D9, 0, LOCK_CONFIG),
	/* GPP_D10 : [NF1: ISH_SPI_CLK NF2: DDP3_CTRLDATA NF4: TBT_LSX2_RXD NF5: BSSB_LS2_TX NF6: USB_C_GPP_D10 NF7: GSPI2_CLK] ==> USB_C2_LSX_RX_STRAP(NC) */
	PAD_NC(GPP_D10, NONE),
	/* GPP_D11 : [] ==> EN_FP_POWER*/
	PAD_CFG_GPO_LOCK(GPP_D11, 0, LOCK_CONFIG),
	/* GPP_D15 : ISH_UART0_RTS_L/I2C7B_SDA ==> WWAN_CONFIG_3 */
	PAD_CFG_GPI_LOCK(GPP_D15, NONE, LOCK_CONFIG),
	/* GPP_D16 : ISH_UART0_CTS_L/I2C7B_SCL ==> WWAN_CONFIG_2 */
	PAD_CFG_GPI_LOCK(GPP_D16, NONE, LOCK_CONFIG),
	/* GPP_D18 : UART1_TXD/ISH_UART1_RXD ==> LANLINK_STATUS */
	PAD_CFG_GPI(GPP_D18, NONE, DEEP),
	/* GPP_D19 : [NF1: I2S_MCLK1_OUT NF6: USB_C_GPP_D19] ==> WWAN_FWUPD#(WWAN_RST_L) */
	PAD_CFG_GPO(GPP_D19, 1, DEEP),

	/* GPP_E4 : [NF1: DEVSLP0 NF6: USB_C_GPP_E4 NF7: SRCCLK_OE9#] ==> GSPI_FPMCU_INT_L */
	PAD_CFG_GPI_IRQ_WAKE(GPP_E4, NONE, PWROK, LEVEL, INVERT),
	/* GPP_E5 : [NF1: DEVSLP1 NF6: USB_C_GPP_E5 NF7: SRCCLK_OE6#] ==> WWAN_WAKE# */
	PAD_CFG_GPI_INT(GPP_E5, NONE, PLTRST, EDGE_SINGLE),
	/* GPP_E7 : [NF1: PROC_GP1 NF6: USB_C_GPP_E7] ==> EN_UCAM_PWR*/
	PAD_CFG_GPO(GPP_E7, 1, DEEP),
	/* GPP_E18 : [NF1: DDP1_CTRLCLK NF4: TBT_LSX0_TXD NF5: BSSB_LS0_RX NF6: USB_C_GPP_E18] ==> NC */
	PAD_NC(GPP_E18, NONE),
	/* GPP_E19 : [NF1: DDP1_CTRLDATA NF4: TBT_LSX0_RXD NF5: BSSB_LS0_TX NF6: USB_C_GPP_E19] ==> USB_C0_LSX_RX_STRAP(NC) */
	PAD_NC(GPP_E19, NONE),

	/* GPP_F11 : [NF3: THC1_SPI2_CLK NF4: GSPI1_CLK NF6: USB_C_GPP_F11] ==> GSPI_PCH_CLK_FPMCU_R */
	PAD_CFG_NF_LOCK(GPP_F11, NONE, NF4, LOCK_CONFIG),
	/* GPP_F12 : [NF1: GSXDOUT NF3: THC1_SPI2_IO0 NF4: GSPI1_MOSI NF5: I2C1A_SCL NF6: USB_C_GPP_F12] ==> GSPI_PCH_DO_FPMCU_DI_R */
	PAD_CFG_NF_LOCK(GPP_F12, NONE, NF4, LOCK_CONFIG),
	/* GPP_F13 : [NF1: GSXSLOAD NF3: THC1_SPI2_IO1 NF4: GSPI1_MISIO NF5: I2C1A_SDA NF6: USB_C_GPP_F13] ==> GSPI_PCH_DI_FPMCU_DO */
	PAD_CFG_NF_LOCK(GPP_F13, NONE, NF4, LOCK_CONFIG),
	/* GPP_F15 : [NF1: GSXSRESET# NF3: THC1_SPI2_IO3 NF6: USB_C_GPP_F15] ==> NC */
	PAD_NC(GPP_F15, NONE),
	/* GPP_F16 : [NF1: GSXCLK NF3: THC1_SPI2_CS# NF4: GSPI1_CS0# NF6: USB_C_GPP_F16] ==> GSPI_PCH_CS_FPMCU_R_L */
	PAD_CFG_NF_LOCK(GPP_F16, NONE, NF4, LOCK_CONFIG),
	/* GPP_F19 : SRCCLKREQ6 ==> PCIE_CLKREQ_WWAN */
	PAD_CFG_NF(GPP_F19, NONE, DEEP, NF1),
	/* F21 : [NF1: Reserved NF6: USB_C_GPP_F21] ==> WWAN_OFF#(WWAN_FCPO_L)*/
	PAD_CFG_GPO(GPP_F21, 1, DEEP),
};

/* Early pad configuration in bootblock */
static const struct pad_config early_gpio_table[] = {

	/* F21 : [NF1: Reserved NF6: USB_C_GPP_F21] ==> WWAN_OFF#(WWAN_FCPO_L) */
	PAD_CFG_GPO(GPP_F21, 0, DEEP),
	/* GPP_A21 : [NF1: DDPC_CTRLCLK NF6: USB_C_GPP_A21] ==> WWAN_ASPM_EXIT(WWAN_PERST_L) */
	PAD_CFG_GPO(GPP_A21, 0, DEEP),
	/* GPP_D19 : [NF1: I2S_MCLK1_OUT NF6: USB_C_GPP_D19] ==> WWAM_FWUPD#(WWAN_RST_L) */
	PAD_CFG_GPO(GPP_D19, 0, DEEP),

	/*
	 * FP_RST_ODL comes out of reset as hi-z and does not have an external pull-down.
	 * To ensure proper power sequencing for the FPMCU device, reset signal is driven low
	 * early on in bootblock, followed by enabling of power. Reset signal is deasserted
	 * later on in ramstage. Since reset signal is asserted in bootblock, it results in
	 * FPMCU not working after a S3 resume. This is a known issue.
	 */
	/* GPP_D9 : [NF1: ISH_SPI_CS# NF2: DDP3_CTRLCLK NF4: TBT_LSX2_TXD NF5: BSSB_LS2_RX NF6: USB_C_GPP_D9 NF7: GSPI2_CS0#] ==> FP_RST_ODL */
	PAD_CFG_GPO(GPP_D9, 0, DEEP),
	/* GPP_D11  : [] ==> EN_FP_PWR */
	PAD_CFG_GPO(GPP_D11, 1, DEEP),

	/* GPP_E2  : THC0_SPI1_IO3 ==> GSC_PCH_INT_ODL */
	PAD_CFG_GPI_APIC(GPP_E2, NONE, PLTRST, LEVEL, INVERT),
	/* GPP_E8 : GPP_E8 ==> PCH_WP_OD */
	PAD_CFG_GPI_LOCK(GPP_E8, NONE, LOCK_CONFIG),
	/* GPP_F9 : [NF1: BOOTMPC NF6: USB_C_GPP_F9] ==> SSD_PERST_L */
	PAD_CFG_GPO(GPP_F9, 0, DEEP),
	/* GPP_H8 : [NF1: I2C4_SDA NF2: CNV_MFUART2_RXD NF6: USB_C_GPP_H8] ==> PCH_I2C_GSC_SDA */
	PAD_CFG_NF(GPP_H8, NONE, DEEP, NF1),
	/* GPP_H9 : [NF1: I2C4_SCL NF2: CNV_MFUART2_TXD] ==> PCH_I2C_GSC_SCL */
	PAD_CFG_NF(GPP_H9, NONE, DEEP, NF1),
	/* H10 : UART0_RXD ==> UART_PCH_RX_DBG_TX */
	PAD_CFG_NF(GPP_H10, NONE, PLTRST, NF2),
	/* H11 : UART0_TXD ==> UART_PCH_TX_DBG_RX */
	PAD_CFG_NF(GPP_H11, NONE, PLTRST, NF2),
	/* GPP_S0 : SNDW0_CLL/I2S1_SCLK ==> MEM_CH_SEL */
	PAD_CFG_GPI(GPP_S0, NONE, DEEP),

	/* CPU PCIe vGPIO for RP2 */
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_32, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_33, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_34, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_35, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_36, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_37, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_38, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_39, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_40, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_41, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_42, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_43, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_44, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_45, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_46, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_47, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_72, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_73, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_74, NONE, PLTRST, NF1),
	PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_75, NONE, PLTRST, NF1),
};

static const struct pad_config romstage_gpio_table[] = {
	/* GPP_D9 : [NF1: ISH_SPI_CS# NF2: DDP3_CTRLCLK NF4: TBT_LSX2_TXD NF5: BSSB_LS2_RX NF6: USB_C_GPP_D9 NF7: GSPI2_CS0#] ==> FP_RST_ODL */
	PAD_CFG_GPO(GPP_D9, 0, DEEP),
	/* GPP_D11 : [] ==> EN_FP_PWR */
	PAD_CFG_GPO(GPP_D11, 0, DEEP),

	/* F21 : [NF1: Reserved NF6: USB_C_GPP_F21] ==> WWAN_OFF#(WWAN_FCPO_L) */
	PAD_CFG_GPO(GPP_F21, 1, DEEP),
	/* GPP_A21 : [NF1: DDPC_CTRLCLK NF6: USB_C_GPP_A21] ==> WWAN_ASPM_EXIT(WWAN_PERST_L) */
	PAD_CFG_GPO(GPP_A21, 0, DEEP),
	/* GPP_D19 : [NF1: I2S_MCLK1_OUT NF6: USB_C_GPP_D19] ==> WWAM_FWUPD#(WWAN_RST_L) */
	PAD_CFG_GPO(GPP_D19, 0, DEEP),

	/* GPP_E10 : THC0_SPI1_CS_L/GSPI0_CS0_L ==> MEM_STRAP_3 */
	PAD_CFG_GPI(GPP_E10, NONE, PLTRST),
	/* GPP_E12 : THC0_SPI1_IO1/I2C0A_SDA/GSPI0_MISO ==> MEM_STRAP_1 */
	PAD_CFG_GPI(GPP_E12, NONE, PLTRST),
	/* GPP_E13 : THC0_SPI1_IO0/I2C0A_SCL/GSPI0_MOSI ==> MEM_STRAP_2 */
	PAD_CFG_GPI(GPP_E13, NONE, PLTRST),
	/* GPP_E15 : SRCCLK_OE8_L ==> MEM_STRAP_0 */
	PAD_CFG_GPI(GPP_E15, NONE, PLTRST),
	/* GPP_F7 : [NF6: USB_C_GPP_F7] ==> EN_PP3300_TCHSCR */
	PAD_CFG_GPO(GPP_F7, 1, PLTRST),
	/* GPP_F9 : [NF1: BOOTMPC NF6: USB_C_GPP_F9] ==> SSD_PERST_L */
	PAD_CFG_GPO(GPP_F9, 1, DEEP),
	/* GPP_F17 : [NF3: THC1_SPI2_RST# NF6: USB_C_GPP_F17] ==> TCHSCR_RST_L */
	PAD_CFG_GPO(GPP_F17, 0, DEEP),
	/* GPP_S0 : SNDW0_CLL/I2S1_SCLK ==> MEM_CH_SEL */
	PAD_CFG_GPI(GPP_S0, NONE, DEEP),
};

const struct pad_config *variant_gpio_override_table(size_t *num)
{
	*num = ARRAY_SIZE(override_gpio_table);
	return override_gpio_table;
}

const struct pad_config *variant_early_gpio_table(size_t *num)
{
	*num = ARRAY_SIZE(early_gpio_table);
	return early_gpio_table;
}

const struct pad_config *variant_romstage_gpio_table(size_t *num)
{
	*num = ARRAY_SIZE(romstage_gpio_table);
	return romstage_gpio_table;
}

static const struct cros_gpio cros_gpios[] = {
	CROS_GPIO_REC_AL(CROS_GPIO_VIRTUAL, CROS_GPIO_DEVICE_NAME),
	CROS_GPIO_WP_AH(GPIO_PCH_WP, CROS_GPIO_DEVICE_NAME),
};

DECLARE_CROS_GPIOS(cros_gpios);
