mb/google/fatcat: Add Intel Touch support for touchscreen and touchpad

This commit introduces support for touch functionalities on the
Google Fatcat board( Please see docu # 818597). Changes include:

- Configuration for building with the THC driver
- Support for touchscreen devices in both THC-I2C and THC-SPI modes
  - Rework is necessary for touchscreen use in THC-SPI mode on Fatcat
    board
  - The ELAN BOM37A device is supported in THC-I2C mode
  - The ELAN BOM36 device is supported in THC-SPI mode
- Support for the HYNITRON HFW68H touchpad device in THC-I2C mode
  - A rework is required to switch the interrupt pad from GPP_A13 to
    GPP_F18 for touchpad use in THC-I2C mode
- Introduction of variant-specific touch.h header file
- Wake support from S0ix state for both touchscreen and touchpad
  across multiple modes: LPSS-I2C, THC-I2C, and THC-SPI
- PMC GPE DW0 is reconfigured to GPP_F for Touchpad in LPSS mode in
  variant.c for wake support

BUG=none
TEST=
1. Set the CBI firmware configuration for touchscreen to
   TOUCHSCREEN_LPSS_I2C and/or TOUCHPAD to TOUCHPAD_LPSS_I2C
2. Check the ACPI objects are generated in SSDT
3. The devices should be enumerated under the /sys/class/hidraw
   directory
4. The Touchscreen and/or touchpad should function properly
   The cursor on the screen should move accordingly
5. Test wake from S0ix state via touchscreen and touchpad inputs
6. Repeat the above for the THC CBI configurations:
   touchscreen: TOUCHSCREEN_THC_I2C
   touchpad: TOUCHPAD_THC_I2C

Signed-off-by: Cliff Huang <cliff.huang@intel.com>
Change-Id: I865dbb9eed648c8f35c7f469b27a13be993ff479
Reviewed-on: https://review.coreboot.org/c/coreboot/+/85200
Reviewed-by: Kapil Porwal <kapilporwal@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Cliff Huang 2024-11-19 15:17:17 -08:00 committed by Matt DeVillier
commit 6e529e7c06
5 changed files with 182 additions and 16 deletions

View file

@ -60,6 +60,7 @@ config BOARD_GOOGLE_MODEL_FATCAT
select BOARD_GOOGLE_BASEBOARD_FATCAT
select DRIVERS_GENERIC_BAYHUB_LV2
select DRIVERS_GENERIC_MAX98357A
select DRIVERS_INTEL_TOUCH
config BOARD_GOOGLE_FATCAT
select BOARD_GOOGLE_MODEL_FATCAT

View file

@ -351,6 +351,8 @@ static const struct pad_config touchscreen_disable_pads[] = {
PAD_NC(GPP_E17, NONE),
/* GPP_E18: THC0_SPI1_INT_N_TCH_PNL1 */
PAD_NC(GPP_E18, NONE),
/* GPP_VGPIO3_THC0: THC0_WOT */
PAD_NC(GPP_VGPIO3_THC0, NONE),
};
static const struct pad_config touchscreen_lpss_i2c_enable_pads[] = {
@ -370,6 +372,8 @@ static const struct pad_config touchscreen_lpss_i2c_enable_pads[] = {
PAD_NC(GPP_E17, NONE),
/* GPP_E18: THC0_SPI1_INT_N_TCH_PNL1 */
PAD_CFG_GPI_APIC(GPP_E18, NONE, PLTRST, LEVEL, NONE),
/* GPP_VGPIO3_THC0: THC0_WOT */
PAD_NC(GPP_VGPIO3_THC0, NONE),
};
static const struct pad_config touchscreen_thc_i2c_enable_pads[] = {
@ -388,7 +392,10 @@ static const struct pad_config touchscreen_thc_i2c_enable_pads[] = {
/* GPP_E17: THC0_SPI1_CS0_N_TCH_PNL1 */
PAD_NC(GPP_E17, NONE),
/* GPP_E18: THC0_SPI1_INT_N_TCH_PNL1 */
PAD_CFG_GPI_APIC(GPP_E18, NONE, PLTRST, LEVEL, NONE),
/* NOTE: this SPI INT NF is also used in THC-I2C mode */
PAD_CFG_NF(GPP_E18, NONE, DEEP, NF3),
/* GPP_VGPIO3_THC0: THC0_WOT */
PAD_NC(GPP_VGPIO3_THC0, NONE),
};
static const struct pad_config touchscreen_gspi_enable_pads[] = {
@ -407,7 +414,9 @@ static const struct pad_config touchscreen_gspi_enable_pads[] = {
/* GPP_E17: THC0_SPI1_CS0_N_TCH_PNL1 NF5: GSPI0 */
PAD_CFG_NF(GPP_E17, NONE, DEEP, NF5),
/* GPP_E18: THC0_SPI1_INT_N_TCH_PNL1 */
PAD_CFG_GPI_APIC(GPP_E18, NONE, PLTRST, EDGE_SINGLE, INVERT)
PAD_CFG_GPI_APIC(GPP_E18, NONE, PLTRST, EDGE_SINGLE, INVERT),
/* GPP_VGPIO3_THC0: THC0_WOT */
PAD_NC(GPP_VGPIO3_THC0, NONE),
};
static const struct pad_config touchscreen_thc_spi_enable_pads[] = {
@ -428,6 +437,8 @@ static const struct pad_config touchscreen_thc_spi_enable_pads[] = {
PAD_CFG_NF(GPP_E17, NONE, DEEP, NF3),
/* GPP_E18: THC0_SPI1_INT_N_TCH_PNL1 NF3: THC HID-SPI */
PAD_CFG_NF(GPP_E18, NONE, DEEP, NF3),
/* GPP_VGPIO3_THC0: THC0_WOT */
PAD_NC(GPP_VGPIO3_THC0, NONE),
};
static const struct pad_config touchpad_thc_i2c_enable_pads[] = {
@ -435,8 +446,12 @@ static const struct pad_config touchpad_thc_i2c_enable_pads[] = {
PAD_CFG_NF(GPP_F12, NONE, DEEP, NF1),
/* GPP_F13: NF1: THC_I2C1_SDA */
PAD_CFG_NF(GPP_F13, NONE, DEEP, NF1),
/* GPP_F18: NF3: THC1_INT_N */
PAD_CFG_NF(GPP_F18, NONE, DEEP, NF3)
/* GPP_F18: TCH_PAD_INT_N */
/* NOTE: this SPI INT NF is also used in THC-I2C mode */
/* NOTE: require rework to switch from GPP_A13 to GPP_F18 */
PAD_CFG_NF(GPP_F18, NONE, DEEP, NF3),
/* GPP_VGPIO3_THC1: THC1_WOT */
PAD_NC(GPP_VGPIO3_THC1, NONE),
};
static const struct pad_config touchpad_lpss_i2c_enable_pads[] = {
@ -445,7 +460,10 @@ static const struct pad_config touchpad_lpss_i2c_enable_pads[] = {
/* GPP_F13: THC_I2C1_SDA_TCH_PAD */
PAD_CFG_NF(GPP_F13, NONE, DEEP, NF8),
/* GPP_F18: TCH_PAD_INT_N */
PAD_CFG_GPI_APIC(GPP_F18, NONE, PWROK, LEVEL, INVERT),
/* NOTE: require rework to switch from GPP_A13 to GPP_F18 */
PAD_CFG_GPI_APIC(GPP_F18, NONE, PLTRST, LEVEL, INVERT),
/* GPP_VGPIO3_THC1: THC1_WOT */
PAD_NC(GPP_VGPIO3_THC1, NONE),
};
static const struct pad_config touchpad_i2c_disable_pads[] = {
@ -454,7 +472,20 @@ static const struct pad_config touchpad_i2c_disable_pads[] = {
/* GPP_F13: THC_I2C1_SDA_TCH_PAD */
PAD_NC(GPP_F13, NONE),
/* GPP_F18: TCH_PAD_INT_N */
/* NOTE: require rework to switch from GPP_A13 to GPP_F18 */
PAD_NC(GPP_F18, NONE),
/* GPP_VGPIO3_THC1: THC1_WOT */
PAD_NC(GPP_VGPIO3_THC1, NONE),
};
static const struct pad_config thc0_enable_wake[] = {
/* GPP_VGPIO3_THC0: THC0_WOT */
PAD_CFG_GPI_APIC_DRIVER(GPP_VGPIO3_THC0, NONE, PLTRST, LEVEL, NONE),
};
static const struct pad_config thc1_enable_wake[] = {
/* GPP_VGPIO3_THC1: THC1_WOT */
PAD_CFG_GPI_APIC_DRIVER(GPP_VGPIO3_THC1, NONE, PLTRST, LEVEL, NONE),
};
static const struct pad_config ish_disable_pads[] = {
@ -558,6 +589,8 @@ void fw_config_configure_pre_mem_gpio(void)
void fw_config_gpio_padbased_override(struct pad_config *padbased_table)
{
const struct soc_intel_pantherlake_config *config = config_of_soc();
if (!fw_config_is_provisioned()) {
printk(BIOS_WARNING, "FW_CONFIG is not provisioned, Exiting\n");
return;
@ -620,23 +653,31 @@ void fw_config_gpio_padbased_override(struct pad_config *padbased_table)
else
GPIO_PADBASED_OVERRIDE(padbased_table, x1slot_pads);
if (fw_config_probe(FW_CONFIG(TOUCHPAD, TOUCHPAD_LPSS_I2C)))
if (fw_config_probe(FW_CONFIG(TOUCHPAD, TOUCHPAD_LPSS_I2C))) {
GPIO_PADBASED_OVERRIDE(padbased_table, touchpad_lpss_i2c_enable_pads);
else if (fw_config_probe(FW_CONFIG(TOUCHPAD, TOUCHPAD_THC_I2C)))
} else if (fw_config_probe(FW_CONFIG(TOUCHPAD, TOUCHPAD_THC_I2C))) {
GPIO_PADBASED_OVERRIDE(padbased_table, touchpad_thc_i2c_enable_pads);
else
if (config->thc_wake_on_touch[1])
GPIO_PADBASED_OVERRIDE(padbased_table, thc1_enable_wake);
} else {
GPIO_PADBASED_OVERRIDE(padbased_table, touchpad_i2c_disable_pads);
}
if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_LPSS_I2C)))
if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_LPSS_I2C))) {
GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_lpss_i2c_enable_pads);
else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C)))
} else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C))) {
GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_thc_i2c_enable_pads);
else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_GSPI)))
if (config->thc_wake_on_touch[0])
GPIO_PADBASED_OVERRIDE(padbased_table, thc0_enable_wake);
} else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_GSPI))) {
GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_gspi_enable_pads);
else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI)))
} else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI))) {
GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_thc_spi_enable_pads);
else
if (config->thc_wake_on_touch[0])
GPIO_PADBASED_OVERRIDE(padbased_table, thc0_enable_wake);
} else {
GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_disable_pads);
}
if (fw_config_probe(FW_CONFIG(ISH, ISH_DISABLE)))
GPIO_PADBASED_OVERRIDE(padbased_table, ish_disable_pads);
@ -646,8 +687,26 @@ void fw_config_gpio_padbased_override(struct pad_config *padbased_table)
/* NOTE: disable PEG (x8 slot) and x4 slot wake for now */
GPIO_PADBASED_OVERRIDE(padbased_table, peg_x4slot_wake_disable_pads);
if (fw_config_probe(FW_CONFIG(FP, FP_PRESENT)))
/*
* *=========================================================================*
* | userage | GPP_E17 |
* *=========================================================================*
* | touchscreen in THC-SPI (with rework) | NF3: THC HID-SPI CS0 |
* *---------------------------------------*---------------------------------*
* | touchscreen in gSPI (with rework) | NF5: GSPI0 CS0 |
* *---------------------------------------*---------------------------------*
* | FPS present (without rework) | NF5: GSPI0 CS0 |
* *---------------------------------------*---------------------------------*
*
* NOTE: 1. CBI selecting TS THC-SPI or GSPI mode implies TS rework is applied for the board.
* 2. CBI selecting TS THC-SPI or TS GSPI with FSP present is invalid case.
*/
if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_GSPI)) ||
fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI))) {
/* board has TS SPI rework and not FPS support */
} else if (fw_config_probe(FW_CONFIG(FP, FP_PRESENT))) {
GPIO_PADBASED_OVERRIDE(padbased_table, fp_enable_pads);
else
} else {
GPIO_PADBASED_OVERRIDE(padbased_table, fp_disable_pads);
}
}

