i2c/generic: Allow GPIOs to be put in _CRS and PowerResource in ACPI

Linux kernel expects that power management with ACPI should always be
handled using PowerResource. However, some kernel drivers (e.g. ELAN
touchscreen) check to see if reset gpio is passed in by the BIOS to
decide whether the device loses power in suspend. Thus, until the kernel
has a better way for drivers to query if device lost power in suspend,
we need to allow passing in of GPIOs via _CRS as well as exporting
PowerResource to control power to the device.

Update mainboards to export reset GPIO as well as PowerResource for
ELAN touchscreen device.

BUG=chrome-os-partner:62311,chrome-os-partner:60194
BRANCH=reef
TEST=Verified that touchscreen works on power-on as well as after
suspend-resume.

Change-Id: I3409689cf56bfddd321402ad5dda3fc8762e6bc6
Signed-off-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-on: https://review.coreboot.org/18238
Tested-by: build bot (Jenkins)
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
This commit is contained in:
Furquan Shaikh 2017-01-25 17:53:01 -08:00 committed by Aaron Durbin
parent 8bf53a9f4e
commit 71d830fddc
5 changed files with 28 additions and 39 deletions

View File

@ -19,11 +19,6 @@
#include <arch/acpi_device.h>
#include <device/i2c.h>
enum power_mgmt_type {
POWER_RESOURCE = 1,
GPIO_EXPORT = 2,
};
struct drivers_i2c_generic_config {
const char *hid; /* ACPI _HID (required) */
const char *cid; /* ACPI _CID */
@ -47,8 +42,11 @@ struct drivers_i2c_generic_config {
unsigned device_present_gpio;
unsigned device_present_gpio_invert;
/* Power management type. */
enum power_mgmt_type pwr_mgmt_type;
/* Disable reset and enable GPIO export in _CRS */
bool disable_gpio_export_in_crs;
/* Does the device have a power resource? */
bool has_power_resource;
/* GPIO used to take device out of reset or to put it into reset. */
struct acpi_gpio reset_gpio;

View File

@ -32,7 +32,7 @@ static void i2c_generic_add_power_res(struct drivers_i2c_generic_config *config)
unsigned reset_gpio = config->reset_gpio.pins[0];
unsigned enable_gpio = config->enable_gpio.pins[0];
if (config->pwr_mgmt_type != POWER_RESOURCE)
if (!config->has_power_resource)
return;
if (!reset_gpio && !enable_gpio)
@ -72,10 +72,17 @@ static void i2c_generic_add_power_res(struct drivers_i2c_generic_config *config)
static bool i2c_generic_add_gpios_to_crs(struct drivers_i2c_generic_config *cfg)
{
if (cfg->pwr_mgmt_type == GPIO_EXPORT)
return true;
/*
* Return false if:
* 1. Request to explicitly disable export of GPIOs in CRS, or
* 2. Both reset and enable GPIOs are not provided.
*/
if (cfg->disable_gpio_export_in_crs ||
((cfg->reset_gpio.pin_count == 0) &&
(cfg->enable_gpio.pin_count == 0)))
return false;
return true;
}
static int i2c_generic_write_gpio(struct acpi_gpio *gpio, int *curr_index)

View File

@ -177,16 +177,11 @@ chip soc/intel/apollolake
register "desc" = ""ELAN Touchscreen""
register "irq" = "IRQ_EDGE_LOW(GPIO_21_IRQ)"
register "probed" = "1"
register "pwr_mgmt_type" = "GPIO_EXPORT"
register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)"
chip drivers/generic/gpio_regulator
register "name" = ""vcc33""
register "gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)"
register "enabled_on_boot" = "1"
device generic 0 on end
end
register "reset_delay_ms" = "20"
register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)"
register "enable_delay_ms" = "1"
register "has_power_resource" = "1"
device i2c 10 on end
end
end # - I2C 3

View File

@ -175,16 +175,11 @@ chip soc/intel/apollolake
register "desc" = ""ELAN Touchscreen""
register "irq" = "IRQ_EDGE_LOW(GPIO_21_IRQ)"
register "probed" = "1"
register "pwr_mgmt_type" = "GPIO_EXPORT"
register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)"
chip drivers/generic/gpio_regulator
register "name" = ""vcc33""
register "gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)"
register "enabled_on_boot" = "1"
device generic 0 on end
end
register "reset_delay_ms" = "20"
register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)"
register "enable_delay_ms" = "1"
register "has_power_resource" = "1"
device i2c 10 on end
end
chip drivers/i2c/hid
@ -192,7 +187,6 @@ chip soc/intel/apollolake
register "generic.desc" = ""WDT Touchscreen""
register "generic.irq" = "IRQ_EDGE_LOW(GPIO_21_IRQ)"
register "generic.probed" = "1"
register "generic.pwr_mgmt_type" = "GPIO_EXPORT"
register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)"
register "hid_desc_reg_offset" = "0x20"
device i2c 2c on end

View File

@ -177,16 +177,11 @@ chip soc/intel/apollolake
register "desc" = ""ELAN Touchscreen""
register "irq" = "IRQ_EDGE_LOW(GPIO_21_IRQ)"
register "probed" = "1"
register "pwr_mgmt_type" = "GPIO_EXPORT"
register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)"
chip drivers/generic/gpio_regulator
register "name" = ""vcc33""
register "gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)"
register "enabled_on_boot" = "1"
device generic 0 on end
end
register "reset_delay_ms" = "20"
register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)"
register "enable_delay_ms" = "1"
register "has_power_resource" = "1"
device i2c 10 on end
end
end # - I2C 3