gpio: Add a method to convert a GPIO to ACPI

When generating ACPI tables we need to convert GPIOs in U-Boot to the ACPI
structures required by ACPI. This is a SoC-specific conversion and cannot
be handled by generic code, so add a new GPIO method to do the conversion.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
Simon Glass
2020-07-07 13:11:44 -06:00
committed by Bin Meng
parent ff715c6f4f
commit 2912686c08
5 changed files with 278 additions and 0 deletions

View File

@@ -92,6 +92,96 @@ struct acpi_irq {
enum acpi_irq_wake wake;
};
/**
* enum acpi_gpio_type - type of the descriptor
*
* @ACPI_GPIO_TYPE_INTERRUPT: GpioInterrupt
* @ACPI_GPIO_TYPE_IO: GpioIo
*/
enum acpi_gpio_type {
ACPI_GPIO_TYPE_INTERRUPT,
ACPI_GPIO_TYPE_IO,
};
/**
* enum acpi_gpio_pull - pull direction
*
* @ACPI_GPIO_PULL_DEFAULT: Use default value for pin
* @ACPI_GPIO_PULL_UP: Pull up
* @ACPI_GPIO_PULL_DOWN: Pull down
* @ACPI_GPIO_PULL_NONE: No pullup/pulldown
*/
enum acpi_gpio_pull {
ACPI_GPIO_PULL_DEFAULT,
ACPI_GPIO_PULL_UP,
ACPI_GPIO_PULL_DOWN,
ACPI_GPIO_PULL_NONE,
};
/**
* enum acpi_gpio_io_restrict - controls input/output of pin
*
* @ACPI_GPIO_IO_RESTRICT_NONE: no restrictions
* @ACPI_GPIO_IO_RESTRICT_INPUT: input only (no output)
* @ACPI_GPIO_IO_RESTRICT_OUTPUT: output only (no input)
* @ACPI_GPIO_IO_RESTRICT_PRESERVE: preserve settings when driver not active
*/
enum acpi_gpio_io_restrict {
ACPI_GPIO_IO_RESTRICT_NONE,
ACPI_GPIO_IO_RESTRICT_INPUT,
ACPI_GPIO_IO_RESTRICT_OUTPUT,
ACPI_GPIO_IO_RESTRICT_PRESERVE,
};
/** enum acpi_gpio_polarity - controls the GPIO polarity */
enum acpi_gpio_polarity {
ACPI_GPIO_ACTIVE_HIGH = 0,
ACPI_GPIO_ACTIVE_LOW = 1,
};
#define ACPI_GPIO_REVISION_ID 1
#define ACPI_GPIO_MAX_PINS 2
/**
* struct acpi_gpio - representation of an ACPI GPIO
*
* @pin_count: Number of pins represented
* @pins: List of pins
* @pin0_addr: Address in memory of the control registers for pin 0. This is
* used when generating ACPI tables
* @type: GPIO type
* @pull: Pullup/pulldown setting
* @resource: Resource name for this GPIO controller
* For GpioInt:
* @interrupt_debounce_timeout: Debounce timeout in units of 10us
* @irq: Interrupt
*
* For GpioIo:
* @output_drive_strength: Drive strength in units of 10uA
* @io_shared; true if GPIO is shared
* @io_restrict: I/O restriction setting
* @polarity: GPIO polarity
*/
struct acpi_gpio {
int pin_count;
u16 pins[ACPI_GPIO_MAX_PINS];
ulong pin0_addr;
enum acpi_gpio_type type;
enum acpi_gpio_pull pull;
char resource[ACPI_PATH_MAX];
/* GpioInt */
u16 interrupt_debounce_timeout;
struct acpi_irq irq;
/* GpioIo */
u16 output_drive_strength;
bool io_shared;
enum acpi_gpio_io_restrict io_restrict;
enum acpi_gpio_polarity polarity;
};
/**
* acpi_device_path() - Get the full path to an ACPI device
*

View File

@@ -10,6 +10,7 @@
#include <dm/ofnode.h>
#include <linux/bitops.h>
struct acpi_gpio;
struct ofnode_phandle_args;
/*
@@ -329,6 +330,20 @@ struct dm_gpio_ops {
*/
int (*get_dir_flags)(struct udevice *dev, unsigned int offset,
ulong *flags);
#if CONFIG_IS_ENABLED(ACPIGEN)
/**
* get_acpi() - Get the ACPI info for a GPIO
*
* This converts a GPIO to an ACPI structure for adding to the ACPI
* tables.
*
* @desc: GPIO description to convert
* @gpio: Output ACPI GPIO information
* @return ACPI pin number or -ve on error
*/
int (*get_acpi)(const struct gpio_desc *desc, struct acpi_gpio *gpio);
#endif
};
/**
@@ -674,4 +689,16 @@ int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags);
*/
int gpio_get_number(const struct gpio_desc *desc);
/**
* gpio_get_acpi() - Get the ACPI pin for a GPIO
*
* This converts a GPIO to an ACPI pin number for adding to the ACPI
* tables. If the GPIO is invalid, the pin_count and pins[0] are set to 0
*
* @desc: GPIO description to convert
* @gpio: Output ACPI GPIO information
* @return ACPI pin number or -ve on error
*/
int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio);
#endif /* _ASM_GENERIC_GPIO_H_ */