View file

@ -265,6 +265,9 @@ static const struct pad_config gpio_table[] = {
PAD_CFG_NF(GPP_F13, NONE, DEEP, NF8),
/* GPP_F17: Not used */
PAD_CFG_GPI_INT(GPP_F17, NONE, PLTRST, EDGE_BOTH),
/* GPP_F18: TCH_PAD_INT_N */
/* NOTE: require rework to switch from GPP_A13 to GPP_F18 */
PAD_CFG_GPI_APIC(GPP_F18, NONE, PLTRST, LEVEL, INVERT),
/* GPP_F19: GPP_PRIVACY_LED_CAM2 */
PAD_CFG_GPO(GPP_F19, 0, PLTRST),
/* GPP_F20: GPP_PRIVACY_LED_CAM1_CVS_HST_WAKE */

View file

@ -317,13 +317,66 @@ chip soc/intel/pantherlake
device ref iaa off end
device ref thc0 on
register "thc_wake_on_touch[0]" = "true"
probe TOUCHSCREEN TOUCHSCREEN_THC_SPI
probe TOUCHSCREEN TOUCHSCREEN_THC_I2C
# THC0 is function 0; hence it needs to be enabled when THC1 is to be enabled.
probe TOUCHPAD TOUCHPAD_THC_I2C
chip drivers/intel/touch
register "name" = "INTEL_THC0_NAME"
register "mode" = "THC_HID_I2C_MODE"
register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F08)"
register "enable_delay_ms" = "2"
register "enable_off_delay_ms" = "2"
register "wake_on_touch" = "true"
# NOTE: Use GpioInt() in _CRS and does not use GPE.
register "wake_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW_WAKE(GPP_VGPIO3_THC0)"
register "active_ltr" = "1"
register "idle_ltr" = "0"
register "connected_device" = "TH_SENSOR_ELAN"
register "add_acpi_dma_property" = "true"
device generic 0 alias touch_0_i2c_elan on
probe TOUCHSCREEN TOUCHSCREEN_THC_I2C
end
end
chip drivers/intel/touch
register "name" = "INTEL_THC0_NAME"
register "mode" = "THC_HID_SPI_MODE"
register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F08)"
register "enable_delay_ms" = "2"
register "enable_off_delay_ms" = "2"
register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E16)"
register "reset_delay_ms" = "10"
register "reset_off_delay_ms" = "2"
register "wake_on_touch" = "true"
# NOTE: Use GpioInt() in _CRS and does not use GPE.
register "wake_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW_WAKE(GPP_VGPIO3_THC0)"
register "active_ltr" = "1"
register "idle_ltr" = "0"
register "connected_device" = "TH_SENSOR_ELAN"
register "soc_hidspi.write_mode" = "HIDSPI_WRITE_MODE_MULTI_SINGLE_SPI"
register "soc_hidspi.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E16)"
register "add_acpi_dma_property" = "true"
device generic 0 alias touch_0_spi_elan on
probe TOUCHSCREEN TOUCHSCREEN_THC_SPI
end
end
end
device ref thc1 on
register "thc_wake_on_touch[1]" = "true"
probe TOUCHPAD TOUCHPAD_THC_I2C
chip drivers/intel/touch
register "name" = "INTEL_THC1_NAME"
register "mode" = "THC_HID_I2C_MODE"
register "wake_on_touch" = "true"
# NOTE: Use GpioInt() in _CRS and does not use GPE.
register "wake_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW_WAKE(GPP_VGPIO3_THC1)"
register "active_ltr" = "1"
register "idle_ltr" = "0"
register "connected_device" = "TH_SENSOR_HYNITRON"
register "add_acpi_dma_property" = "true"
device generic 0 alias touch_1_i2c_hynitron on end
end
end
device ref tbt_pcie_rp0 on end
@ -811,9 +864,11 @@ chip soc/intel/pantherlake
end # I2C3
device ref i2c4 on
chip drivers/i2c/hid
register "generic.hid" = ""ELAN6918""
register "generic.hid" = ""ELAN9048""
register "generic.desc" = ""ELAN Touchscreen""
register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E18_IRQ)"
# NOTE: pmc_gpe0_dw2 is GPP_E in baseboard devicetree.cb.
register "generic.wake" = "GPE0_DW2_18"
register "generic.probed" = "1"
register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E16)"
register "generic.reset_delay_ms" = "20"
@ -832,6 +887,8 @@ chip soc/intel/pantherlake
register "generic.hid" = ""HFW68H""
register "generic.desc" = ""Hynitron TOUCHPAD""
register "generic.irq" = "ACPI_IRQ_WAKE_LEVEL_LOW(GPP_F18_IRQ)"
# NOTE: pmc_gpe0_dw0 will be overridden to GPP_F in variant.c.
register "generic.wake" = "GPE0_DW0_18"
register "generic.uid" = "5"
register "generic.detect" = "1"
register "hid_desc_reg_offset" = "0x20"

