diff options
-rw-r--r-- | src/soc/intel/common/block/gpio/gpio.c | 20 | ||||
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/gpio.h | 32 |
2 files changed, 46 insertions, 6 deletions
diff --git a/src/soc/intel/common/block/gpio/gpio.c b/src/soc/intel/common/block/gpio/gpio.c index 9b6ca7e1d5..c3b0ebfa25 100644 --- a/src/soc/intel/common/block/gpio/gpio.c +++ b/src/soc/intel/common/block/gpio/gpio.c @@ -397,10 +397,26 @@ void gpio_set(gpio_t gpio_num, int value) uint16_t gpio_acpi_pin(gpio_t gpio_num) { - if (!IS_ENABLED(CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_MULTI_ACPI_DEVICES)) + const struct pad_community *comm; + size_t group, pin; + + if (IS_ENABLED(CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_MULTI_ACPI_DEVICES)) + return relative_pad_in_comm(gpio_get_community(gpio_num), + gpio_num); + + comm = gpio_get_community(gpio_num); + pin = relative_pad_in_comm(comm, gpio_num); + group = gpio_group_index(comm, pin); + + /* If pad base is not set then use GPIO number as ACPI pin number. */ + if (comm->groups[group].acpi_pad_base == PAD_BASE_NONE) return gpio_num; - return relative_pad_in_comm(gpio_get_community(gpio_num), gpio_num); + /* + * If this group has a non-zero pad base then compute the ACPI pin + * number from the pad base and the relative pad in the group. + */ + return comm->groups[group].acpi_pad_base + gpio_within_group(comm, pin); } static void print_gpi_status(const struct gpi_status *sts) diff --git a/src/soc/intel/common/block/include/intelblocks/gpio.h b/src/soc/intel/common/block/include/intelblocks/gpio.h index 4e26db3619..c389ec4531 100644 --- a/src/soc/intel/common/block/include/intelblocks/gpio.h +++ b/src/soc/intel/common/block/include/intelblocks/gpio.h @@ -23,13 +23,30 @@ #ifndef __ACPI__ #include <types.h> -#define INTEL_GPP(first_of_community, start_of_group, end_of_group) \ - { \ - .first_pad = (start_of_group) - (first_of_community), \ - .size = (end_of_group) - (start_of_group) + 1, \ +/* + * GPIO numbers may not be contiguous and instead will have a different + * starting pin number for each pad group. + */ +#define INTEL_GPP_BASE(first_of_community, start_of_group, end_of_group,\ + group_pad_base) \ + { \ + .first_pad = (start_of_group) - (first_of_community), \ + .size = (end_of_group) - (start_of_group) + 1, \ + .acpi_pad_base = (group_pad_base), \ } /* + * A pad base of -1 indicates that this group uses contiguous numbering + * and a pad base should not be used for this group. + */ +#define PAD_BASE_NONE -1 + +/* The common/default group numbering is contiguous */ +#define INTEL_GPP(first_of_community, start_of_group, end_of_group) \ + INTEL_GPP_BASE(first_of_community, start_of_group, end_of_group,\ + PAD_BASE_NONE) + +/* * Following should be defined in soc/gpio.h * GPIO_MISCCFG - offset to GPIO MISCCFG Register * @@ -67,6 +84,13 @@ struct pad_group { int first_pad; /* offset of first pad of the group relative to the community */ unsigned int size; /* Size of the group */ + /* + * This is the starting pin number for the pads in this group when + * they are used in ACPI. This is only needed if the pins are not + * contiguous across groups, most groups will have this set to + * PAD_BASE_NONE and use contiguous numbering for ACPI. + */ + int acpi_pad_base; }; /* This structure will be used to describe a community or each group within a |