summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2017-03-15 11:25:31 -0700
committerDuncan Laurie <dlaurie@chromium.org>2017-03-16 16:25:00 +0100
commitb94e93531f14a3788c3722d291ce061be271fd48 (patch)
treee046ae77db37b2bae1305507ad9e33c07409d7a7 /src/drivers
parent346cfe363ee79da6a59611b8b24f5ad01053ea01 (diff)
downloadcoreboot-b94e93531f14a3788c3722d291ce061be271fd48.tar.xz
i2c/generic: Add support for GPIO IRQ
Add support for using GPIO IRQ instead of PIRQ with an I2C device. This allows a device to use an edge triggered interrupt that will trigger on both high and low transitions. The _DSD method for describing these GPIOs has a field for 'active low' which is supposed to be 1 if the pin is active low, otherwise is zero. The value in here doesn't mean too much for GpioInt() as those will end up using the value from GpioInt() when it actually requests the interrupt. BUG=b:35581264 BRANCH=none TEST=test on Eve board that codec IRQ can be delcared as GPIO IRQ Change-Id: I02c64c7fc28dc2d608ad40db889c7242892f16db Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: https://review.coreboot.org/18835 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Furquan Shaikh <furquan@google.com>
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/i2c/generic/chip.h3
-rw-r--r--src/drivers/i2c/generic/generic.c18
2 files changed, 18 insertions, 3 deletions
diff --git a/src/drivers/i2c/generic/chip.h b/src/drivers/i2c/generic/chip.h
index a4f85df2ee..5810db801f 100644
--- a/src/drivers/i2c/generic/chip.h
+++ b/src/drivers/i2c/generic/chip.h
@@ -29,6 +29,9 @@ struct drivers_i2c_generic_config {
unsigned wake; /* Wake GPE */
struct acpi_irq irq; /* Interrupt */
+ /* Use GPIO based interrupt instead of PIRQ */
+ struct acpi_gpio irq_gpio;
+
/*
* This flag will add a device propery which will indicate
* to the OS that it should probe this device before adding it.
diff --git a/src/drivers/i2c/generic/generic.c b/src/drivers/i2c/generic/generic.c
index dea78d5e89..f8de1c22d9 100644
--- a/src/drivers/i2c/generic/generic.c
+++ b/src/drivers/i2c/generic/generic.c
@@ -68,7 +68,7 @@ void i2c_generic_fill_ssdt(struct device *dev,
};
struct acpi_dp *dsd = NULL;
int curr_index = 0;
- int reset_gpio_index = -1, enable_gpio_index = -1;
+ int reset_gpio_index = -1, enable_gpio_index = -1, irq_gpio_index = -1;
const char *path = acpi_device_path(dev);
if (!dev->enabled || !scope)
@@ -93,7 +93,14 @@ void i2c_generic_fill_ssdt(struct device *dev,
acpigen_write_name("_CRS");
acpigen_write_resourcetemplate_header();
acpi_device_write_i2c(&i2c);
- acpi_device_write_interrupt(&config->irq);
+
+ /* Use either Interrupt() or GpioInt() */
+ if (config->irq_gpio.pin_count)
+ irq_gpio_index = i2c_generic_write_gpio(&config->irq_gpio,
+ &curr_index);
+ else
+ acpi_device_write_interrupt(&config->irq);
+
if (i2c_generic_add_gpios_to_crs(config) == true) {
reset_gpio_index = i2c_generic_write_gpio(&config->reset_gpio,
&curr_index);
@@ -110,10 +117,15 @@ void i2c_generic_fill_ssdt(struct device *dev,
/* DSD */
if (config->probed || (reset_gpio_index != -1) ||
- (enable_gpio_index != -1)) {
+ (enable_gpio_index != -1) || (irq_gpio_index != -1)) {
dsd = acpi_dp_new_table("_DSD");
if (config->probed)
acpi_dp_add_integer(dsd, "linux,probed", 1);
+ if (irq_gpio_index != -1)
+ acpi_dp_add_gpio(dsd, "irq-gpios", path,
+ irq_gpio_index, 0,
+ config->irq_gpio.polarity ==
+ ACPI_GPIO_ACTIVE_LOW);
if (reset_gpio_index != -1)
acpi_dp_add_gpio(dsd, "reset-gpios", path,
reset_gpio_index, 0,