ec/google/chromeec: Add driver for i2c_tunnel device under Chrome EC

This change enables support for generating ACPI nodes for I2C tunnel for
any GOOG0012 device that is sitting behind the Chrome EC. It accepts a
config "remote_bus" which allows mainboard to configure the id of the
remote bus that is being tunneled.

BUG=b:154290952
BRANCH=None
TEST=Verified that SSDT node for I2C tunnel behind Chrome EC is
generated correctly.

Signed-off-by: Furquan Shaikh <furquan@google.com>
Change-Id: Icfc0ec3725d7f1d20bcb5cb43a0a23aac72bf4eb
Reviewed-on: https://review.coreboot.org/c/coreboot/+/40515
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
This commit is contained in:
Furquan Shaikh 2020-04-19 17:40:22 -07:00
parent 93193a0f09
commit 38b349cb35
6 changed files with 102 additions and 0 deletions

View File

@ -196,3 +196,9 @@ config EC_GOOGLE_CHROMEEC_SWITCHES
help help
Enable support for Chrome OS mode switches provided by the Chrome OS Enable support for Chrome OS mode switches provided by the Chrome OS
EC. EC.
if EC_GOOGLE_CHROMEEC
source "src/ec/google/chromeec/*/Kconfig"
endif

View File

@ -1,5 +1,7 @@
ifeq ($(CONFIG_EC_GOOGLE_CHROMEEC),y) ifeq ($(CONFIG_EC_GOOGLE_CHROMEEC),y)
subdirs-y += i2c_tunnel
bootblock-$(CONFIG_EC_GOOGLE_CHROMEEC_BOARDID) += ec_boardid.c bootblock-$(CONFIG_EC_GOOGLE_CHROMEEC_BOARDID) += ec_boardid.c
verstage-$(CONFIG_EC_GOOGLE_CHROMEEC_BOARDID) += ec_boardid.c verstage-$(CONFIG_EC_GOOGLE_CHROMEEC_BOARDID) += ec_boardid.c
romstage-$(CONFIG_EC_GOOGLE_CHROMEEC_BOARDID) += ec_boardid.c romstage-$(CONFIG_EC_GOOGLE_CHROMEEC_BOARDID) += ec_boardid.c

View File

@ -0,0 +1,6 @@
config EC_GOOGLE_CHROMEEC_I2C_TUNNEL
bool
depends on HAVE_ACPI_TABLES
help
This enables the Cros EC I2C tunnel driver that is required to fill the
SSDT nodes for the I2C tunnel used by the mainboard.

View File

@ -0,0 +1 @@
ramstage-$(CONFIG_EC_GOOGLE_CHROMEEC_I2C_TUNNEL) += i2c_tunnel.c

View File

@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* This file is part of the coreboot project. */
#ifndef __EC_GOOGLE_CHROMEEC_I2C_TUNNEL__
#define __EC_GOOGLE_CHROMEEC_I2C_TUNNEL__
struct ec_google_chromeec_i2c_tunnel_config {
/* ACPI device name */
const char *name;
/* ACPI _UID */
unsigned int uid;
/* EC I2C bus number we tunnel to on the other side. */
unsigned int remote_bus;
};
#endif /* __EC_GOOGLE_CHROMEEC_I2C_TUNNEL__ */

View File

@ -0,0 +1,71 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* This file is part of the coreboot project. */
#include <arch/acpi_device.h>
#include <arch/acpigen.h>
#include <console/console.h>
#include <device/device.h>
#include <device/path.h>
#include <string.h>
#include "chip.h"
#define CROS_EC_I2C_TUNNEL_HID "GOOG0012"
#define CROS_EC_I2C_TUNNEL_DDN "Cros EC I2C Tunnel"
static void crosec_i2c_tunnel_fill_ssdt(struct device *dev)
{
const char *scope = acpi_device_scope(dev);
struct ec_google_chromeec_i2c_tunnel_config *cfg = dev->chip_info;
struct acpi_dp *dsd;
if (!dev->enabled || !scope || !cfg)
return;
acpigen_write_scope(scope);
acpigen_write_device(acpi_device_name(dev));
acpigen_write_name_string("_HID", CROS_EC_I2C_TUNNEL_HID);
acpigen_write_name_integer("_UID", cfg->uid);
acpigen_write_name_string("_DDN", CROS_EC_I2C_TUNNEL_DDN);
acpigen_write_STA(acpi_device_status(dev));
dsd = acpi_dp_new_table("_DSD");
acpi_dp_add_integer(dsd, "google,remote-bus", cfg->remote_bus);
acpi_dp_write(dsd);
acpigen_pop_len(); /* Device */
acpigen_pop_len(); /* Scope */
printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev), CROS_EC_I2C_TUNNEL_DDN,
dev_path(dev));
}
static const char *crosec_i2c_tunnel_acpi_name(const struct device *dev)
{
struct ec_google_chromeec_i2c_tunnel_config *cfg = dev->chip_info;
static char name[5];
if (cfg->name)
return cfg->name;
snprintf(name, sizeof(name), "TUN%X", dev->path.generic.id);
return name;
}
static struct device_operations crosec_i2c_tunnel_ops = {
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
.acpi_name = crosec_i2c_tunnel_acpi_name,
.acpi_fill_ssdt = crosec_i2c_tunnel_fill_ssdt,
.scan_bus = scan_static_bus,
};
static void crosec_i2c_tunnel_enable(struct device *dev)
{
dev->ops = &crosec_i2c_tunnel_ops;
}
struct chip_operations ec_google_chromeec_i2c_tunnel_ops = {
CHIP_NAME("CrosEC I2C Tunnel Device")
.enable_dev = crosec_i2c_tunnel_enable
};