mail.coreboot.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
List overview
Download
coreboot-gerrit
July 2016
----- 2024 -----
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
coreboot-gerrit@coreboot.org
1 participants
1820 discussions
Start a n
N
ew thread
Patch set updated for coreboot: mainboard/google/reef: Use device driver for DA7219 configuration
by Duncan Laurie
04 Jul '16
04 Jul '16
Duncan Laurie (dlaurie(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/15539
-gerrit commit f56d8b0e0c7271154ba553c6b6306437e7679d97 Author: Duncan Laurie <dlaurie(a)chromium.org> Date: Sat Jul 2 20:05:43 2016 -0700 mainboard/google/reef: Use device driver for DA7219 configuration Use the device driver for DA7219 device configuration in the SSDT and remove the static copy in the DSDT. Tested on reef to ensure that the generated SSDT contents are equivalent to the current DSDT contents. Change-Id: I288eb05d0cb3f5310c4dca4aa1eab5a029f216af Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org> --- src/mainboard/google/reef/Kconfig | 3 ++ src/mainboard/google/reef/acpi/mainboard.asl | 60 ---------------------------- src/mainboard/google/reef/devicetree.cb | 20 +++++++++- 3 files changed, 22 insertions(+), 61 deletions(-) diff --git a/src/mainboard/google/reef/Kconfig b/src/mainboard/google/reef/Kconfig index 194a6ba..3ca1af1 100644 --- a/src/mainboard/google/reef/Kconfig +++ b/src/mainboard/google/reef/Kconfig @@ -25,6 +25,9 @@ config CHROMEOS select VBOOT_OPROM_MATTERS select VIRTUAL_DEV_SWITCH +config DRIVERS_I2C_DA7219 + default y + config DRIVERS_I2C_GENERIC default y diff --git a/src/mainboard/google/reef/acpi/mainboard.asl b/src/mainboard/google/reef/acpi/mainboard.asl index 6e6d61f..5b6e976 100644 --- a/src/mainboard/google/reef/acpi/mainboard.asl +++ b/src/mainboard/google/reef/acpi/mainboard.asl @@ -38,63 +38,3 @@ Scope (\_SB.PCI0.LPCB) /* Chrome OS Embedded Controller */ #include "ec.asl" } - -Scope (\_SB.PCI0.I2C0) -{ - /* Headphone Codec */ - Device (HPDA) - { - Name (_HID, "DLGS7219") - Name (_DDN, "Dialog DA7219 Codec") - Name (_UID, 1) - Name (_S0W, 4) - Name (_DSD, Package () { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package () { - Package () { "dlg,micbias-lvl", 2600 }, - Package () { "dlg,mic-amp-in-sel", "diff" }, - }, - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package () { - Package () {"da7219_aad", "DAAD"}, - } - }) - - Name (DAAD, Package () { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package () { - Package () { "dlg,btn-cfg", 50 }, - Package () { "dlg,mic-det-thr", 500 }, - Package () { "dlg,jack-ins-deb", 20 }, - Package () { "dlg,jack-det-rate", "32ms_64ms" }, - Package () { "dlg,jack-rem-deb", 1 }, - Package () { "dlg,a-d-btn-thr", 0xa }, - Package () { "dlg,d-b-btn-thr", 0x16 }, - Package () { "dlg,b-c-btn-thr", 0x21 }, - Package () { "dlg,c-mic-btn-thr", 0x3E }, - Package () { "dlg,btn-avg", 4 }, - Package () { "dlg,adc-1bit-rpt", 1 }, - } - }) - - Name (_CRS, ResourceTemplate() - { - I2cSerialBus ( - BOARD_HP_MIC_CODEC_I2C_ADDR, - ControllerInitiated, - 400000, - AddressingMode7Bit, - "\\_SB.PCI0.I2C0", - ) - Interrupt (ResourceConsumer, Level, ActiveLow) - { - BOARD_HP_MIC_CODEC_IRQ - } - }) - - Method (_STA) - { - Return (0xF) - } - } -} diff --git a/src/mainboard/google/reef/devicetree.cb b/src/mainboard/google/reef/devicetree.cb index e0831f4..b931a89 100644 --- a/src/mainboard/google/reef/devicetree.cb +++ b/src/mainboard/google/reef/devicetree.cb @@ -57,7 +57,25 @@ chip soc/intel/apollolake device pci 14.1 off end # - Root Port 1 - PCIe-B 1 device pci 15.0 on end # - XHCI device pci 15.1 off end # - XDCI - device pci 16.0 on end # - I2C 0 + device pci 16.0 on # - I2C 0 + chip drivers/i2c/da7219 + register "irq" = "IRQ_LEVEL_LOW(GPIO_116_IRQ)" + register "btn_cfg" = "50" + register "mic_det_thr" = "500" + register "jack_ins_deb" = "20" + register "jack_det_rate" = ""32ms_64ms"" + register "jack_rem_deb" = "1" + register "a_d_btn_thr" = "0xa" + register "d_b_btn_thr" = "0x16" + register "b_c_btn_thr" = "0x21" + register "c_mic_btn_thr" = "0x3e" + register "btn_avg" = "4" + register "adc_1bit_rpt" = "1" + register "micbias_lvl" = "2600" + register "mic_amp_in_sel" = ""diff"" + device i2c 1a on end + end + end device pci 16.1 on end # - I2C 1 device pci 16.2 on end # - I2C 2 device pci 16.3 on end # - I2C 3
1
0
0
0
Patch set updated for coreboot: acpi: Change device properties to work as a tree
by Duncan Laurie
04 Jul '16
04 Jul '16
Duncan Laurie (dlaurie(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/15537
-gerrit commit bdf336724ee619e65d335510dca27a43ca2e6587 Author: Duncan Laurie <dlaurie(a)chromium.org> Date: Sat Jul 2 19:56:06 2016 -0700 acpi: Change device properties to work as a tree There is a second ACPI _DSD document from the UEFI Forum that details how _DSD style tables can be nested, creating a tree of similarly formatted tables. This document is linked from acpi_device.h. In order to support this the device property interface needs to be more flexible and build up a tree of properties to write all entries at once instead of writing each entry as it is generated. In the end this is a more flexible solution that can support drivers that need child tables like the DA7219 codec, while only requiring minor changes to the existing drivers that use the device property interface. This was tested on reef (apollolake) and chell (skylake) boards to ensure that there was no change in the generated SSDT AML. Change-Id: Ia22e3a5fd3982ffa7c324bee1a8d190d49f853dd Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org> --- src/arch/x86/acpi_device.c | 303 ++++++++++++++++++++---------- src/arch/x86/include/arch/acpi_device.h | 106 +++++++---- src/drivers/generic/max98357a/max98357a.c | 9 +- src/drivers/i2c/nau8825/nau8825.c | 14 +- src/soc/intel/skylake/sd.c | 7 +- 5 files changed, 297 insertions(+), 142 deletions(-) diff --git a/src/arch/x86/acpi_device.c b/src/arch/x86/acpi_device.c index f8f6a6d..402d6d3 100644 --- a/src/arch/x86/acpi_device.c +++ b/src/arch/x86/acpi_device.c @@ -24,15 +24,6 @@ #include <gpio.h> #endif -/* - * Pointer to length field in device properties package - * Location is set in dp_header() and length filled in by dp_footer() - */ -static char *dp_count_ptr; - -/* Count of the number of device properties in the current set */ -static char dp_count; - /* Write empty word value and return pointer to it */ static void *acpi_device_write_zero_len(void) { @@ -473,39 +464,8 @@ void acpi_device_write_spi(const struct acpi_spi *spi) acpi_device_fill_len(desc_length); } -/* Write a header for using _DSD to export Device Properties */ -void acpi_dp_write_header(void) -{ - /* Name (_DSD) */ - acpigen_write_name("_DSD"); - - /* Package (2) */ - acpigen_write_package(2); - - /* ToUUID (ACPI_DP_UUID) */ - acpigen_write_uuid(ACPI_DP_UUID); - - /* Package (X) */ - acpigen_emit_byte(0x12); - acpigen_write_len_f(); - dp_count_ptr = acpigen_get_current(); - acpigen_emit_byte(0); /* Number of elements, filled by dp_footer */ - - /* Reset element counter */ - dp_count = 0; -} - -/* Fill in length values from writing Device Properties */ -void acpi_dp_write_footer(void) -{ - /* Patch device property element count */ - *dp_count_ptr = dp_count; - - acpigen_pop_len(); /* Inner package length */ - acpigen_pop_len(); /* Outer package length */ -} - -void acpi_dp_write_value(const struct acpi_dp *prop) +static void acpi_dp_write_array(const struct acpi_dp *array); +static void acpi_dp_write_value(const struct acpi_dp *prop) { switch (prop->type) { case ACPI_DP_TYPE_INTEGER: @@ -515,86 +475,237 @@ void acpi_dp_write_value(const struct acpi_dp *prop) acpigen_write_string(prop->string); break; case ACPI_DP_TYPE_REFERENCE: + case ACPI_DP_TYPE_CHILD: acpigen_emit_namestring(prop->string); break; + case ACPI_DP_TYPE_ARRAY: + acpi_dp_write_array(prop->child); + break; + default: + break; } } -/* Write Device Property key with value as an integer */ -void acpi_dp_write_keyval(const char *key, const struct acpi_dp *prop) +/* Package (2) { "prop->name", VALUE } */ +static void acpi_dp_write_property(const struct acpi_dp *prop) { acpigen_write_package(2); - acpigen_write_string(key); + acpigen_write_string(prop->name); acpi_dp_write_value(prop); acpigen_pop_len(); - dp_count++; } -/* Write Device Property key with value as an integer */ -void acpi_dp_write_integer(const char *key, uint64_t value) +/* Write array of Device Properties */ +static void acpi_dp_write_array(const struct acpi_dp *array) { - const struct acpi_dp prop = ACPI_DP_INTEGER(value); - acpi_dp_write_keyval(key, &prop); -} + const struct acpi_dp *dp; + char *pkg_count; -/* Write Device Property key with value as a string */ -void acpi_dp_write_string(const char *key, const char *value) -{ - const struct acpi_dp prop = ACPI_DP_STRING(value); - acpi_dp_write_keyval(key, &prop); + /* Package element count determined as it is populated */ + pkg_count = acpigen_write_package(0); + + for (dp = array; dp; dp = dp->next) { + acpi_dp_write_value(dp); + (*pkg_count)++; + } + + acpigen_pop_len(); } -/* Write Device Property key with value as a reference */ -void acpi_dp_write_reference(const char *key, const char *value) +static void acpi_dp_free(struct acpi_dp *dp) { - const struct acpi_dp prop = ACPI_DP_REFERENCE(value); - acpi_dp_write_keyval(key, &prop); + while (dp) { + struct acpi_dp *p = dp->next; + acpi_dp_free(dp->child); + free(dp); + dp = p; + } } -/* Write array of Device Properties */ -void acpi_dp_write_array(const char *key, const struct acpi_dp *array, int len) +void acpi_dp_write(struct acpi_dp *table) { - int i; - acpigen_write_package(2); - acpigen_write_string(key); - acpigen_write_package(len); - for (i = 0; i < len; i++) - acpi_dp_write_value(&array[i]); + struct acpi_dp *dp, *prop; + char *dp_count, *prop_count; + int child_count = 0; + + if (!table || table->type != ACPI_DP_TYPE_TABLE) + return; + + /* Name (name) */ + acpigen_write_name(table->name); + + /* Device Property list starts with the next entry */ + prop = table->next; + + /* Package (DP), default to 2 elements (assuming no children) */ + dp_count = acpigen_write_package(2); + + /* ToUUID (ACPI_DP_UUID) */ + acpigen_write_uuid(ACPI_DP_UUID); + + /* Package (PROP), element count determined as it is populated */ + prop_count = acpigen_write_package(0); + + /* Print base properties */ + for (dp = prop; dp; dp = dp->next) { + if (dp->type == ACPI_DP_TYPE_CHILD) { + child_count++; + } else { + (*prop_count)++; + acpi_dp_write_property(dp); + } + } + + /* Package (PROP) length */ acpigen_pop_len(); + + if (child_count) { + /* Update DP package count to 4 */ + *dp_count = 4; + + /* ToUUID (ACPI_DP_CHILD_UUID) */ + acpigen_write_uuid(ACPI_DP_CHILD_UUID); + + /* Print child pointer properties */ + acpigen_write_package(child_count); + + for (dp = prop; dp; dp = dp->next) + if (dp->type == ACPI_DP_TYPE_CHILD) + acpi_dp_write_property(dp); + + acpigen_pop_len(); + } + + /* Package (DP) length */ acpigen_pop_len(); - dp_count++; + + /* Recursively parse children into separate tables */ + for (dp = prop; dp; dp = dp->next) + if (dp->type == ACPI_DP_TYPE_CHILD) + acpi_dp_write(dp->child); + + /* Clean up */ + acpi_dp_free(table); } -/* Write array of Device Properties with values as integers */ -void acpi_dp_write_integer_array(const char *key, uint64_t *array, int len) +static struct acpi_dp *acpi_dp_new(struct acpi_dp *dp, enum acpi_dp_type type, + const char *name) { + struct acpi_dp *new; + + new = malloc(sizeof(struct acpi_dp)); + if (!new) + return NULL; + + memset(new, 0, sizeof(*new)); + new->type = type; + new->name = name; + + if (dp) { + /* Add to end of property list */ + while (dp->next) + dp = dp->next; + dp->next = new; + } + + return new; +} + +struct acpi_dp *acpi_dp_new_table(const char *name) +{ + return acpi_dp_new(NULL, ACPI_DP_TYPE_TABLE, name); +} + +struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name, + uint64_t value) +{ + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_INTEGER, name); + + if (new) + new->integer = value; + + return new; +} + +struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name, + const char *string) +{ + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_STRING, name); + + if (new) + new->string = string; + + return new; +} + +struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name, + const char *reference) +{ + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_REFERENCE, name); + + if (new) + new->string = reference; + + return new; +} + +struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name, + struct acpi_dp *child) +{ + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_CHILD, name); + + if (new) { + new->string = child->name; + new->child = child; + } + + return new; +} + +struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name, + uint64_t *array, int len) +{ + struct acpi_dp *dp_array; int i; - acpigen_write_package(2); - acpigen_write_string(key); - acpigen_write_package(len); - for (i = 0; i < len; i++) - acpigen_write_integer(array[i]); - acpigen_pop_len(); - acpigen_pop_len(); - dp_count++; + + if (len <= 0) + return NULL; + + /* Package (2) { name, ... } */ + dp_array = acpi_dp_new(dp, ACPI_DP_TYPE_ARRAY, name); + if (!dp_array) + return NULL; + + /* Package (len) { [0], [1], ... } */ + dp_array->child = acpi_dp_add_integer(NULL, NULL, array[0]); + for (i = 1; i < len; i++) + if (!acpi_dp_add_integer(dp_array->child, NULL, array[i])) + break; + + return dp_array; } -/* - * Device Properties for GPIO binding - * linux/Documentation/acpi/gpio-properties.txt - */ -void acpi_dp_write_gpio(const char *key, const char *ref, int index, - int pin, int active_low) +struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name, + const char *ref, int index, int pin, + int active_low) { - const struct acpi_dp gpio_prop[] = { - /* The device that has _CRS containing GpioIo()/GpioInt() */ - ACPI_DP_REFERENCE(ref), - /* Index of the GPIO resource in _CRS starting from zero */ - ACPI_DP_INTEGER(index), - /* Pin in the GPIO resource, typically zero */ - ACPI_DP_INTEGER(pin), - /* Set if pin is active low */ - ACPI_DP_INTEGER(active_low) - }; - acpi_dp_write_array(key, gpio_prop, ARRAY_SIZE(gpio_prop)); + struct acpi_dp *gpio; + + gpio = acpi_dp_new(dp, ACPI_DP_TYPE_ARRAY, name); + if (!gpio) + return NULL; + + /* The device that has _CRS containing GpioIO()/GpioInt() */ + gpio->child = acpi_dp_add_reference(NULL, NULL, ref); + + /* Index of the GPIO resource in _CRS starting from zero */ + acpi_dp_add_integer(gpio->child, NULL, index); + + /* Pin in the GPIO resource, typically zero */ + acpi_dp_add_integer(gpio->child, NULL, pin); + + /* Set if pin is active low */ + acpi_dp_add_integer(gpio->child, NULL, active_low); + + return gpio; } diff --git a/src/arch/x86/include/arch/acpi_device.h b/src/arch/x86/include/arch/acpi_device.h index 65f49b2..dd6b290 100644 --- a/src/arch/x86/include/arch/acpi_device.h +++ b/src/arch/x86/include/arch/acpi_device.h @@ -229,63 +229,103 @@ struct acpi_spi { void acpi_device_write_spi(const struct acpi_spi *spi); /* - * Device Properties with _DSD + * Writing Device Properties objects via _DSD + * *
http://uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.p…
+ *
http://uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extens…
+ * + * The Device Property Hierarchy can be multiple levels deep with multiple + * children possible in each level. In order to support this flexibility + * the device property hierarchy must be built up before being written out. + * + * For example: + * + * // Child table with string and integer + * struct acpi_dp *child = acpi_dp_new_table("CHLD"); + * acpi_dp_add_string(child, "childstring", "CHILD"); + * acpi_dp_add_integer(child, "childint", 100); + * + * // _DSD table with integer and gpio and child pointer + * struct acpi_dp *dsd = acpi_dp_new_table("_DSD"); + * acpi_dp_add_integer(dsd, "number1", 1); + * acpi_dp_add_gpio(dsd, "gpio", "\_SB.PCI0.GPIO", 0, 0, 1); + * acpi_dp_add_child(dsd, "child", child); + * + * // Write entries into SSDT and clean up resources + * acpi_dp_write(dsd); + * + * Name(_DSD, Package() { + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") + * Package() { + * Package() { "gpio", Package() { \_SB.PCI0.GPIO, 0, 0, 0 } } + * Package() { "number1", 1 } + * } + * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b") + * Package() { + * Package() { "child", CHLD } + * } + * } + * Name(CHLD, Package() { + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") + * Package() { + * Package() { "childstring", "CHILD" } + * Package() { "childint", 100 } + * } + * } */ -#define ACPI_DP_UUID "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" +#define ACPI_DP_UUID "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" +#define ACPI_DP_CHILD_UUID "dbb8e3e6-5886-4ba6-8795-1319f52a966b" enum acpi_dp_type { ACPI_DP_TYPE_INTEGER, ACPI_DP_TYPE_STRING, ACPI_DP_TYPE_REFERENCE, + ACPI_DP_TYPE_TABLE, + ACPI_DP_TYPE_ARRAY, + ACPI_DP_TYPE_CHILD, }; struct acpi_dp { enum acpi_dp_type type; + const char *name; + struct acpi_dp *next; + struct acpi_dp *child; union { uint64_t integer; const char *string; }; }; -#define ACPI_DP_INTEGER(x) { .type = ACPI_DP_TYPE_INTEGER, .integer = x } -#define ACPI_DP_STRING(x) { .type = ACPI_DP_TYPE_STRING, .string = x } -#define ACPI_DP_REFERENCE(x) { .type = ACPI_DP_TYPE_REFERENCE, .string = x } - -/* - * Writing Device Properties objects via _DSD - */ - -/* Start a set of Device Properties with _DSD and UUID */ -void acpi_dp_write_header(void); - -/* End the Device Properties set and fill in length values */ -void acpi_dp_write_footer(void); - -/* Write a Device Property value, but not the key */ -void acpi_dp_write_value(const struct acpi_dp *prop); +/* Start a new Device Property table with provided ACPI reference */ +struct acpi_dp *acpi_dp_new_table(const char *ref); -/* Write a Device Property, both key and value */ -void acpi_dp_write_keyval(const char *key, const struct acpi_dp *prop); +/* Add integer Device Property */ +struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name, + uint64_t value); -/* Write an integer as a Device Property */ -void acpi_dp_write_integer(const char *key, uint64_t value); +/* Add string Device Property */ +struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name, + const char *string); -/* Write a string as a Device Property */ -void acpi_dp_write_string(const char *key, const char *value); +/* Add ACPI reference Device Property */ +struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name, + const char *reference); -/* Write an ACPI reference as a Device Property */ -void acpi_dp_write_reference(const char *key, const char *value); +/* Add an array of integers Device Property */ +struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name, + uint64_t *array, int len); -/* Write an array of Device Properties */ -void acpi_dp_write_array(const char *key, const struct acpi_dp *array, int len); +/* Add a GPIO binding Device Property */ +struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name, + const char *ref, int index, int pin, + int active_low); -/* Write an array of integers as Device Properties */ -void acpi_dp_write_integer_array(const char *key, uint64_t *array, int len); +/* Add a child table of Device Properties */ +struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name, + struct acpi_dp *child); -/* Write a GPIO binding Device Property */ -void acpi_dp_write_gpio(const char *key, const char *ref, int index, - int pin, int active_low); +/* Write Device Property hierarchy and clean up resources */ +void acpi_dp_write(struct acpi_dp *table); #endif diff --git a/src/drivers/generic/max98357a/max98357a.c b/src/drivers/generic/max98357a/max98357a.c index 0d522d4..25e5104 100644 --- a/src/drivers/generic/max98357a/max98357a.c +++ b/src/drivers/generic/max98357a/max98357a.c @@ -32,6 +32,7 @@ static void max98357a_fill_ssdt(struct device *dev) { struct drivers_generic_max98357a_config *config = dev->chip_info; const char *path; + struct acpi_dp *dp; if (!dev->enabled || !config) return; @@ -51,12 +52,12 @@ static void max98357a_fill_ssdt(struct device *dev) acpigen_write_resourcetemplate_footer(); /* _DSD for devicetree properties */ - acpi_dp_write_header(); /* This points to the first pin in the first gpio entry in _CRS */ path = acpi_device_path(dev); - acpi_dp_write_gpio("sdmode-gpio", path, 0, 0, 0); - acpi_dp_write_integer("sdmode-delay", config->sdmode_delay); - acpi_dp_write_footer(); + dp = acpi_dp_new_table("_DSD"); + acpi_dp_add_gpio(dp, "sdmode-gpio", path, 0, 0, 0); + acpi_dp_add_integer(dp, "sdmode-delay", config->sdmode_delay); + acpi_dp_write(dp); acpigen_pop_len(); /* Device */ acpigen_pop_len(); /* Scope */ diff --git a/src/drivers/i2c/nau8825/nau8825.c b/src/drivers/i2c/nau8825/nau8825.c index 71aacea..a86eff4 100644 --- a/src/drivers/i2c/nau8825/nau8825.c +++ b/src/drivers/i2c/nau8825/nau8825.c @@ -28,7 +28,9 @@ #define NAU8825_ACPI_NAME "NAU8" #define NAU8825_ACPI_HID "10508825" -#define NAU8825_DP_INT(key,val) acpi_dp_write_integer("nuvoton," key, (val)) + +#define NAU8825_DP_INT(key,val) \ + acpi_dp_add_integer(dp, "nuvoton," key, (val)) static void nau8825_fill_ssdt(struct device *dev) { @@ -40,6 +42,7 @@ static void nau8825_fill_ssdt(struct device *dev) .speed = config->bus_speed ? : I2C_SPEED_FAST, .resource = scope, }; + struct acpi_dp *dp = NULL; if (!dev->enabled || !scope) return; @@ -62,7 +65,7 @@ static void nau8825_fill_ssdt(struct device *dev) acpigen_write_resourcetemplate_footer(); /* Device Properties */ - acpi_dp_write_header(); + dp = acpi_dp_new_table("_DSD"); NAU8825_DP_INT("jkdet-enable", config->jkdet_enable); NAU8825_DP_INT("jkdet-pull-enable", config->jkdet_pull_enable); NAU8825_DP_INT("jkdet-pull-up", config->jkdet_pull_up); @@ -77,10 +80,9 @@ static void nau8825_fill_ssdt(struct device *dev) NAU8825_DP_INT("jack-insert-debounce", config->jack_insert_debounce); NAU8825_DP_INT("jack-eject-deboune", config->jack_eject_debounce); NAU8825_DP_INT("sar-threshold-num", config->sar_threshold_num); - acpi_dp_write_integer_array("nuvoton,sar-threshold", - config->sar_threshold, - config->sar_threshold_num); - acpi_dp_write_footer(); + acpi_dp_add_integer_array(dp, "nuvoton,sar-threshold", + config->sar_threshold, config->sar_threshold_num); + acpi_dp_write(dp); acpigen_pop_len(); /* Device */ acpigen_pop_len(); /* Scope */ diff --git a/src/soc/intel/skylake/sd.c b/src/soc/intel/skylake/sd.c index 80adb9c..a75cf63 100644 --- a/src/soc/intel/skylake/sd.c +++ b/src/soc/intel/skylake/sd.c @@ -38,6 +38,7 @@ static void sd_fill_ssdt(struct device *dev) .pin_count = 1, .pins = { config->sdcard_cd_gpio_default } }; + struct acpi_dp *dp; if (!dev->enabled) return; @@ -62,9 +63,9 @@ static void sd_fill_ssdt(struct device *dev) acpigen_write_resourcetemplate_footer(); /* Bind the cd-gpio name to the GpioInt() resource */ - acpi_dp_write_header(); - acpi_dp_write_gpio("cd-gpio", path, 0, 0, 1); - acpi_dp_write_footer(); + dp = acpi_dp_new_table("_DSD"); + acpi_dp_add_gpio(dp, "cd-gpio", path, 0, 0, 1); + acpi_dp_write(dp); acpigen_pop_len(); }
1
0
0
0
Patch set updated for coreboot: drivers/i2c/da7219: Add driver for generating device in SSDT
by Duncan Laurie
04 Jul '16
04 Jul '16
Duncan Laurie (dlaurie(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/15538
-gerrit commit 08657757f9b57990563ff9ef32ecea0eac0f3908 Author: Duncan Laurie <dlaurie(a)chromium.org> Date: Sat Jul 2 20:00:56 2016 -0700 drivers/i2c/da7219: Add driver for generating device in SSDT Add a device driver to generate the device and required properties into the SSDT. This driver uses the ACPI Device Property interface to generate the required parameters into the _DSD table format expected by the kernel. This was tested on the reef mainboard to ensure that the SSDT contained the equivalent parameters that are provided by the current DSDT object. Change-Id: Ia809e953932a7e127352a7ef193974d95e511565 Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org> --- src/drivers/i2c/da7219/Kconfig | 2 + src/drivers/i2c/da7219/Makefile.inc | 1 + src/drivers/i2c/da7219/chip.h | 106 +++++++++++++++++++++++++++++++ src/drivers/i2c/da7219/da7219.c | 122 ++++++++++++++++++++++++++++++++++++ 4 files changed, 231 insertions(+) diff --git a/src/drivers/i2c/da7219/Kconfig b/src/drivers/i2c/da7219/Kconfig new file mode 100644 index 0000000..5539af1 --- /dev/null +++ b/src/drivers/i2c/da7219/Kconfig @@ -0,0 +1,2 @@ +config DRIVERS_I2C_DA7219 + bool diff --git a/src/drivers/i2c/da7219/Makefile.inc b/src/drivers/i2c/da7219/Makefile.inc new file mode 100644 index 0000000..354a330 --- /dev/null +++ b/src/drivers/i2c/da7219/Makefile.inc @@ -0,0 +1 @@ +ramstage-$(CONFIG_DRIVERS_I2C_DA7219) += da7219.c diff --git a/src/drivers/i2c/da7219/chip.h b/src/drivers/i2c/da7219/chip.h new file mode 100644 index 0000000..823b940 --- /dev/null +++ b/src/drivers/i2c/da7219/chip.h @@ -0,0 +1,106 @@ +#include <arch/acpi_device.h> + +/* + * Dialog Semiconductor DA7219 Audio Codec devicetree bindings + * linux/Documentation/devicetree/bindings/sound/da7219.txt + */ +struct drivers_i2c_da7219_config { + /* Interrupt configuration */ + struct acpi_irq irq; + + /* I2C Bus Frequency in Hertz (default 400kHz) */ + unsigned bus_speed; + + /* + * micbias-lvl : Voltage (mV) for Mic Bias + * [<1600>, <1800>, <2000>, <2200>, <2400>, <2600>] + */ + unsigned micbias_lvl; + + /* + * mic-amp-in-sel : Mic input source type + * ["diff", "se_p", "se_n"] + */ + const char *mic_amp_in_sel; + + /* + * Properties for da7219_aad child node + */ + + /* + * micbias-pulse-lvl : Mic bias higher voltage pulse level (mV) + * [<2800>, <2900>] + */ + unsigned micbias_pulse_lvl; + + /* + * micbias-pulse-time : Mic bias higher voltage pulse duration (ms) + */ + unsigned micbias_pulse_time; + + /* + * btn-cfg : Periodic button press measurements for 4-pole jack (ms) + * [<2>, <5>, <10>, <50>, <100>, <200>, <500>] + */ + unsigned btn_cfg; + + /* + * mic-det-thr : Impedance threshold for mic detection measurement (Ohms) + * [<200>, <500>, <750>, <1000>] + */ + unsigned mic_det_thr; + + /* + * jack-ins-deb : Debounce time for jack insertion (ms) + * [<5>, <10>, <20>, <50>, <100>, <200>, <500>, <1000>] + */ + unsigned jack_ins_deb; + + /* + * jack-det-rate : Jack type detection latency (3/4 pole) + * ["32ms_64ms", "64ms_128ms", "128ms_256ms", "256ms_512ms"] + */ + const char *jack_det_rate; + + /* + * jack-rem-deb : Debounce time for jack removal (ms) + * [<1>, <5>, <10>, <20>] + */ + unsigned jack_rem_deb; + + /* + * a-d-btn-thr : Impedance threshold between buttons A and D + * [0x0 - 0xFF] + */ + unsigned a_d_btn_thr; + + /* + * d-b-btn-thr : Impedance threshold between buttons D and B + * [0x0 - 0xFF] + */ + unsigned d_b_btn_thr; + + /* + * b-c-btn-thr : Impedance threshold between buttons B and C + * [0x0 - 0xFF] + */ + unsigned b_c_btn_thr; + + /* + * c-mic-btn-thr : Impedance threshold between button C and Mic + * [0x0 - 0xFF] + */ + unsigned c_mic_btn_thr; + + /* + * btn-avg : Number of 8-bit readings for averaged button measurement + * [<1>, <2>, <4>, <8>] + */ + unsigned btn_avg; + + /* + * adc-1bit-rpt : Repeat count for 1-bit button measurement + * [<1>, <2>, <4>, <8>] + */ + unsigned adc_1bit_rpt; +}; diff --git a/src/drivers/i2c/da7219/da7219.c b/src/drivers/i2c/da7219/da7219.c new file mode 100644 index 0000000..b29a4a1 --- /dev/null +++ b/src/drivers/i2c/da7219/da7219.c @@ -0,0 +1,122 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2016 Google Inc. + * + * 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 <arch/acpi.h> +#include <arch/acpi_device.h> +#include <arch/acpigen.h> +#include <console/console.h> +#include <device/i2c.h> +#include <device/device.h> +#include <device/path.h> +#include <stdint.h> +#include <string.h> +#include "chip.h" + +#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) + +#define DA7219_ACPI_NAME "DLG7" +#define DA7219_ACPI_HID "DLGS7219" + +static void da7219_fill_ssdt(struct device *dev) +{ + struct drivers_i2c_da7219_config *config = dev->chip_info; + const char *scope = acpi_device_scope(dev); + struct acpi_i2c i2c = { + .address = dev->path.i2c.device, + .mode_10bit = dev->path.i2c.mode_10bit, + .speed = config->bus_speed ? : I2C_SPEED_FAST, + .resource = scope, + }; + struct acpi_dp *dsd, *aad; + + if (!dev->enabled || !scope) + return; + + /* Device */ + acpigen_write_scope(scope); + acpigen_write_device(acpi_device_name(dev)); + acpigen_write_name_string("_HID", DA7219_ACPI_HID); + acpigen_write_name_integer("_UID", 1); + acpigen_write_name_string("_DDN", dev->chip_ops->name); + acpigen_write_name_integer("_S0W", 4); + acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON); + + /* Resources */ + acpigen_write_name("_CRS"); + acpigen_write_resourcetemplate_header(); + acpi_device_write_i2c(&i2c); + acpi_device_write_interrupt(&config->irq); + acpigen_write_resourcetemplate_footer(); + + /* AAD Child Device Properties */ + aad = acpi_dp_new_table("DAAD"); + acpi_dp_add_integer(aad, "dlg,btn-cfg", config->btn_cfg); + acpi_dp_add_integer(aad, "dlg,mic-det-thr", config->mic_det_thr); + acpi_dp_add_integer(aad, "dlg,jack-ins-deb", config->jack_ins_deb); + acpi_dp_add_string(aad, "dlg,jack-det-rate", config->jack_det_rate); + acpi_dp_add_integer(aad, "dlg,jack-rem-deb", config->jack_rem_deb); + acpi_dp_add_integer(aad, "dlg,a-d-btn-thr", config->a_d_btn_thr); + acpi_dp_add_integer(aad, "dlg,d-b-btn-thr", config->d_b_btn_thr); + acpi_dp_add_integer(aad, "dlg,b-c-btn-thr", config->b_c_btn_thr); + acpi_dp_add_integer(aad, "dlg,c-mic-btn-thr", config->c_mic_btn_thr); + acpi_dp_add_integer(aad, "dlg,btn-avg", config->btn_avg); + acpi_dp_add_integer(aad, "dlg,adc-1bit-rpt", config->adc_1bit_rpt); + acpi_dp_add_integer(aad, "dlg,micbias-pulse-lvl", + config->micbias_pulse_lvl); + acpi_dp_add_integer(aad, "dlg,micbias-pulse-time", + config->micbias_pulse_time); + + /* DA7219 Properties */ + dsd = acpi_dp_new_table("_DSD"); + acpi_dp_add_integer(dsd, "dlg,micbias-lvl", config->micbias_lvl); + acpi_dp_add_string(dsd, "dlg,mic-amp-in-sel", config->mic_amp_in_sel); + acpi_dp_add_child(dsd, "da7219_aad", aad); + + /* Write Device Property Hierarchy */ + acpi_dp_write(dsd); + + acpigen_pop_len(); /* Device */ + acpigen_pop_len(); /* Scope */ + + printk(BIOS_INFO, "%s: %s address 0%xh irq %d\n", + acpi_device_path(dev), dev->chip_ops->name, + dev->path.i2c.device, config->irq.pin); +} + +static const char *da7219_acpi_name(struct device *dev) +{ + return DA7219_ACPI_NAME; +} +#endif + +static struct device_operations da7219_ops = { + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, + .enable_resources = DEVICE_NOOP, +#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) + .acpi_name = &da7219_acpi_name, + .acpi_fill_ssdt_generator = &da7219_fill_ssdt, +#endif +}; + +static void da7219_enable(struct device *dev) +{ + dev->ops = &da7219_ops; +} + +struct chip_operations drivers_i2c_da7219_ops = { + CHIP_NAME("Dialog Semiconductor DA7219 Audio Codec") + .enable_dev = &da7219_enable +};
1
0
0
0
Patch set updated for coreboot: mainboard/google/reef: Use device driver for DA7219 configuration
by Duncan Laurie
04 Jul '16
04 Jul '16
Duncan Laurie (dlaurie(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/15539
-gerrit commit a663ca5c9fb300fac895510c0935b34a92640896 Author: Duncan Laurie <dlaurie(a)chromium.org> Date: Sat Jul 2 20:05:43 2016 -0700 mainboard/google/reef: Use device driver for DA7219 configuration Use the device driver for DA7219 device configuration in the SSDT and remove the static copy in the DSDT. Tested on reef to ensure that the generated SSDT contents are equivalent to the current DSDT contents. Change-Id: I288eb05d0cb3f5310c4dca4aa1eab5a029f216af Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org> --- src/mainboard/google/reef/Kconfig | 3 ++ src/mainboard/google/reef/acpi/mainboard.asl | 60 ---------------------------- src/mainboard/google/reef/devicetree.cb | 20 +++++++++- 3 files changed, 22 insertions(+), 61 deletions(-) diff --git a/src/mainboard/google/reef/Kconfig b/src/mainboard/google/reef/Kconfig index 194a6ba..3ca1af1 100644 --- a/src/mainboard/google/reef/Kconfig +++ b/src/mainboard/google/reef/Kconfig @@ -25,6 +25,9 @@ config CHROMEOS select VBOOT_OPROM_MATTERS select VIRTUAL_DEV_SWITCH +config DRIVERS_I2C_DA7219 + default y + config DRIVERS_I2C_GENERIC default y diff --git a/src/mainboard/google/reef/acpi/mainboard.asl b/src/mainboard/google/reef/acpi/mainboard.asl index 6e6d61f..5b6e976 100644 --- a/src/mainboard/google/reef/acpi/mainboard.asl +++ b/src/mainboard/google/reef/acpi/mainboard.asl @@ -38,63 +38,3 @@ Scope (\_SB.PCI0.LPCB) /* Chrome OS Embedded Controller */ #include "ec.asl" } - -Scope (\_SB.PCI0.I2C0) -{ - /* Headphone Codec */ - Device (HPDA) - { - Name (_HID, "DLGS7219") - Name (_DDN, "Dialog DA7219 Codec") - Name (_UID, 1) - Name (_S0W, 4) - Name (_DSD, Package () { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package () { - Package () { "dlg,micbias-lvl", 2600 }, - Package () { "dlg,mic-amp-in-sel", "diff" }, - }, - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package () { - Package () {"da7219_aad", "DAAD"}, - } - }) - - Name (DAAD, Package () { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package () { - Package () { "dlg,btn-cfg", 50 }, - Package () { "dlg,mic-det-thr", 500 }, - Package () { "dlg,jack-ins-deb", 20 }, - Package () { "dlg,jack-det-rate", "32ms_64ms" }, - Package () { "dlg,jack-rem-deb", 1 }, - Package () { "dlg,a-d-btn-thr", 0xa }, - Package () { "dlg,d-b-btn-thr", 0x16 }, - Package () { "dlg,b-c-btn-thr", 0x21 }, - Package () { "dlg,c-mic-btn-thr", 0x3E }, - Package () { "dlg,btn-avg", 4 }, - Package () { "dlg,adc-1bit-rpt", 1 }, - } - }) - - Name (_CRS, ResourceTemplate() - { - I2cSerialBus ( - BOARD_HP_MIC_CODEC_I2C_ADDR, - ControllerInitiated, - 400000, - AddressingMode7Bit, - "\\_SB.PCI0.I2C0", - ) - Interrupt (ResourceConsumer, Level, ActiveLow) - { - BOARD_HP_MIC_CODEC_IRQ - } - }) - - Method (_STA) - { - Return (0xF) - } - } -} diff --git a/src/mainboard/google/reef/devicetree.cb b/src/mainboard/google/reef/devicetree.cb index e0831f4..b931a89 100644 --- a/src/mainboard/google/reef/devicetree.cb +++ b/src/mainboard/google/reef/devicetree.cb @@ -57,7 +57,25 @@ chip soc/intel/apollolake device pci 14.1 off end # - Root Port 1 - PCIe-B 1 device pci 15.0 on end # - XHCI device pci 15.1 off end # - XDCI - device pci 16.0 on end # - I2C 0 + device pci 16.0 on # - I2C 0 + chip drivers/i2c/da7219 + register "irq" = "IRQ_LEVEL_LOW(GPIO_116_IRQ)" + register "btn_cfg" = "50" + register "mic_det_thr" = "500" + register "jack_ins_deb" = "20" + register "jack_det_rate" = ""32ms_64ms"" + register "jack_rem_deb" = "1" + register "a_d_btn_thr" = "0xa" + register "d_b_btn_thr" = "0x16" + register "b_c_btn_thr" = "0x21" + register "c_mic_btn_thr" = "0x3e" + register "btn_avg" = "4" + register "adc_1bit_rpt" = "1" + register "micbias_lvl" = "2600" + register "mic_amp_in_sel" = ""diff"" + device i2c 1a on end + end + end device pci 16.1 on end # - I2C 1 device pci 16.2 on end # - I2C 2 device pci 16.3 on end # - I2C 3
1
0
0
0
Patch set updated for coreboot: acpi: Change device properties to work as a tree
by Duncan Laurie
04 Jul '16
04 Jul '16
Duncan Laurie (dlaurie(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/15537
-gerrit commit 53d65c7372af3d15c19b54dc7fa1525620e20dc6 Author: Duncan Laurie <dlaurie(a)chromium.org> Date: Sat Jul 2 19:56:06 2016 -0700 acpi: Change device properties to work as a tree There is a second ACPI _DSD document from the UEFI Forum that details how _DSD style tables can be nested, creating a tree of similarly formatted tables. This document is linked from acpi_device.h. In order to support this the device property interface needs to be more flexible and build up a tree of properties to write all entries at once instead of writing each entry as it is generated. In the end this is a more flexible solution that can support drivers that need child tables like the DA7219 codec, while only requiring minor changes to the existing drivers that use the device property interface. This was tested on reef (apollolake) and chell (skylake) boards to ensure that there was no change in the generated SSDT AML. Change-Id: Ia22e3a5fd3982ffa7c324bee1a8d190d49f853dd Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org> --- src/arch/x86/acpi_device.c | 303 ++++++++++++++++++++---------- src/arch/x86/include/arch/acpi_device.h | 106 +++++++---- src/drivers/generic/max98357a/max98357a.c | 9 +- src/drivers/i2c/nau8825/nau8825.c | 14 +- src/soc/intel/skylake/sd.c | 7 +- 5 files changed, 297 insertions(+), 142 deletions(-) diff --git a/src/arch/x86/acpi_device.c b/src/arch/x86/acpi_device.c index f8f6a6d..402d6d3 100644 --- a/src/arch/x86/acpi_device.c +++ b/src/arch/x86/acpi_device.c @@ -24,15 +24,6 @@ #include <gpio.h> #endif -/* - * Pointer to length field in device properties package - * Location is set in dp_header() and length filled in by dp_footer() - */ -static char *dp_count_ptr; - -/* Count of the number of device properties in the current set */ -static char dp_count; - /* Write empty word value and return pointer to it */ static void *acpi_device_write_zero_len(void) { @@ -473,39 +464,8 @@ void acpi_device_write_spi(const struct acpi_spi *spi) acpi_device_fill_len(desc_length); } -/* Write a header for using _DSD to export Device Properties */ -void acpi_dp_write_header(void) -{ - /* Name (_DSD) */ - acpigen_write_name("_DSD"); - - /* Package (2) */ - acpigen_write_package(2); - - /* ToUUID (ACPI_DP_UUID) */ - acpigen_write_uuid(ACPI_DP_UUID); - - /* Package (X) */ - acpigen_emit_byte(0x12); - acpigen_write_len_f(); - dp_count_ptr = acpigen_get_current(); - acpigen_emit_byte(0); /* Number of elements, filled by dp_footer */ - - /* Reset element counter */ - dp_count = 0; -} - -/* Fill in length values from writing Device Properties */ -void acpi_dp_write_footer(void) -{ - /* Patch device property element count */ - *dp_count_ptr = dp_count; - - acpigen_pop_len(); /* Inner package length */ - acpigen_pop_len(); /* Outer package length */ -} - -void acpi_dp_write_value(const struct acpi_dp *prop) +static void acpi_dp_write_array(const struct acpi_dp *array); +static void acpi_dp_write_value(const struct acpi_dp *prop) { switch (prop->type) { case ACPI_DP_TYPE_INTEGER: @@ -515,86 +475,237 @@ void acpi_dp_write_value(const struct acpi_dp *prop) acpigen_write_string(prop->string); break; case ACPI_DP_TYPE_REFERENCE: + case ACPI_DP_TYPE_CHILD: acpigen_emit_namestring(prop->string); break; + case ACPI_DP_TYPE_ARRAY: + acpi_dp_write_array(prop->child); + break; + default: + break; } } -/* Write Device Property key with value as an integer */ -void acpi_dp_write_keyval(const char *key, const struct acpi_dp *prop) +/* Package (2) { "prop->name", VALUE } */ +static void acpi_dp_write_property(const struct acpi_dp *prop) { acpigen_write_package(2); - acpigen_write_string(key); + acpigen_write_string(prop->name); acpi_dp_write_value(prop); acpigen_pop_len(); - dp_count++; } -/* Write Device Property key with value as an integer */ -void acpi_dp_write_integer(const char *key, uint64_t value) +/* Write array of Device Properties */ +static void acpi_dp_write_array(const struct acpi_dp *array) { - const struct acpi_dp prop = ACPI_DP_INTEGER(value); - acpi_dp_write_keyval(key, &prop); -} + const struct acpi_dp *dp; + char *pkg_count; -/* Write Device Property key with value as a string */ -void acpi_dp_write_string(const char *key, const char *value) -{ - const struct acpi_dp prop = ACPI_DP_STRING(value); - acpi_dp_write_keyval(key, &prop); + /* Package element count determined as it is populated */ + pkg_count = acpigen_write_package(0); + + for (dp = array; dp; dp = dp->next) { + acpi_dp_write_value(dp); + (*pkg_count)++; + } + + acpigen_pop_len(); } -/* Write Device Property key with value as a reference */ -void acpi_dp_write_reference(const char *key, const char *value) +static void acpi_dp_free(struct acpi_dp *dp) { - const struct acpi_dp prop = ACPI_DP_REFERENCE(value); - acpi_dp_write_keyval(key, &prop); + while (dp) { + struct acpi_dp *p = dp->next; + acpi_dp_free(dp->child); + free(dp); + dp = p; + } } -/* Write array of Device Properties */ -void acpi_dp_write_array(const char *key, const struct acpi_dp *array, int len) +void acpi_dp_write(struct acpi_dp *table) { - int i; - acpigen_write_package(2); - acpigen_write_string(key); - acpigen_write_package(len); - for (i = 0; i < len; i++) - acpi_dp_write_value(&array[i]); + struct acpi_dp *dp, *prop; + char *dp_count, *prop_count; + int child_count = 0; + + if (!table || table->type != ACPI_DP_TYPE_TABLE) + return; + + /* Name (name) */ + acpigen_write_name(table->name); + + /* Device Property list starts with the next entry */ + prop = table->next; + + /* Package (DP), default to 2 elements (assuming no children) */ + dp_count = acpigen_write_package(2); + + /* ToUUID (ACPI_DP_UUID) */ + acpigen_write_uuid(ACPI_DP_UUID); + + /* Package (PROP), element count determined as it is populated */ + prop_count = acpigen_write_package(0); + + /* Print base properties */ + for (dp = prop; dp; dp = dp->next) { + if (dp->type == ACPI_DP_TYPE_CHILD) { + child_count++; + } else { + (*prop_count)++; + acpi_dp_write_property(dp); + } + } + + /* Package (PROP) length */ acpigen_pop_len(); + + if (child_count) { + /* Update DP package count to 4 */ + *dp_count = 4; + + /* ToUUID (ACPI_DP_CHILD_UUID) */ + acpigen_write_uuid(ACPI_DP_CHILD_UUID); + + /* Print child pointer properties */ + acpigen_write_package(child_count); + + for (dp = prop; dp; dp = dp->next) + if (dp->type == ACPI_DP_TYPE_CHILD) + acpi_dp_write_property(dp); + + acpigen_pop_len(); + } + + /* Package (DP) length */ acpigen_pop_len(); - dp_count++; + + /* Recursively parse children into separate tables */ + for (dp = prop; dp; dp = dp->next) + if (dp->type == ACPI_DP_TYPE_CHILD) + acpi_dp_write(dp->child); + + /* Clean up */ + acpi_dp_free(table); } -/* Write array of Device Properties with values as integers */ -void acpi_dp_write_integer_array(const char *key, uint64_t *array, int len) +static struct acpi_dp *acpi_dp_new(struct acpi_dp *dp, enum acpi_dp_type type, + const char *name) { + struct acpi_dp *new; + + new = malloc(sizeof(struct acpi_dp)); + if (!new) + return NULL; + + memset(new, 0, sizeof(*new)); + new->type = type; + new->name = name; + + if (dp) { + /* Add to end of property list */ + while (dp->next) + dp = dp->next; + dp->next = new; + } + + return new; +} + +struct acpi_dp *acpi_dp_new_table(const char *name) +{ + return acpi_dp_new(NULL, ACPI_DP_TYPE_TABLE, name); +} + +struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name, + uint64_t value) +{ + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_INTEGER, name); + + if (new) + new->integer = value; + + return new; +} + +struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name, + const char *string) +{ + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_STRING, name); + + if (new) + new->string = string; + + return new; +} + +struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name, + const char *reference) +{ + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_REFERENCE, name); + + if (new) + new->string = reference; + + return new; +} + +struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name, + struct acpi_dp *child) +{ + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_CHILD, name); + + if (new) { + new->string = child->name; + new->child = child; + } + + return new; +} + +struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name, + uint64_t *array, int len) +{ + struct acpi_dp *dp_array; int i; - acpigen_write_package(2); - acpigen_write_string(key); - acpigen_write_package(len); - for (i = 0; i < len; i++) - acpigen_write_integer(array[i]); - acpigen_pop_len(); - acpigen_pop_len(); - dp_count++; + + if (len <= 0) + return NULL; + + /* Package (2) { name, ... } */ + dp_array = acpi_dp_new(dp, ACPI_DP_TYPE_ARRAY, name); + if (!dp_array) + return NULL; + + /* Package (len) { [0], [1], ... } */ + dp_array->child = acpi_dp_add_integer(NULL, NULL, array[0]); + for (i = 1; i < len; i++) + if (!acpi_dp_add_integer(dp_array->child, NULL, array[i])) + break; + + return dp_array; } -/* - * Device Properties for GPIO binding - * linux/Documentation/acpi/gpio-properties.txt - */ -void acpi_dp_write_gpio(const char *key, const char *ref, int index, - int pin, int active_low) +struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name, + const char *ref, int index, int pin, + int active_low) { - const struct acpi_dp gpio_prop[] = { - /* The device that has _CRS containing GpioIo()/GpioInt() */ - ACPI_DP_REFERENCE(ref), - /* Index of the GPIO resource in _CRS starting from zero */ - ACPI_DP_INTEGER(index), - /* Pin in the GPIO resource, typically zero */ - ACPI_DP_INTEGER(pin), - /* Set if pin is active low */ - ACPI_DP_INTEGER(active_low) - }; - acpi_dp_write_array(key, gpio_prop, ARRAY_SIZE(gpio_prop)); + struct acpi_dp *gpio; + + gpio = acpi_dp_new(dp, ACPI_DP_TYPE_ARRAY, name); + if (!gpio) + return NULL; + + /* The device that has _CRS containing GpioIO()/GpioInt() */ + gpio->child = acpi_dp_add_reference(NULL, NULL, ref); + + /* Index of the GPIO resource in _CRS starting from zero */ + acpi_dp_add_integer(gpio->child, NULL, index); + + /* Pin in the GPIO resource, typically zero */ + acpi_dp_add_integer(gpio->child, NULL, pin); + + /* Set if pin is active low */ + acpi_dp_add_integer(gpio->child, NULL, active_low); + + return gpio; } diff --git a/src/arch/x86/include/arch/acpi_device.h b/src/arch/x86/include/arch/acpi_device.h index 65f49b2..6ba904d 100644 --- a/src/arch/x86/include/arch/acpi_device.h +++ b/src/arch/x86/include/arch/acpi_device.h @@ -229,63 +229,103 @@ struct acpi_spi { void acpi_device_write_spi(const struct acpi_spi *spi); /* - * Device Properties with _DSD + * Writing Device Properties objects via _DSD + * *
http://uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.p…
+ *
http://uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extens…
+ * + * The Device Property Hierarchy can be multiple levels deep with multiple + * children possible in each level. In order to support this flexibility + * the device property hierarchy must be built up before being written out. + * + * For example: + * + * // Child table with string and integer + * struct acpi_dp *child = acpi_dp_new_table("CHLD"); + * acpi_dp_add_string(child, "childstring", "CHILD"); + * acpi_dp_add_integer(child, "childint", 100); + * + * // _DSD table with integer and gpio and child pointer + * struct acpi_dp *dsd = acpi_dp_new_table("_DSD"); + * acpi_dp_add_integer(dsd, "number1", 1); + * acpi_dp_add_gpio(dsd, "gpio", "\_SB.PCI0.GPIO", 0, 0, 1); + * acpi_dp_add_child(dsd, "child", "CHLD", child); + * + * // Write entries into SSDT and clean up resources + * acpi_dp_write(dsd); + * + * Name(_DSD, Package() { + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") + * Package() { + * Package() { "gpio", Package() { \_SB.PCI0.GPIO, 0, 0, 0 } } + * Package() { "number1", 1 } + * } + * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b") + * Package() { + * Package() { "child", CHLD } + * } + * } + * Name(CHLD, Package() { + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") + * Package() { + * Package() { "childstring", "CHILD" } + * Package() { "childint", 100 } + * } + * } */ -#define ACPI_DP_UUID "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" +#define ACPI_DP_UUID "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" +#define ACPI_DP_CHILD_UUID "dbb8e3e6-5886-4ba6-8795-1319f52a966b" enum acpi_dp_type { ACPI_DP_TYPE_INTEGER, ACPI_DP_TYPE_STRING, ACPI_DP_TYPE_REFERENCE, + ACPI_DP_TYPE_TABLE, + ACPI_DP_TYPE_ARRAY, + ACPI_DP_TYPE_CHILD, }; struct acpi_dp { enum acpi_dp_type type; + const char *name; + struct acpi_dp *next; + struct acpi_dp *child; union { uint64_t integer; const char *string; }; }; -#define ACPI_DP_INTEGER(x) { .type = ACPI_DP_TYPE_INTEGER, .integer = x } -#define ACPI_DP_STRING(x) { .type = ACPI_DP_TYPE_STRING, .string = x } -#define ACPI_DP_REFERENCE(x) { .type = ACPI_DP_TYPE_REFERENCE, .string = x } - -/* - * Writing Device Properties objects via _DSD - */ - -/* Start a set of Device Properties with _DSD and UUID */ -void acpi_dp_write_header(void); - -/* End the Device Properties set and fill in length values */ -void acpi_dp_write_footer(void); - -/* Write a Device Property value, but not the key */ -void acpi_dp_write_value(const struct acpi_dp *prop); +/* Start a new Device Property table with provided ACPI reference */ +struct acpi_dp *acpi_dp_new_table(const char *ref); -/* Write a Device Property, both key and value */ -void acpi_dp_write_keyval(const char *key, const struct acpi_dp *prop); +/* Add integer Device Property */ +struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name, + uint64_t value); -/* Write an integer as a Device Property */ -void acpi_dp_write_integer(const char *key, uint64_t value); +/* Add string Device Property */ +struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name, + const char *string); -/* Write a string as a Device Property */ -void acpi_dp_write_string(const char *key, const char *value); +/* Add ACPI reference Device Property */ +struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name, + const char *reference); -/* Write an ACPI reference as a Device Property */ -void acpi_dp_write_reference(const char *key, const char *value); +/* Add an array of integers Device Property */ +struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name, + uint64_t *array, int len); -/* Write an array of Device Properties */ -void acpi_dp_write_array(const char *key, const struct acpi_dp *array, int len); +/* Add a GPIO binding Device Property */ +struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name, + const char *ref, int index, int pin, + int active_low); -/* Write an array of integers as Device Properties */ -void acpi_dp_write_integer_array(const char *key, uint64_t *array, int len); +/* Add a child table of Device Properties */ +struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name, + struct acpi_dp *child); -/* Write a GPIO binding Device Property */ -void acpi_dp_write_gpio(const char *key, const char *ref, int index, - int pin, int active_low); +/* Write Device Property hierarchy and clean up resources */ +void acpi_dp_write(struct acpi_dp *table); #endif diff --git a/src/drivers/generic/max98357a/max98357a.c b/src/drivers/generic/max98357a/max98357a.c index 0d522d4..25e5104 100644 --- a/src/drivers/generic/max98357a/max98357a.c +++ b/src/drivers/generic/max98357a/max98357a.c @@ -32,6 +32,7 @@ static void max98357a_fill_ssdt(struct device *dev) { struct drivers_generic_max98357a_config *config = dev->chip_info; const char *path; + struct acpi_dp *dp; if (!dev->enabled || !config) return; @@ -51,12 +52,12 @@ static void max98357a_fill_ssdt(struct device *dev) acpigen_write_resourcetemplate_footer(); /* _DSD for devicetree properties */ - acpi_dp_write_header(); /* This points to the first pin in the first gpio entry in _CRS */ path = acpi_device_path(dev); - acpi_dp_write_gpio("sdmode-gpio", path, 0, 0, 0); - acpi_dp_write_integer("sdmode-delay", config->sdmode_delay); - acpi_dp_write_footer(); + dp = acpi_dp_new_table("_DSD"); + acpi_dp_add_gpio(dp, "sdmode-gpio", path, 0, 0, 0); + acpi_dp_add_integer(dp, "sdmode-delay", config->sdmode_delay); + acpi_dp_write(dp); acpigen_pop_len(); /* Device */ acpigen_pop_len(); /* Scope */ diff --git a/src/drivers/i2c/nau8825/nau8825.c b/src/drivers/i2c/nau8825/nau8825.c index 71aacea..a86eff4 100644 --- a/src/drivers/i2c/nau8825/nau8825.c +++ b/src/drivers/i2c/nau8825/nau8825.c @@ -28,7 +28,9 @@ #define NAU8825_ACPI_NAME "NAU8" #define NAU8825_ACPI_HID "10508825" -#define NAU8825_DP_INT(key,val) acpi_dp_write_integer("nuvoton," key, (val)) + +#define NAU8825_DP_INT(key,val) \ + acpi_dp_add_integer(dp, "nuvoton," key, (val)) static void nau8825_fill_ssdt(struct device *dev) { @@ -40,6 +42,7 @@ static void nau8825_fill_ssdt(struct device *dev) .speed = config->bus_speed ? : I2C_SPEED_FAST, .resource = scope, }; + struct acpi_dp *dp = NULL; if (!dev->enabled || !scope) return; @@ -62,7 +65,7 @@ static void nau8825_fill_ssdt(struct device *dev) acpigen_write_resourcetemplate_footer(); /* Device Properties */ - acpi_dp_write_header(); + dp = acpi_dp_new_table("_DSD"); NAU8825_DP_INT("jkdet-enable", config->jkdet_enable); NAU8825_DP_INT("jkdet-pull-enable", config->jkdet_pull_enable); NAU8825_DP_INT("jkdet-pull-up", config->jkdet_pull_up); @@ -77,10 +80,9 @@ static void nau8825_fill_ssdt(struct device *dev) NAU8825_DP_INT("jack-insert-debounce", config->jack_insert_debounce); NAU8825_DP_INT("jack-eject-deboune", config->jack_eject_debounce); NAU8825_DP_INT("sar-threshold-num", config->sar_threshold_num); - acpi_dp_write_integer_array("nuvoton,sar-threshold", - config->sar_threshold, - config->sar_threshold_num); - acpi_dp_write_footer(); + acpi_dp_add_integer_array(dp, "nuvoton,sar-threshold", + config->sar_threshold, config->sar_threshold_num); + acpi_dp_write(dp); acpigen_pop_len(); /* Device */ acpigen_pop_len(); /* Scope */ diff --git a/src/soc/intel/skylake/sd.c b/src/soc/intel/skylake/sd.c index 80adb9c..a75cf63 100644 --- a/src/soc/intel/skylake/sd.c +++ b/src/soc/intel/skylake/sd.c @@ -38,6 +38,7 @@ static void sd_fill_ssdt(struct device *dev) .pin_count = 1, .pins = { config->sdcard_cd_gpio_default } }; + struct acpi_dp *dp; if (!dev->enabled) return; @@ -62,9 +63,9 @@ static void sd_fill_ssdt(struct device *dev) acpigen_write_resourcetemplate_footer(); /* Bind the cd-gpio name to the GpioInt() resource */ - acpi_dp_write_header(); - acpi_dp_write_gpio("cd-gpio", path, 0, 0, 1); - acpi_dp_write_footer(); + dp = acpi_dp_new_table("_DSD"); + acpi_dp_add_gpio(dp, "cd-gpio", path, 0, 0, 1); + acpi_dp_write(dp); acpigen_pop_len(); }
1
0
0
0
Patch set updated for coreboot: drivers/i2c/da7219: Add driver for generating device in SSDT
by Duncan Laurie
03 Jul '16
03 Jul '16
Duncan Laurie (dlaurie(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/15538
-gerrit commit 0e54c264753be1c51c0c769dd9815265f04ed582 Author: Duncan Laurie <dlaurie(a)chromium.org> Date: Sat Jul 2 20:00:56 2016 -0700 drivers/i2c/da7219: Add driver for generating device in SSDT Add a device driver to generate the device and required properties into the SSDT. This driver uses the ACPI Device Property interface to generate the required parameters into the _DSD table format expected by the kernel. This was tested on the reef mainboard to ensure that the SSDT contained the equivalent parameters that are provided by the current DSDT object. Change-Id: Ia809e953932a7e127352a7ef193974d95e511565 Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org> --- src/drivers/i2c/da7219/Kconfig | 2 + src/drivers/i2c/da7219/Makefile.inc | 1 + src/drivers/i2c/da7219/chip.h | 106 +++++++++++++++++++++++++++++++ src/drivers/i2c/da7219/da7219.c | 122 ++++++++++++++++++++++++++++++++++++ 4 files changed, 231 insertions(+) diff --git a/src/drivers/i2c/da7219/Kconfig b/src/drivers/i2c/da7219/Kconfig new file mode 100644 index 0000000..5539af1 --- /dev/null +++ b/src/drivers/i2c/da7219/Kconfig @@ -0,0 +1,2 @@ +config DRIVERS_I2C_DA7219 + bool diff --git a/src/drivers/i2c/da7219/Makefile.inc b/src/drivers/i2c/da7219/Makefile.inc new file mode 100644 index 0000000..354a330 --- /dev/null +++ b/src/drivers/i2c/da7219/Makefile.inc @@ -0,0 +1 @@ +ramstage-$(CONFIG_DRIVERS_I2C_DA7219) += da7219.c diff --git a/src/drivers/i2c/da7219/chip.h b/src/drivers/i2c/da7219/chip.h new file mode 100644 index 0000000..823b940 --- /dev/null +++ b/src/drivers/i2c/da7219/chip.h @@ -0,0 +1,106 @@ +#include <arch/acpi_device.h> + +/* + * Dialog Semiconductor DA7219 Audio Codec devicetree bindings + * linux/Documentation/devicetree/bindings/sound/da7219.txt + */ +struct drivers_i2c_da7219_config { + /* Interrupt configuration */ + struct acpi_irq irq; + + /* I2C Bus Frequency in Hertz (default 400kHz) */ + unsigned bus_speed; + + /* + * micbias-lvl : Voltage (mV) for Mic Bias + * [<1600>, <1800>, <2000>, <2200>, <2400>, <2600>] + */ + unsigned micbias_lvl; + + /* + * mic-amp-in-sel : Mic input source type + * ["diff", "se_p", "se_n"] + */ + const char *mic_amp_in_sel; + + /* + * Properties for da7219_aad child node + */ + + /* + * micbias-pulse-lvl : Mic bias higher voltage pulse level (mV) + * [<2800>, <2900>] + */ + unsigned micbias_pulse_lvl; + + /* + * micbias-pulse-time : Mic bias higher voltage pulse duration (ms) + */ + unsigned micbias_pulse_time; + + /* + * btn-cfg : Periodic button press measurements for 4-pole jack (ms) + * [<2>, <5>, <10>, <50>, <100>, <200>, <500>] + */ + unsigned btn_cfg; + + /* + * mic-det-thr : Impedance threshold for mic detection measurement (Ohms) + * [<200>, <500>, <750>, <1000>] + */ + unsigned mic_det_thr; + + /* + * jack-ins-deb : Debounce time for jack insertion (ms) + * [<5>, <10>, <20>, <50>, <100>, <200>, <500>, <1000>] + */ + unsigned jack_ins_deb; + + /* + * jack-det-rate : Jack type detection latency (3/4 pole) + * ["32ms_64ms", "64ms_128ms", "128ms_256ms", "256ms_512ms"] + */ + const char *jack_det_rate; + + /* + * jack-rem-deb : Debounce time for jack removal (ms) + * [<1>, <5>, <10>, <20>] + */ + unsigned jack_rem_deb; + + /* + * a-d-btn-thr : Impedance threshold between buttons A and D + * [0x0 - 0xFF] + */ + unsigned a_d_btn_thr; + + /* + * d-b-btn-thr : Impedance threshold between buttons D and B + * [0x0 - 0xFF] + */ + unsigned d_b_btn_thr; + + /* + * b-c-btn-thr : Impedance threshold between buttons B and C + * [0x0 - 0xFF] + */ + unsigned b_c_btn_thr; + + /* + * c-mic-btn-thr : Impedance threshold between button C and Mic + * [0x0 - 0xFF] + */ + unsigned c_mic_btn_thr; + + /* + * btn-avg : Number of 8-bit readings for averaged button measurement + * [<1>, <2>, <4>, <8>] + */ + unsigned btn_avg; + + /* + * adc-1bit-rpt : Repeat count for 1-bit button measurement + * [<1>, <2>, <4>, <8>] + */ + unsigned adc_1bit_rpt; +}; diff --git a/src/drivers/i2c/da7219/da7219.c b/src/drivers/i2c/da7219/da7219.c new file mode 100644 index 0000000..54cadfc --- /dev/null +++ b/src/drivers/i2c/da7219/da7219.c @@ -0,0 +1,122 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2016 Google Inc. + * + * 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 <arch/acpi.h> +#include <arch/acpi_device.h> +#include <arch/acpigen.h> +#include <console/console.h> +#include <device/i2c.h> +#include <device/device.h> +#include <device/path.h> +#include <stdint.h> +#include <string.h> +#include "chip.h" + +#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) + +#define DA7219_ACPI_NAME "DLG7" +#define DA7219_ACPI_HID "DLGS7219" + +static void da7219_fill_ssdt(struct device *dev) +{ + struct drivers_i2c_da7219_config *config = dev->chip_info; + const char *scope = acpi_device_scope(dev); + struct acpi_i2c i2c = { + .address = dev->path.i2c.device, + .mode_10bit = dev->path.i2c.mode_10bit, + .speed = config->bus_speed ? : I2C_SPEED_FAST, + .resource = scope, + }; + struct acpi_dp *da7219, *aad; + + if (!dev->enabled || !scope) + return; + + /* Device */ + acpigen_write_scope(scope); + acpigen_write_device(acpi_device_name(dev)); + acpigen_write_name_string("_HID", DA7219_ACPI_HID); + acpigen_write_name_integer("_UID", 1); + acpigen_write_name_string("_DDN", dev->chip_ops->name); + acpigen_write_name_integer("_S0W", 4); + acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON); + + /* Resources */ + acpigen_write_name("_CRS"); + acpigen_write_resourcetemplate_header(); + acpi_device_write_i2c(&i2c); + acpi_device_write_interrupt(&config->irq); + acpigen_write_resourcetemplate_footer(); + + /* AAD Child Device Properties */ + aad = acpi_dp_add_integer(NULL, "dlg,btn-cfg", config->btn_cfg); + acpi_dp_add_integer(aad, "dlg,mic-det-thr", config->mic_det_thr); + acpi_dp_add_integer(aad, "dlg,jack-ins-deb", config->jack_ins_deb); + acpi_dp_add_string(aad, "dlg,jack-det-rate", config->jack_det_rate); + acpi_dp_add_integer(aad, "dlg,jack-rem-deb", config->jack_rem_deb); + acpi_dp_add_integer(aad, "dlg,a-d-btn-thr", config->a_d_btn_thr); + acpi_dp_add_integer(aad, "dlg,d-b-btn-thr", config->d_b_btn_thr); + acpi_dp_add_integer(aad, "dlg,b-c-btn-thr", config->b_c_btn_thr); + acpi_dp_add_integer(aad, "dlg,c-mic-btn-thr", config->c_mic_btn_thr); + acpi_dp_add_integer(aad, "dlg,btn-avg", config->btn_avg); + acpi_dp_add_integer(aad, "dlg,adc-1bit-rpt", config->adc_1bit_rpt); + acpi_dp_add_integer(aad, "dlg,micbias-pulse-lvl", + config->micbias_pulse_lvl); + acpi_dp_add_integer(aad, "dlg,micbias-pulse-time", + config->micbias_pulse_time); + + /* DA7219 Properties */ + da7219 = acpi_dp_add_integer(NULL, "dlg,micbias-lvl", + config->micbias_lvl); + acpi_dp_add_string(da7219, "dlg,mic-amp-in-sel", + config->mic_amp_in_sel); + acpi_dp_add_child(da7219, "da7219_aad", "DAAD", aad); + + /* Write Device Property Hierarchy */ + acpi_dp_write("_DSD", da7219); + + acpigen_pop_len(); /* Device */ + acpigen_pop_len(); /* Scope */ + + printk(BIOS_INFO, "%s: %s address 0%xh irq %d\n", + acpi_device_path(dev), dev->chip_ops->name, + dev->path.i2c.device, config->irq.pin); +} + +static const char *da7219_acpi_name(struct device *dev) +{ + return DA7219_ACPI_NAME; +} +#endif + +static struct device_operations da7219_ops = { + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, + .enable_resources = DEVICE_NOOP, +#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) + .acpi_name = &da7219_acpi_name, + .acpi_fill_ssdt_generator = &da7219_fill_ssdt, +#endif +}; + +static void da7219_enable(struct device *dev) +{ + dev->ops = &da7219_ops; +} + +struct chip_operations drivers_i2c_da7219_ops = { + CHIP_NAME("Dialog Semiconductor DA7219 Audio Codec") + .enable_dev = &da7219_enable +};
1
0
0
0
Patch set updated for coreboot: mainboard/google/reef: Use device driver for DA7219 configuration
by Duncan Laurie
03 Jul '16
03 Jul '16
Duncan Laurie (dlaurie(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/15539
-gerrit commit 66d8e06ab4436a00253c4827f92f8145d4ce9d52 Author: Duncan Laurie <dlaurie(a)chromium.org> Date: Sat Jul 2 20:05:43 2016 -0700 mainboard/google/reef: Use device driver for DA7219 configuration Use the device driver for DA7219 device configuration in the SSDT and remove the static copy in the DSDT. Tested on reef to ensure that the generated SSDT contents are equivalent to the current DSDT contents. Change-Id: I288eb05d0cb3f5310c4dca4aa1eab5a029f216af Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org> --- src/mainboard/google/reef/Kconfig | 3 ++ src/mainboard/google/reef/acpi/mainboard.asl | 60 ---------------------------- src/mainboard/google/reef/devicetree.cb | 20 +++++++++- 3 files changed, 22 insertions(+), 61 deletions(-) diff --git a/src/mainboard/google/reef/Kconfig b/src/mainboard/google/reef/Kconfig index 194a6ba..3ca1af1 100644 --- a/src/mainboard/google/reef/Kconfig +++ b/src/mainboard/google/reef/Kconfig @@ -25,6 +25,9 @@ config CHROMEOS select VBOOT_OPROM_MATTERS select VIRTUAL_DEV_SWITCH +config DRIVERS_I2C_DA7219 + default y + config DRIVERS_I2C_GENERIC default y diff --git a/src/mainboard/google/reef/acpi/mainboard.asl b/src/mainboard/google/reef/acpi/mainboard.asl index 6e6d61f..5b6e976 100644 --- a/src/mainboard/google/reef/acpi/mainboard.asl +++ b/src/mainboard/google/reef/acpi/mainboard.asl @@ -38,63 +38,3 @@ Scope (\_SB.PCI0.LPCB) /* Chrome OS Embedded Controller */ #include "ec.asl" } - -Scope (\_SB.PCI0.I2C0) -{ - /* Headphone Codec */ - Device (HPDA) - { - Name (_HID, "DLGS7219") - Name (_DDN, "Dialog DA7219 Codec") - Name (_UID, 1) - Name (_S0W, 4) - Name (_DSD, Package () { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package () { - Package () { "dlg,micbias-lvl", 2600 }, - Package () { "dlg,mic-amp-in-sel", "diff" }, - }, - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package () { - Package () {"da7219_aad", "DAAD"}, - } - }) - - Name (DAAD, Package () { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package () { - Package () { "dlg,btn-cfg", 50 }, - Package () { "dlg,mic-det-thr", 500 }, - Package () { "dlg,jack-ins-deb", 20 }, - Package () { "dlg,jack-det-rate", "32ms_64ms" }, - Package () { "dlg,jack-rem-deb", 1 }, - Package () { "dlg,a-d-btn-thr", 0xa }, - Package () { "dlg,d-b-btn-thr", 0x16 }, - Package () { "dlg,b-c-btn-thr", 0x21 }, - Package () { "dlg,c-mic-btn-thr", 0x3E }, - Package () { "dlg,btn-avg", 4 }, - Package () { "dlg,adc-1bit-rpt", 1 }, - } - }) - - Name (_CRS, ResourceTemplate() - { - I2cSerialBus ( - BOARD_HP_MIC_CODEC_I2C_ADDR, - ControllerInitiated, - 400000, - AddressingMode7Bit, - "\\_SB.PCI0.I2C0", - ) - Interrupt (ResourceConsumer, Level, ActiveLow) - { - BOARD_HP_MIC_CODEC_IRQ - } - }) - - Method (_STA) - { - Return (0xF) - } - } -} diff --git a/src/mainboard/google/reef/devicetree.cb b/src/mainboard/google/reef/devicetree.cb index e0831f4..b931a89 100644 --- a/src/mainboard/google/reef/devicetree.cb +++ b/src/mainboard/google/reef/devicetree.cb @@ -57,7 +57,25 @@ chip soc/intel/apollolake device pci 14.1 off end # - Root Port 1 - PCIe-B 1 device pci 15.0 on end # - XHCI device pci 15.1 off end # - XDCI - device pci 16.0 on end # - I2C 0 + device pci 16.0 on # - I2C 0 + chip drivers/i2c/da7219 + register "irq" = "IRQ_LEVEL_LOW(GPIO_116_IRQ)" + register "btn_cfg" = "50" + register "mic_det_thr" = "500" + register "jack_ins_deb" = "20" + register "jack_det_rate" = ""32ms_64ms"" + register "jack_rem_deb" = "1" + register "a_d_btn_thr" = "0xa" + register "d_b_btn_thr" = "0x16" + register "b_c_btn_thr" = "0x21" + register "c_mic_btn_thr" = "0x3e" + register "btn_avg" = "4" + register "adc_1bit_rpt" = "1" + register "micbias_lvl" = "2600" + register "mic_amp_in_sel" = ""diff"" + device i2c 1a on end + end + end device pci 16.1 on end # - I2C 1 device pci 16.2 on end # - I2C 2 device pci 16.3 on end # - I2C 3
1
0
0
0
Patch set updated for coreboot: acpigen_write_package: Return pointer to package element counter
by Duncan Laurie
03 Jul '16
03 Jul '16
Duncan Laurie (dlaurie(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/15536
-gerrit commit 5ee5ce32ad2920789b5ab545912321676f9406c5 Author: Duncan Laurie <dlaurie(a)chromium.org> Date: Sat Jul 2 19:53:54 2016 -0700 acpigen_write_package: Return pointer to package element counter Have acpigen_write_package() return a pointer to the package element counter so it can be used for dynamic package generation where needed. Change-Id: Id7f6dd03511069211ba3ee3eb29a6ca1742de847 Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org> --- src/arch/x86/acpigen.c | 5 ++++- src/arch/x86/include/arch/acpigen.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/acpigen.c b/src/arch/x86/acpigen.c index c370321..d37568c 100644 --- a/src/arch/x86/acpigen.c +++ b/src/arch/x86/acpigen.c @@ -87,12 +87,15 @@ void acpigen_emit_dword(unsigned int data) acpigen_emit_byte((data >> 24) & 0xff); } -void acpigen_write_package(int nr_el) +char *acpigen_write_package(int nr_el) { + char *p; /* package op */ acpigen_emit_byte(0x12); acpigen_write_len_f(); + p = acpigen_get_current(); acpigen_emit_byte(nr_el); + return p; } void acpigen_write_byte(unsigned int data) diff --git a/src/arch/x86/include/arch/acpigen.h b/src/arch/x86/include/arch/acpigen.h index 9e6ef29..9035f27 100644 --- a/src/arch/x86/include/arch/acpigen.h +++ b/src/arch/x86/include/arch/acpigen.h @@ -38,7 +38,7 @@ void acpigen_write_len_f(void); void acpigen_pop_len(void); void acpigen_set_current(char *curr); char *acpigen_get_current(void); -void acpigen_write_package(int nr_el); +char *acpigen_write_package(int nr_el); void acpigen_write_zero(void); void acpigen_write_one(void); void acpigen_write_ones(void);
1
0
0
0
Patch set updated for coreboot: acpi: Change device properties to work as a tree
by Duncan Laurie
03 Jul '16
03 Jul '16
Duncan Laurie (dlaurie(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/15537
-gerrit commit 590d62392c856de48d179b066e4c60600a35a117 Author: Duncan Laurie <dlaurie(a)chromium.org> Date: Sat Jul 2 19:56:06 2016 -0700 acpi: Change device properties to work as a tree There is a second ACPI _DSD document from the UEFI Forum that details how _DSD style tables can be nested, creating a tree of similarly formatted tables. This document is linked from acpi_device.h. In order to support this the device property interface needs to be more flexible and build up a tree of properties to write all entries at once instead of writing each entry as it is generated. In the end this is a more flexible solution that can support drivers that need child tables like the DA7219 codec, while only requiring minor changes to the existing drivers that use the device property interface. This was tested on reef (apollolake) and chell (skylake) boards to ensure that there was no change in the generated SSDT AML. Change-Id: Ia22e3a5fd3982ffa7c324bee1a8d190d49f853dd Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org> --- src/arch/x86/acpi_device.c | 292 ++++++++++++++++++++---------- src/arch/x86/include/arch/acpi_device.h | 102 +++++++---- src/drivers/generic/max98357a/max98357a.c | 8 +- src/drivers/i2c/nau8825/nau8825.c | 15 +- src/soc/intel/skylake/sd.c | 6 +- 5 files changed, 279 insertions(+), 144 deletions(-) diff --git a/src/arch/x86/acpi_device.c b/src/arch/x86/acpi_device.c index f8f6a6d..683ba5d 100644 --- a/src/arch/x86/acpi_device.c +++ b/src/arch/x86/acpi_device.c @@ -24,15 +24,6 @@ #include <gpio.h> #endif -/* - * Pointer to length field in device properties package - * Location is set in dp_header() and length filled in by dp_footer() - */ -static char *dp_count_ptr; - -/* Count of the number of device properties in the current set */ -static char dp_count; - /* Write empty word value and return pointer to it */ static void *acpi_device_write_zero_len(void) { @@ -473,39 +464,8 @@ void acpi_device_write_spi(const struct acpi_spi *spi) acpi_device_fill_len(desc_length); } -/* Write a header for using _DSD to export Device Properties */ -void acpi_dp_write_header(void) -{ - /* Name (_DSD) */ - acpigen_write_name("_DSD"); - - /* Package (2) */ - acpigen_write_package(2); - - /* ToUUID (ACPI_DP_UUID) */ - acpigen_write_uuid(ACPI_DP_UUID); - - /* Package (X) */ - acpigen_emit_byte(0x12); - acpigen_write_len_f(); - dp_count_ptr = acpigen_get_current(); - acpigen_emit_byte(0); /* Number of elements, filled by dp_footer */ - - /* Reset element counter */ - dp_count = 0; -} - -/* Fill in length values from writing Device Properties */ -void acpi_dp_write_footer(void) -{ - /* Patch device property element count */ - *dp_count_ptr = dp_count; - - acpigen_pop_len(); /* Inner package length */ - acpigen_pop_len(); /* Outer package length */ -} - -void acpi_dp_write_value(const struct acpi_dp *prop) +static void acpi_dp_write_array(const struct acpi_dp *array); +static void acpi_dp_write_value(const struct acpi_dp *prop) { switch (prop->type) { case ACPI_DP_TYPE_INTEGER: @@ -515,86 +475,226 @@ void acpi_dp_write_value(const struct acpi_dp *prop) acpigen_write_string(prop->string); break; case ACPI_DP_TYPE_REFERENCE: + case ACPI_DP_TYPE_CHILD: acpigen_emit_namestring(prop->string); break; + case ACPI_DP_TYPE_ARRAY: + acpi_dp_write_array(prop->child); + break; + default: + break; } } -/* Write Device Property key with value as an integer */ -void acpi_dp_write_keyval(const char *key, const struct acpi_dp *prop) +/* Package (2) { "prop->name", VALUE } */ +static void acpi_dp_write_property(const struct acpi_dp *prop) { acpigen_write_package(2); - acpigen_write_string(key); + acpigen_write_string(prop->name); acpi_dp_write_value(prop); acpigen_pop_len(); - dp_count++; } -/* Write Device Property key with value as an integer */ -void acpi_dp_write_integer(const char *key, uint64_t value) +/* Write array of Device Properties */ +static void acpi_dp_write_array(const struct acpi_dp *array) { - const struct acpi_dp prop = ACPI_DP_INTEGER(value); - acpi_dp_write_keyval(key, &prop); -} + const struct acpi_dp *dp; + char *pkg_count; -/* Write Device Property key with value as a string */ -void acpi_dp_write_string(const char *key, const char *value) -{ - const struct acpi_dp prop = ACPI_DP_STRING(value); - acpi_dp_write_keyval(key, &prop); + /* Package element count determined as it is populated */ + pkg_count = acpigen_write_package(0); + + for (dp = array; dp; dp = dp->next) { + acpi_dp_write_value(dp); + (*pkg_count)++; + } + + acpigen_pop_len(); } -/* Write Device Property key with value as a reference */ -void acpi_dp_write_reference(const char *key, const char *value) +static void acpi_dp_free(struct acpi_dp *dp) { - const struct acpi_dp prop = ACPI_DP_REFERENCE(value); - acpi_dp_write_keyval(key, &prop); + while (dp) { + struct acpi_dp *p = dp->next; + acpi_dp_free(dp->child); + free(dp); + dp = p; + } } -/* Write array of Device Properties */ -void acpi_dp_write_array(const char *key, const struct acpi_dp *array, int len) +void acpi_dp_write(const char *name, struct acpi_dp *prop) { - int i; - acpigen_write_package(2); - acpigen_write_string(key); - acpigen_write_package(len); - for (i = 0; i < len; i++) - acpi_dp_write_value(&array[i]); + struct acpi_dp *dp; + char *dp_count, *prop_count; + int child_count = 0; + + /* Name (name) */ + acpigen_write_name(name); + + /* Package (DP), default to 2 elements (assuming no children) */ + dp_count = acpigen_write_package(2); + + /* ToUUID (ACPI_DP_UUID) */ + acpigen_write_uuid(ACPI_DP_UUID); + + /* Package (PROP), element count determined as it is populated */ + prop_count = acpigen_write_package(0); + + /* Print base properties */ + for (dp = prop; dp; dp = dp->next) { + if (dp->type == ACPI_DP_TYPE_CHILD) { + child_count++; + } else { + (*prop_count)++; + acpi_dp_write_property(dp); + } + } + + /* Package (PROP) length */ acpigen_pop_len(); + + if (child_count) { + /* Update DP package count to 4 */ + *dp_count = 4; + + /* ToUUID (ACPI_DP_CHILD_UUID) */ + acpigen_write_uuid(ACPI_DP_CHILD_UUID); + + /* Print child pointer properties */ + acpigen_write_package(child_count); + + for (dp = prop; dp; dp = dp->next) + if (dp->type == ACPI_DP_TYPE_CHILD) + acpi_dp_write_property(dp); + + acpigen_pop_len(); + } + + /* Package (DP) length */ acpigen_pop_len(); - dp_count++; + + /* Recursively parse children into separate tables */ + for (dp = prop; dp; dp = dp->next) + if (dp->type == ACPI_DP_TYPE_CHILD) + acpi_dp_write(dp->string, dp->child); + + /* Clean up */ + acpi_dp_free(prop); } -/* Write array of Device Properties with values as integers */ -void acpi_dp_write_integer_array(const char *key, uint64_t *array, int len) +static struct acpi_dp *acpi_dp_new(struct acpi_dp *dp, enum acpi_dp_type type, + const char *name) { + struct acpi_dp *new; + + new = malloc(sizeof(struct acpi_dp)); + if (!new) + return NULL; + + memset(new, 0, sizeof(*new)); + new->type = type; + new->name = name; + + if (dp) { + /* Add to end of property list */ + while (dp->next) + dp = dp->next; + dp->next = new; + } + + return new; +} + +struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name, + uint64_t value) +{ + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_INTEGER, name); + + if (new) + new->integer = value; + + return new; +} + +struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name, + const char *string) +{ + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_STRING, name); + + if (new) + new->string = string; + + return new; +} + +struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name, + const char *reference) +{ + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_REFERENCE, name); + + if (new) + new->string = reference; + + return new; +} + +struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name, + const char *ref, struct acpi_dp *child) +{ + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_CHILD, name); + + if (new) { + new->string = ref; + new->child = child; + } + + return new; +} + +struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name, + uint64_t *array, int len) +{ + struct acpi_dp *dp_array; int i; - acpigen_write_package(2); - acpigen_write_string(key); - acpigen_write_package(len); - for (i = 0; i < len; i++) - acpigen_write_integer(array[i]); - acpigen_pop_len(); - acpigen_pop_len(); - dp_count++; + + if (len <= 0) + return NULL; + + /* Package (2) { name, ... } */ + dp_array = acpi_dp_new(dp, ACPI_DP_TYPE_ARRAY, name); + if (!dp_array) + return NULL; + + /* Package (len) { [0], [1], ... } */ + dp_array->child = acpi_dp_add_integer(NULL, NULL, array[0]); + for (i = 1; i < len; i++) + if (!acpi_dp_add_integer(dp_array->child, NULL, array[i])) + break; + + return dp_array; } -/* - * Device Properties for GPIO binding - * linux/Documentation/acpi/gpio-properties.txt - */ -void acpi_dp_write_gpio(const char *key, const char *ref, int index, - int pin, int active_low) +struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name, + const char *ref, int index, int pin, + int active_low) { - const struct acpi_dp gpio_prop[] = { - /* The device that has _CRS containing GpioIo()/GpioInt() */ - ACPI_DP_REFERENCE(ref), - /* Index of the GPIO resource in _CRS starting from zero */ - ACPI_DP_INTEGER(index), - /* Pin in the GPIO resource, typically zero */ - ACPI_DP_INTEGER(pin), - /* Set if pin is active low */ - ACPI_DP_INTEGER(active_low) - }; - acpi_dp_write_array(key, gpio_prop, ARRAY_SIZE(gpio_prop)); + struct acpi_dp *gpio; + + gpio = acpi_dp_new(dp, ACPI_DP_TYPE_ARRAY, name); + if (!gpio) + return NULL; + + /* The device that has _CRS containing GpioIO()/GpioInt() */ + gpio->child = acpi_dp_add_reference(NULL, NULL, ref); + + /* Index of the GPIO resource in _CRS starting from zero */ + acpi_dp_add_integer(gpio->child, NULL, index); + + /* Pin in the GPIO resource, typically zero */ + acpi_dp_add_integer(gpio->child, NULL, pin); + + /* Set if pin is active low */ + acpi_dp_add_integer(gpio->child, NULL, active_low); + + return gpio; } diff --git a/src/arch/x86/include/arch/acpi_device.h b/src/arch/x86/include/arch/acpi_device.h index 65f49b2..e6b13e1 100644 --- a/src/arch/x86/include/arch/acpi_device.h +++ b/src/arch/x86/include/arch/acpi_device.h @@ -229,63 +229,97 @@ struct acpi_spi { void acpi_device_write_spi(const struct acpi_spi *spi); /* - * Device Properties with _DSD + * Writing Device Properties objects via _DSD + * *
http://uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.p…
+ *
http://uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extens…
+ * + * The Device Property Hierarchy can be multiple levels deep with multiple + * children possible in each level. In order to support this flexibility + * the device property hierarchy must be built up before being written out. + * + * For example: + * + * // Child table with string and integer + * struct acpi_dp *child = acpi_dp_add_string(NULL, "childstring", "CHILD"); + * acpi_dp_add_integer(child, "childint", 100); + * + * // _DSD table with integer and gpio and child pointer + * struct acpi_dp *dsd = acpi_dp_add_integer(NULL, "number1", 1); + * acpi_dp_add_gpio(dsd, "gpio", "\_SB.PCI0.GPIO", 0, 0, 1); + * acpi_dp_add_child(dsd, "child", "CHLD", child); + * + * // Write into SSDT and clean up resources + * acpi_dp_write("_DSD", dsd); + * + * Name(_DSD, Package() { + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") + * Package() { + * Package() { "gpio", Package() { \_SB.PCI0.GPIO, 0, 0, 0 } } + * Package() { "number1", 1 } + * } + * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b") + * Package() { + * Package() { "child", CHLD } + * } + * } + * Name(CHLD, Package() { + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") + * Package() { + * Package() { "childstring", "CHILD" } + * Package() { "childint", 100 } + * } + * } */ -#define ACPI_DP_UUID "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" +#define ACPI_DP_UUID "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" +#define ACPI_DP_CHILD_UUID "dbb8e3e6-5886-4ba6-8795-1319f52a966b" enum acpi_dp_type { ACPI_DP_TYPE_INTEGER, ACPI_DP_TYPE_STRING, ACPI_DP_TYPE_REFERENCE, + ACPI_DP_TYPE_ARRAY, + ACPI_DP_TYPE_CHILD, }; struct acpi_dp { enum acpi_dp_type type; + const char *name; + struct acpi_dp *next; + struct acpi_dp *child; union { uint64_t integer; const char *string; }; }; -#define ACPI_DP_INTEGER(x) { .type = ACPI_DP_TYPE_INTEGER, .integer = x } -#define ACPI_DP_STRING(x) { .type = ACPI_DP_TYPE_STRING, .string = x } -#define ACPI_DP_REFERENCE(x) { .type = ACPI_DP_TYPE_REFERENCE, .string = x } - -/* - * Writing Device Properties objects via _DSD - */ - -/* Start a set of Device Properties with _DSD and UUID */ -void acpi_dp_write_header(void); - -/* End the Device Properties set and fill in length values */ -void acpi_dp_write_footer(void); - -/* Write a Device Property value, but not the key */ -void acpi_dp_write_value(const struct acpi_dp *prop); - -/* Write a Device Property, both key and value */ -void acpi_dp_write_keyval(const char *key, const struct acpi_dp *prop); +/* Add integer Device Property */ +struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name, + uint64_t value); -/* Write an integer as a Device Property */ -void acpi_dp_write_integer(const char *key, uint64_t value); +/* Add string Device Property */ +struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name, + const char *string); -/* Write a string as a Device Property */ -void acpi_dp_write_string(const char *key, const char *value); +/* Add ACPI reference Device Property */ +struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name, + const char *reference); -/* Write an ACPI reference as a Device Property */ -void acpi_dp_write_reference(const char *key, const char *value); +/* Add an array of integers Device Property */ +struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name, + uint64_t *array, int len); -/* Write an array of Device Properties */ -void acpi_dp_write_array(const char *key, const struct acpi_dp *array, int len); +/* Add a GPIO binding Device Property */ +struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name, + const char *ref, int index, int pin, + int active_low); -/* Write an array of integers as Device Properties */ -void acpi_dp_write_integer_array(const char *key, uint64_t *array, int len); +/* Add a child list of Device Properties */ +struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name, + const char *ref, struct acpi_dp *child); -/* Write a GPIO binding Device Property */ -void acpi_dp_write_gpio(const char *key, const char *ref, int index, - int pin, int active_low); +/* Write Device Property hierarchy and clean up resources */ +void acpi_dp_write(const char *name, struct acpi_dp *prop); #endif diff --git a/src/drivers/generic/max98357a/max98357a.c b/src/drivers/generic/max98357a/max98357a.c index 0d522d4..ea20f59 100644 --- a/src/drivers/generic/max98357a/max98357a.c +++ b/src/drivers/generic/max98357a/max98357a.c @@ -32,6 +32,7 @@ static void max98357a_fill_ssdt(struct device *dev) { struct drivers_generic_max98357a_config *config = dev->chip_info; const char *path; + struct acpi_dp *dp; if (!dev->enabled || !config) return; @@ -51,12 +52,11 @@ static void max98357a_fill_ssdt(struct device *dev) acpigen_write_resourcetemplate_footer(); /* _DSD for devicetree properties */ - acpi_dp_write_header(); /* This points to the first pin in the first gpio entry in _CRS */ path = acpi_device_path(dev); - acpi_dp_write_gpio("sdmode-gpio", path, 0, 0, 0); - acpi_dp_write_integer("sdmode-delay", config->sdmode_delay); - acpi_dp_write_footer(); + dp = acpi_dp_add_gpio(NULL, "sdmode-gpio", path, 0, 0, 0); + acpi_dp_add_integer(dp, "sdmode-delay", config->sdmode_delay); + acpi_dp_write("_DSD", dp); acpigen_pop_len(); /* Device */ acpigen_pop_len(); /* Scope */ diff --git a/src/drivers/i2c/nau8825/nau8825.c b/src/drivers/i2c/nau8825/nau8825.c index 71aacea..ccbfdec 100644 --- a/src/drivers/i2c/nau8825/nau8825.c +++ b/src/drivers/i2c/nau8825/nau8825.c @@ -28,7 +28,9 @@ #define NAU8825_ACPI_NAME "NAU8" #define NAU8825_ACPI_HID "10508825" -#define NAU8825_DP_INT(key,val) acpi_dp_write_integer("nuvoton," key, (val)) + +#define NAU8825_DP_INT(key,val) \ + acpi_dp_add_integer(dp, "nuvoton," key, (val)) static void nau8825_fill_ssdt(struct device *dev) { @@ -40,6 +42,7 @@ static void nau8825_fill_ssdt(struct device *dev) .speed = config->bus_speed ? : I2C_SPEED_FAST, .resource = scope, }; + struct acpi_dp *dp = NULL; if (!dev->enabled || !scope) return; @@ -62,8 +65,7 @@ static void nau8825_fill_ssdt(struct device *dev) acpigen_write_resourcetemplate_footer(); /* Device Properties */ - acpi_dp_write_header(); - NAU8825_DP_INT("jkdet-enable", config->jkdet_enable); + dp = NAU8825_DP_INT("jkdet-enable", config->jkdet_enable); NAU8825_DP_INT("jkdet-pull-enable", config->jkdet_pull_enable); NAU8825_DP_INT("jkdet-pull-up", config->jkdet_pull_up); NAU8825_DP_INT("jkdet-polarity", config->jkdet_polarity); @@ -77,10 +79,9 @@ static void nau8825_fill_ssdt(struct device *dev) NAU8825_DP_INT("jack-insert-debounce", config->jack_insert_debounce); NAU8825_DP_INT("jack-eject-deboune", config->jack_eject_debounce); NAU8825_DP_INT("sar-threshold-num", config->sar_threshold_num); - acpi_dp_write_integer_array("nuvoton,sar-threshold", - config->sar_threshold, - config->sar_threshold_num); - acpi_dp_write_footer(); + acpi_dp_add_integer_array(dp, "nuvoton,sar-threshold", + config->sar_threshold, config->sar_threshold_num); + acpi_dp_write("_DSD", dp); acpigen_pop_len(); /* Device */ acpigen_pop_len(); /* Scope */ diff --git a/src/soc/intel/skylake/sd.c b/src/soc/intel/skylake/sd.c index 80adb9c..01813b9 100644 --- a/src/soc/intel/skylake/sd.c +++ b/src/soc/intel/skylake/sd.c @@ -38,6 +38,7 @@ static void sd_fill_ssdt(struct device *dev) .pin_count = 1, .pins = { config->sdcard_cd_gpio_default } }; + struct acpi_dp *dp; if (!dev->enabled) return; @@ -62,9 +63,8 @@ static void sd_fill_ssdt(struct device *dev) acpigen_write_resourcetemplate_footer(); /* Bind the cd-gpio name to the GpioInt() resource */ - acpi_dp_write_header(); - acpi_dp_write_gpio("cd-gpio", path, 0, 0, 1); - acpi_dp_write_footer(); + dp = acpi_dp_add_gpio(NULL, "cd-gpio", path, 0, 0, 1); + acpi_dp_write("_DSD", dp); acpigen_pop_len(); }
1
0
0
0
Patch set updated for coreboot: [DontMerge]]Intel/x4x correct DDR2 latency
by HAOUAS Elyes
03 Jul '16
03 Jul '16
HAOUAS Elyes (ehaouas(a)noos.fr) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/15542
-gerrit commit 02b461f9b86bbf0eaea06328022467a3162032da Author: Elyes HAOUAS <ehaouas(a)noos.fr> Date: Sun Jul 3 18:00:21 2016 +0200 [DontMerge]]Intel/x4x correct DDR2 latency return the lowest supported by the DDR2 module. Change-Id: I9d593b318fbd8f8a33de4deb3e0af93f7bd80c38 Signed-off-by: Elyes HAOUAS <ehaouas(a)noos.fr> --- src/northbridge/intel/x4x/raminit.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/northbridge/intel/x4x/raminit.c b/src/northbridge/intel/x4x/raminit.c index 4f5575c..c62c2dd 100644 --- a/src/northbridge/intel/x4x/raminit.c +++ b/src/northbridge/intel/x4x/raminit.c @@ -36,7 +36,7 @@ static inline int spd_read_byte(unsigned int device, unsigned int address) static void sdram_read_spds(struct sysinfo *s) { - u8 i, j, chan; + u8 i, j, chan, cas_bit; int status = 0; FOR_EACH_DIMM(i) { if (s->spd_map[i] == 0) { @@ -111,10 +111,13 @@ static void sdram_read_spds(struct sysinfo *s) s->dimms[i].chip_capacity = s->dimms[i].banks; s->dimms[i].rows = s->dimms[i].spd_data[3];// - 12; s->dimms[i].cols = s->dimms[i].spd_data[4];// - 9; - s->dimms[i].cas_latencies = 0x78; - s->dimms[i].cas_latencies &= s->dimms[i].spd_data[18]; - if (s->dimms[i].cas_latencies == 0) - s->dimms[i].cas_latencies = 7; + cas_bit = 2; + do { + if ((1 << cas_bit) & s->dimms[i].spd_data[18]) + break; + ++cas_bit; + } while (cas_bit < 0x8); + s->dimms[i].cas_latencies = cas_bit; s->dimms[i].tAAmin = s->dimms[i].spd_data[26]; s->dimms[i].tCKmin = s->dimms[i].spd_data[25]; s->dimms[i].width = (s->dimms[i].spd_data[13] >> 3) - 1;
1
0
0
0
← Newer
1
...
170
171
172
173
174
175
176
...
182
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
Results per page:
10
25
50
100
200