[coreboot-gerrit] Patch set updated for coreboot: acpi_device: Add support for writing ACPI I2C descriptors

Duncan Laurie (dlaurie@google.com) gerrit at coreboot.org
Fri May 27 00:45:47 CEST 2016


Duncan Laurie (dlaurie at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14935

-gerrit

commit 2c7abd002e1d66ebd702f8040b4823ac29e81e5d
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Mon May 9 20:10:47 2016 -0700

    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 at chromium.org>
---
 src/arch/x86/acpi_device.c              | 58 +++++++++++++++++++++++++++++++++
 src/arch/x86/include/arch/acpi_device.h | 27 +++++++++++++++
 src/include/device/i2c.h                | 13 ++++++++
 3 files changed, 98 insertions(+)

diff --git a/src/arch/x86/acpi_device.c b/src/arch/x86/acpi_device.c
index 610b922..3c0230f 100644
--- a/src/arch/x86/acpi_device.c
+++ b/src/arch/x86/acpi_device.c
@@ -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);
+}
diff --git a/src/arch/x86/include/arch/acpi_device.h b/src/arch/x86/include/arch/acpi_device.h
index a81cee0..7b5001f 100644
--- a/src/arch/x86/include/arch/acpi_device.h
+++ b/src/arch/x86/include/arch/acpi_device.h
@@ -16,11 +16,13 @@
 #ifndef __ACPI_DEVICE_H
 #define __ACPI_DEVICE_H
 
+#include <device/i2c.h>
 #include <stdint.h>
 
 #define ACPI_DESCRIPTOR_LARGE		(1 << 7)
 #define ACPI_DESCRIPTOR_INTERRUPT	(ACPI_DESCRIPTOR_LARGE | 9)
 #define ACPI_DESCRIPTOR_GPIO		(ACPI_DESCRIPTOR_LARGE | 12)
+#define ACPI_DESCRIPTOR_SERIAL_BUS	(ACPI_DESCRIPTOR_LARGE | 14)
 
 struct device;
 const char *acpi_device_name(struct device *dev);
@@ -157,4 +159,29 @@ struct acpi_gpio {
 /* Write GpioIo() or GpioInt() descriptor to SSDT AML output */
 void acpi_device_write_gpio(const struct acpi_gpio *gpio);
 
+/*
+ * ACPI Descriptors for Serial Bus interfaces
+ */
+
+#define ACPI_SERIAL_BUS_TYPE_I2C	1
+#define ACPI_SERIAL_BUS_REVISION_ID	1
+
+/*
+ * ACPI I2C Bus
+ */
+
+struct acpi_i2c {
+	/* I2C Address */
+	uint16_t address;
+	/* 7 or 10 bit Address Mode */
+	enum i2c_address_mode mode_10bit;
+	/* I2C Bus Speed in Hz */
+	enum i2c_speed speed;
+	/* Reference to I2C controller */
+	const char *resource;
+};
+
+/* Write I2cSerialBus() descriptor to SSDT AML output */
+void acpi_device_write_i2c(const struct acpi_i2c *i2c);
+
 #endif
diff --git a/src/include/device/i2c.h b/src/include/device/i2c.h
index b152bb9..c8c7b22 100644
--- a/src/include/device/i2c.h
+++ b/src/include/device/i2c.h
@@ -19,6 +19,19 @@
 #include <stdint.h>
 #include <stdlib.h>
 
+enum i2c_speed {
+	I2C_SPEED_STANDARD	= 100000,
+	I2C_SPEED_FAST		= 400000,
+	I2C_SPEED_FAST_PLUS	= 1000000,
+	I2C_SPEED_HIGH		= 3400000,
+	I2C_SPEED_FAST_ULTRA	= 5000000,
+};
+
+enum i2c_address_mode {
+	I2C_MODE_7_BIT,
+	I2C_MODE_10_BIT
+};
+
 struct i2c_seg
 {
 	int read;



More information about the coreboot-gerrit mailing list