View file

@ -4,6 +4,8 @@
#include <fsp/api.h>
#include <fw_config.h>
#include <sar.h>
#include <soc/gpio_soc_defs.h>
#include <drivers/intel/touch/chip.h>
const char *get_wifi_sar_cbfs_filename(void)
{
@ -25,6 +27,50 @@ void variant_update_soc_chip_config(struct soc_intel_pantherlake_config *config)
config->cnvi_bt_audio_offload = true;
}
}
/* Touchscreen and touchpad WOT support:
* +===================+==================+=================+============================+
* | touchsreen | touchpad | PMC_GPE0_DW0 | WOT |
* +===================+==================+==============================================+
* | THC-SPI/THC-I2C | LPSS-I2C | GPP_F | TS, TP |
* +-------------------+------------------+----------------------------------------------+
* | THC-SPI/THC-I2C | not used or | GPP_A (default) | TS |
* | | with WOT disabled| | |
* +-------------------+------------------+----------------------------------------------+
* | THC-SPI/THC-I2C | THC-I2C | GPP_A (default) | TS, TP |
* +-------------------+------------------+----------------------------------------------+
* | LPSS-SPI/LPSS-I2C | LPSS-I2C | GPP_F | TS via PMC_GPE0_DW2: GPP_E,|
* | | | | TP |
* +-------------------+------------------+----------------------------------------------+
* | LPSS-SPI/LPSS-I2C | not used or | GPP_A (default) | TS via PMC_GPE0_DW2: GPP_E |
* | | with WOT disabled| | |
* +-------------------+------------------+----------------------------------------------+
* | not used | not used or | GPP_A (default) | NA |
* | with WOT disabled | with WOT disabled| | |
* +===================+==================+=================+============================+
*/
if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C))) {
config->thc_mode[0] = THC_HID_I2C_MODE;
} else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI))) {
config->thc_mode[0] = THC_HID_SPI_MODE;
} else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_GSPI))) {
config->serial_io_gspi_mode[PchSerialIoIndexGSPI0] = PchSerialIoPci;
}
if (fw_config_probe(FW_CONFIG(TOUCHPAD, TOUCHPAD_LPSS_I2C))) {
/* touchpad: GPP_F18: GPE0_DW0_18 */
if (config->thc_wake_on_touch[1])
config->pmc_gpe0_dw0 = GPP_F;
} else if (fw_config_probe(FW_CONFIG(TOUCHPAD, TOUCHPAD_THC_I2C))) {
config->thc_mode[1] = THC_HID_I2C_MODE;
if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_NONE)))
/* When THC0 is only enabled due to THC1 is enabled, we force THC0
* to I2C mode so that kernel THC I2C driver will find it and put
* THC0 to low power state because no connected device is found.
*/
config->thc_mode[0] = THC_HID_I2C_MODE;
}
}
void variant_update_soc_memory_init_params(FSPM_UPD *memupd)