acpi_device: Add support for writing ACPI I2C descriptors
Add required definitions to describe an ACPI I2C bus and a method to write the I2cSerialBus() descriptor to the SSDT. This will be used by device drivers to describe their I2C resources to the OS. The devicetree i2c device can supply the address and 7 or 10 bit mode as well as indicate the GPIO controller device, and the bus speed can be fixed or configured by the driver. chip.h: struct drivers_i2c_generic_config { enum i2c_speed bus_speed; }; generic.c: void acpi_fill_ssdt_generator(struct device *dev) { struct drivers_i2c_generic_config *config = dev->chip_info; struct acpi_i2c i2c = { .address = dev->path->i2c.device, .mode_10bit = dev->path.i2c.mode_10bit, .speed = config->bus_speed ? : I2C_SPEED_FAST, .resource = acpi_device_path(dev->bus->dev) }; ... acpi_device_write_i2c(&i2c); ... } devicetree.cb: device pci 15.0 on chip drivers/i2c/generic device i2c 10.0 on end end end SSDT.dsl: I2cSerialBus (0x10, ControllerInitiated, 400000, AddressingMode7Bit, "\\_SB.PCI0.I2C0", 0, ResourceConsumer) Change-Id: I598401ac81a92c72f19da0271af1e218580a6c49 Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: https://review.coreboot.org/14935 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
committed by
Duncan Laurie
parent
cfb6ea7e65
commit
1010b4aeac
@@ -18,6 +18,7 @@
|
||||
#include <arch/acpi_device.h>
|
||||
#include <arch/acpigen.h>
|
||||
#include <device/device.h>
|
||||
#include <device/i2c.h>
|
||||
#include <device/path.h>
|
||||
#if IS_ENABLED(CONFIG_GENERIC_GPIO_LIB)
|
||||
#include <gpio.h>
|
||||
@@ -323,3 +324,60 @@ void acpi_device_write_gpio(const struct acpi_gpio *gpio)
|
||||
/* Fill in GPIO Descriptor Length (account for len word) */
|
||||
acpi_device_fill_len(desc_length);
|
||||
}
|
||||
|
||||
/* ACPI 6.1 section 6.4.3.8.2.1 - I2cSerialBus() */
|
||||
void acpi_device_write_i2c(const struct acpi_i2c *i2c)
|
||||
{
|
||||
void *desc_length, *type_length;
|
||||
|
||||
/* Byte 0: Descriptor Type */
|
||||
acpigen_emit_byte(ACPI_DESCRIPTOR_SERIAL_BUS);
|
||||
|
||||
/* Byte 1+2: Length (filled in later) */
|
||||
desc_length = acpi_device_write_zero_len();
|
||||
|
||||
/* Byte 3: Revision ID */
|
||||
acpigen_emit_byte(ACPI_SERIAL_BUS_REVISION_ID);
|
||||
|
||||
/* Byte 4: Resource Source Index is Reserved */
|
||||
acpigen_emit_byte(0);
|
||||
|
||||
/* Byte 5: Serial Bus Type is I2C */
|
||||
acpigen_emit_byte(ACPI_SERIAL_BUS_TYPE_I2C);
|
||||
|
||||
/*
|
||||
* Byte 6: Flags
|
||||
* [7:2]: 0 => Reserved
|
||||
* [1]: 1 => ResourceConsumer
|
||||
* [0]: 0 => ControllerInitiated
|
||||
*/
|
||||
acpigen_emit_byte(1 << 1);
|
||||
|
||||
/*
|
||||
* Byte 7-8: Type Specific Flags
|
||||
* [15:1]: 0 => Reserved
|
||||
* [0]: 0 => 7bit, 1 => 10bit
|
||||
*/
|
||||
acpigen_emit_word(i2c->mode_10bit);
|
||||
|
||||
/* Byte 9: Type Specific Revision ID */
|
||||
acpigen_emit_byte(ACPI_SERIAL_BUS_REVISION_ID);
|
||||
|
||||
/* Byte 10-11: I2C Type Data Length */
|
||||
type_length = acpi_device_write_zero_len();
|
||||
|
||||
/* Byte 12-15: I2C Bus Speed */
|
||||
acpigen_emit_dword(i2c->speed);
|
||||
|
||||
/* Byte 16-17: I2C Slave Address */
|
||||
acpigen_emit_word(i2c->address);
|
||||
|
||||
/* Fill in Type Data Length */
|
||||
acpi_device_fill_len(type_length);
|
||||
|
||||
/* Byte 18+: ResourceSource */
|
||||
acpigen_emit_string(i2c->resource);
|
||||
|
||||
/* Fill in I2C Descriptor Length */
|
||||
acpi_device_fill_len(desc_length);
|
||||
}
|
||||
|
Reference in New Issue
Block a user