From f1690f0ec166c214a2c42acf2d410ea7f35a77f0 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Fri, 8 Feb 2019 16:43:48 -0800 Subject: [PATCH] mb/google/sarien: Support multiple touchscreen at same address The Sarien board may have different touchscreen devices that use the same I2C slave address but have different requirements such as needing a special driver or ACPI configuration. In order to support this the devicetree may be configured with multiple devices at the same address and at boot time the unused devices will be disabled. Because there is no GPIO for selecting the device that is present it can instead be selected with Kconfig, or by setting a VPD key to the HID of the touchscreen device that is present. The default for Sarien devices is to not enable a touchscreen for the OS. The touchscreen selection is currently limited to the Sarien variant but this also adds the touchscreen HID for Arcada to Kconfig so it would not complain about the key not being set. BUG=b:122019253 TEST=This was tested on a Sarien board by adding a second entry to the devicetree at the same address. Without this change the SSDT is not loaded by the kernel because of the address conflict. After this change no touchscreen is enabled by default, but one can be selected with Kconfig or by setting the 'touchscreen_hid' VPD key. Change-Id: I4da12b1de0c551bcd89325fe0d8c66c6ffeb7afc Signed-off-by: Duncan Laurie Reviewed-on: https://review.coreboot.org/c/31295 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/mainboard/google/sarien/Kconfig | 5 ++ .../sarien/variants/sarien/Makefile.inc | 2 +- .../google/sarien/variants/sarien/ramstage.c | 73 +++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/mainboard/google/sarien/variants/sarien/ramstage.c diff --git a/src/mainboard/google/sarien/Kconfig b/src/mainboard/google/sarien/Kconfig index dc8f486104..4aea9f7470 100644 --- a/src/mainboard/google/sarien/Kconfig +++ b/src/mainboard/google/sarien/Kconfig @@ -97,6 +97,11 @@ config DEVICETREE string default "variants/$(CONFIG_VARIANT_DIR)/devicetree.cb" +config TOUCHSCREEN_HID + string "Specify the touchscreen HID enabled for the OS" + default "WCOM48E2" if BOARD_GOOGLE_ARCADA + default "NONE" if BOARD_GOOGLE_SARIEN + config VBOOT select HAS_RECOVERY_MRC_CACHE select MRC_CLEAR_NORMAL_CACHE_ON_RECOVERY_RETRAIN diff --git a/src/mainboard/google/sarien/variants/sarien/Makefile.inc b/src/mainboard/google/sarien/variants/sarien/Makefile.inc index 2bf028eb1f..fa5b2ea36a 100644 --- a/src/mainboard/google/sarien/variants/sarien/Makefile.inc +++ b/src/mainboard/google/sarien/variants/sarien/Makefile.inc @@ -14,6 +14,6 @@ ## bootblock-y += gpio.c -ramstage-y += gpio.c +ramstage-y += gpio.c ramstage.c romstage-y += gpio.c verstage-y += gpio.c diff --git a/src/mainboard/google/sarien/variants/sarien/ramstage.c b/src/mainboard/google/sarien/variants/sarien/ramstage.c new file mode 100644 index 0000000000..ab79678f9a --- /dev/null +++ b/src/mainboard/google/sarien/variants/sarien/ramstage.c @@ -0,0 +1,73 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * This board may have different touchscreen devices that are at the + * same I2C slave address but need different drivers or ACPI configuration. + * + * The default touchscreen to be enabled is specified in Kconfig by the + * ACPI HID of the device. If a board is connected to a different + * touchscreen device it can be enabled in Kconfig or by setting the + * VPD key 'touchscreen_hid'. + */ + +#define TOUCHSCREEN_I2C_ADDR 0x10 +#define TOUCHSCREEN_VPD_KEY "touchscreen_hid" + +static void disable_unused_touchscreen(void *unused) +{ + struct device *i2c0 = PCH_DEV_I2C0; + struct bus *i2c_slaves = i2c0->link_list; + struct device *slave = i2c_slaves->children; + char touchscreen_hid[9] = CONFIG_TOUCHSCREEN_HID; + struct drivers_i2c_hid_config *info; + + /* Look for VPD key that indicates which touchscreen is present */ + if (IS_ENABLED(CONFIG_VPD) && + !vpd_gets(TOUCHSCREEN_VPD_KEY, touchscreen_hid, + ARRAY_SIZE(touchscreen_hid), VPD_ANY)) + printk(BIOS_INFO, "%s: VPD key '%s' not found, default to %s\n", + __func__, TOUCHSCREEN_VPD_KEY, touchscreen_hid); + + /* Go through all I2C slave devices on this bus */ + while (slave) { + /* Find all the I2C slaves with the matching address */ + if (slave->path.type == DEVICE_PATH_I2C && + slave->path.i2c.device == TOUCHSCREEN_I2C_ADDR) { + info = slave->chip_info; + /* Disable all devices except the matching HID */ + if (strncmp(info->generic.hid, touchscreen_hid, + ARRAY_SIZE(touchscreen_hid))) { + printk(BIOS_INFO, "%s: Disable %s\n", __func__, + info->generic.hid); + slave->enabled = 0; + } else { + printk(BIOS_INFO, "%s: Enable %s\n", __func__, + info->generic.hid); + } + } + slave = slave->sibling; + } +} +BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY, + disable_unused_touchscreen, NULL);