drivers/i2c/gpiomux: Add chip driver for multiplexed I2C bus

This chip driver adds ACPI identifiers for multiplexed I2C bus that are
selected using GPIO. The multiplexed bus device defines the address
to select the I2C lines. These ACPI identifiers are consumed by the
i2c-mux-gpio kernel driver:
https://www.kernel.org/doc/html/latest/i2c/muxes/i2c-mux-gpio.html

BUG=b:169444894
TEST=Build and boot to OS in waddledee. Ensure that the ACPI identifiers
are added in appropriate context.
Scope (\_SB.PCI0.I2C3.MUX0)
{
    Device (MXA0)
    {
        Method (_STA, 0, NotSerialized)  // _STA: Status
        {
            Return (0x0F)
        }

        Name (_ADR, Zero)  // _ADR: Address
    }
}

Scope (\_SB.PCI0.I2C3.MUX0)
{
    Device (MXA1)
    {
        Method (_STA, 0, NotSerialized)  // _STA: Status
        {
            Return (0x0F)
        }

        Name (_ADR, One)  // _ADR: Address
    }
}

Change-Id: If8b983bc8ce212ce05fe6b7f01a6d9092468e582
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46144
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
Karthikeyan Ramasubramanian 2020-10-07 12:42:44 -06:00 committed by Patrick Georgi
parent cbc29a2160
commit bf089d2a62
4 changed files with 71 additions and 0 deletions

View file

@ -1 +1,2 @@
subdirs-$(CONFIG_DRIVERS_I2C_GPIO_MUX) += mux
subdirs-$(CONFIG_DRIVERS_I2C_GPIO_MUX) += bus

View file

@ -0,0 +1 @@
ramstage-$(CONFIG_DRIVERS_I2C_GPIO_MUX) += bus.c

View file

@ -0,0 +1,60 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <console/console.h>
#include <device/device.h>
#include <device/path.h>
#include <stdlib.h>
#include <string.h>
#include "chip.h"
static const char *i2c_gpiomux_bus_acpi_name(const struct device *dev)
{
static char name[ACPI_NAME_BUFFER_SIZE];
snprintf(name, ACPI_NAME_BUFFER_SIZE, "MXA%01.1X", dev->path.generic.id);
return name;
}
static void i2c_gpiomux_bus_fill_ssdt(const struct device *dev)
{
const char *scope = acpi_device_scope(dev);
const char *path = acpi_device_path(dev);
if (!dev || !dev->enabled || !scope || !path)
return;
/* Device */
acpigen_write_scope(scope);
acpigen_write_device(acpi_device_name(dev));
acpigen_write_STA(acpi_device_status(dev));
acpigen_write_ADR(dev->path.generic.id);
acpigen_pop_len(); /* Device */
acpigen_pop_len(); /* Scope */
printk(BIOS_INFO, "%s: %s at %s\n", path, dev->chip_ops->name, dev_path(dev));
}
static struct device_operations i2c_gpiomux_bus_ops = {
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
.scan_bus = scan_static_bus,
.acpi_name = i2c_gpiomux_bus_acpi_name,
.acpi_fill_ssdt = i2c_gpiomux_bus_fill_ssdt,
};
static void i2c_gpiomux_bus_enable(struct device *dev)
{
if (!dev)
return;
dev->ops = &i2c_gpiomux_bus_ops;
}
struct chip_operations drivers_i2c_gpiomux_bus_ops = {
CHIP_NAME("I2C GPIO MUX Bus Device")
.enable_dev = i2c_gpiomux_bus_enable
};

View file

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __I2C_GPIOMUX_BUS_CHIP_H__
#define __I2C_GPIOMUX_BUS_CHIP_H__
struct drivers_i2c_gpiomux_bus_config {
};
#endif /* __I2C_GPIOMUX_BUS_CHIP_H__ */