summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/i2c/generic/chip.h9
-rw-r--r--src/drivers/i2c/generic/generic.c43
2 files changed, 52 insertions, 0 deletions
diff --git a/src/drivers/i2c/generic/chip.h b/src/drivers/i2c/generic/chip.h
index d84097f6c6..e84fc38df9 100644
--- a/src/drivers/i2c/generic/chip.h
+++ b/src/drivers/i2c/generic/chip.h
@@ -22,4 +22,13 @@ struct drivers_i2c_generic_config {
/* GPIO used to indicate if this device is present */
unsigned device_present_gpio;
unsigned device_present_gpio_invert;
+
+ /* GPIO used to take device out of reset or to put it into reset. */
+ unsigned reset_gpio;
+ /* Delay to be inserted after device is taken out of reset. */
+ unsigned reset_delay_ms;
+ /* GPIO used to enable device. */
+ unsigned enable_gpio;
+ /* Delay to be inserted after device is enabled. */
+ unsigned enable_delay_ms;
};
diff --git a/src/drivers/i2c/generic/generic.c b/src/drivers/i2c/generic/generic.c
index c11a889d5b..34fbf77a3e 100644
--- a/src/drivers/i2c/generic/generic.c
+++ b/src/drivers/i2c/generic/generic.c
@@ -25,6 +25,46 @@
#include "chip.h"
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+
+static void i2c_generic_add_power_res(struct drivers_i2c_generic_config *config)
+{
+ const char *power_res_dev_states[] = { "_PR0", "_PR3" };
+
+ if (!config->reset_gpio && !config->enable_gpio)
+ return;
+
+ /* PowerResource (PRIC, 0, 0) */
+ acpigen_write_power_res("PRIC", 0, 0, power_res_dev_states,
+ ARRAY_SIZE(power_res_dev_states));
+
+ /* Method (_STA, 0, NotSerialized) { Return (0x1) } */
+ acpigen_write_STA(0x1);
+
+ /* Method (_ON, 0, Serialized) */
+ acpigen_write_method_serialized("_ON", 0);
+ if (config->reset_gpio)
+ acpigen_soc_set_tx_gpio(config->reset_gpio);
+ if (config->enable_gpio) {
+ acpigen_soc_set_tx_gpio(config->enable_gpio);
+ acpigen_write_sleep(config->enable_delay_ms);
+ }
+ if (config->reset_gpio) {
+ acpigen_soc_clear_tx_gpio(config->reset_gpio);
+ acpigen_write_sleep(config->reset_delay_ms);
+ }
+ acpigen_pop_len(); /* _ON method */
+
+ /* Method (_OFF, 0, Serialized) */
+ acpigen_write_method_serialized("_OFF", 0);
+ if (config->reset_gpio)
+ acpigen_soc_set_tx_gpio(config->reset_gpio);
+ if (config->enable_gpio)
+ acpigen_soc_clear_tx_gpio(config->enable_gpio);
+ acpigen_pop_len(); /* _OFF method */
+
+ acpigen_pop_len(); /* PowerResource PRIC */
+}
+
static void i2c_generic_fill_ssdt(struct device *dev)
{
struct drivers_i2c_generic_config *config = dev->chip_info;
@@ -72,6 +112,9 @@ static void i2c_generic_fill_ssdt(struct device *dev)
acpi_dp_write(dsd);
}
+ /* Power Resource */
+ i2c_generic_add_power_res(config);
+
acpigen_pop_len(); /* Device */
acpigen_pop_len(); /* Scope */