592 lines
18 KiB
C
592 lines
18 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
|
|
#ifndef __ACPI_ACPI_DEVICE_H__
|
|
#define __ACPI_ACPI_DEVICE_H__
|
|
|
|
#include <device/i2c.h>
|
|
#include <spi-generic.h>
|
|
#include <types.h>
|
|
|
|
enum acpi_dp_type {
|
|
ACPI_DP_TYPE_UNKNOWN,
|
|
ACPI_DP_TYPE_INTEGER,
|
|
ACPI_DP_TYPE_STRING,
|
|
ACPI_DP_TYPE_REFERENCE,
|
|
ACPI_DP_TYPE_TABLE,
|
|
ACPI_DP_TYPE_ARRAY,
|
|
ACPI_DP_TYPE_CHILD,
|
|
ACPI_DP_TYPE_PACKAGE,
|
|
};
|
|
|
|
struct acpi_dp {
|
|
enum acpi_dp_type type;
|
|
const char *name;
|
|
const char *uuid;
|
|
struct acpi_dp *next;
|
|
union {
|
|
struct acpi_dp *child;
|
|
struct acpi_dp *array;
|
|
};
|
|
union {
|
|
uint64_t integer;
|
|
const char *string;
|
|
};
|
|
};
|
|
|
|
#define ACPI_DESCRIPTOR_LARGE (1 << 7)
|
|
#define ACPI_DESCRIPTOR_INTERRUPT (ACPI_DESCRIPTOR_LARGE | 9)
|
|
#define ACPI_DESCRIPTOR_GPIO (ACPI_DESCRIPTOR_LARGE | 12)
|
|
#define ACPI_DESCRIPTOR_SERIAL_BUS (ACPI_DESCRIPTOR_LARGE | 14)
|
|
|
|
/*
|
|
* PRP0001 is a special DT namespace link device ID. It provides a means to use
|
|
* existing DT-compatible device identification in ACPI. When this _HID is used
|
|
* by an ACPI device, the ACPI subsystem in OS looks up "compatible" property in
|
|
* device object's _DSD and will use the value of that property to identify the
|
|
* corresponding device in analogy with the original DT device identification
|
|
* algorithm.
|
|
* More details can be found in Linux kernel documentation:
|
|
* Documentation/acpi/enumeration.txt
|
|
*/
|
|
#define ACPI_DT_NAMESPACE_HID "PRP0001"
|
|
|
|
struct device;
|
|
const char *acpi_device_name(const struct device *dev);
|
|
const char *acpi_device_hid(const struct device *dev);
|
|
uint32_t acpi_device_uid(const struct device *dev);
|
|
const char *acpi_device_path(const struct device *dev);
|
|
const char *acpi_device_scope(const struct device *dev);
|
|
const char *acpi_device_path_join(const struct device *dev, const char *name);
|
|
int acpi_device_status(const struct device *dev);
|
|
void acpi_device_write_uid(const struct device *dev);
|
|
|
|
/*
|
|
* ACPI Descriptor for extended Interrupt()
|
|
*/
|
|
|
|
enum acpi_irq_mode {
|
|
ACPI_IRQ_EDGE_TRIGGERED,
|
|
ACPI_IRQ_LEVEL_TRIGGERED
|
|
};
|
|
|
|
enum acpi_irq_polarity {
|
|
ACPI_IRQ_ACTIVE_LOW,
|
|
ACPI_IRQ_ACTIVE_HIGH,
|
|
ACPI_IRQ_ACTIVE_BOTH
|
|
};
|
|
|
|
enum acpi_irq_shared {
|
|
ACPI_IRQ_EXCLUSIVE,
|
|
ACPI_IRQ_SHARED
|
|
};
|
|
|
|
enum acpi_irq_wake {
|
|
ACPI_IRQ_NO_WAKE,
|
|
ACPI_IRQ_WAKE
|
|
};
|
|
|
|
struct acpi_irq {
|
|
unsigned int pin;
|
|
enum acpi_irq_mode mode;
|
|
enum acpi_irq_polarity polarity;
|
|
enum acpi_irq_shared shared;
|
|
enum acpi_irq_wake wake;
|
|
};
|
|
|
|
#define ACPI_IRQ_CFG(_pin, _mode, _pol, _shared, _wake) { \
|
|
.pin = (_pin), \
|
|
.mode = (_mode), \
|
|
.polarity = (_pol), \
|
|
.shared = (_shared), \
|
|
.wake = (_wake) }
|
|
|
|
#define ACPI_IRQ_EDGE_LOW(x) \
|
|
ACPI_IRQ_CFG((x), ACPI_IRQ_EDGE_TRIGGERED, ACPI_IRQ_ACTIVE_LOW, \
|
|
ACPI_IRQ_EXCLUSIVE, ACPI_IRQ_NO_WAKE)
|
|
|
|
#define ACPI_IRQ_EDGE_HIGH(x) \
|
|
ACPI_IRQ_CFG((x), ACPI_IRQ_EDGE_TRIGGERED, ACPI_IRQ_ACTIVE_HIGH, \
|
|
ACPI_IRQ_EXCLUSIVE, ACPI_IRQ_NO_WAKE)
|
|
|
|
#define ACPI_IRQ_LEVEL_LOW(x) \
|
|
ACPI_IRQ_CFG((x), ACPI_IRQ_LEVEL_TRIGGERED, ACPI_IRQ_ACTIVE_LOW, \
|
|
ACPI_IRQ_SHARED, ACPI_IRQ_NO_WAKE)
|
|
|
|
#define ACPI_IRQ_LEVEL_HIGH(x) \
|
|
ACPI_IRQ_CFG((x), ACPI_IRQ_LEVEL_TRIGGERED, ACPI_IRQ_ACTIVE_HIGH, \
|
|
ACPI_IRQ_SHARED, ACPI_IRQ_NO_WAKE)
|
|
|
|
#define ACPI_IRQ_WAKE_EDGE_LOW(x) \
|
|
ACPI_IRQ_CFG((x), ACPI_IRQ_EDGE_TRIGGERED, ACPI_IRQ_ACTIVE_LOW, \
|
|
ACPI_IRQ_EXCLUSIVE, ACPI_IRQ_WAKE)
|
|
|
|
#define ACPI_IRQ_WAKE_EDGE_HIGH(x) \
|
|
ACPI_IRQ_CFG((x), ACPI_IRQ_EDGE_TRIGGERED, ACPI_IRQ_ACTIVE_HIGH, \
|
|
ACPI_IRQ_EXCLUSIVE, ACPI_IRQ_WAKE)
|
|
|
|
#define ACPI_IRQ_WAKE_LEVEL_LOW(x) \
|
|
ACPI_IRQ_CFG((x), ACPI_IRQ_LEVEL_TRIGGERED, ACPI_IRQ_ACTIVE_LOW, \
|
|
ACPI_IRQ_SHARED, ACPI_IRQ_WAKE)
|
|
|
|
#define ACPI_IRQ_WAKE_LEVEL_HIGH(x) \
|
|
ACPI_IRQ_CFG((x), ACPI_IRQ_LEVEL_TRIGGERED, ACPI_IRQ_ACTIVE_HIGH, \
|
|
ACPI_IRQ_SHARED, ACPI_IRQ_WAKE)
|
|
|
|
/* Write extended Interrupt() descriptor to SSDT AML output */
|
|
void acpi_device_write_interrupt(const struct acpi_irq *irq);
|
|
|
|
/*
|
|
* ACPI Descriptors for GpioIo() and GpioInterrupt()
|
|
*/
|
|
|
|
enum acpi_gpio_type {
|
|
ACPI_GPIO_TYPE_INTERRUPT,
|
|
ACPI_GPIO_TYPE_IO
|
|
};
|
|
|
|
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 {
|
|
ACPI_GPIO_IO_RESTRICT_NONE,
|
|
ACPI_GPIO_IO_RESTRICT_INPUT,
|
|
ACPI_GPIO_IO_RESTRICT_OUTPUT,
|
|
ACPI_GPIO_IO_RESTRICT_PRESERVE
|
|
};
|
|
|
|
#define ACPI_GPIO_REVISION_ID 1
|
|
#define ACPI_GPIO_MAX_PINS 8
|
|
|
|
struct acpi_gpio {
|
|
int pin_count;
|
|
uint16_t pins[ACPI_GPIO_MAX_PINS];
|
|
|
|
enum acpi_gpio_type type;
|
|
enum acpi_gpio_pull pull;
|
|
const char *resource;
|
|
|
|
/* GpioInt */
|
|
uint16_t interrupt_debounce_timeout; /* 1/100 ms */
|
|
struct acpi_irq irq;
|
|
|
|
/* GpioIo */
|
|
uint16_t output_drive_strength; /* 1/100 mA */
|
|
int io_shared;
|
|
enum acpi_gpio_io_restrict io_restrict;
|
|
/*
|
|
* As per ACPI spec, GpioIo does not have any polarity associated with it. Linux kernel
|
|
* uses `active_low` argument within GPIO _DSD property to allow BIOS to indicate if the
|
|
* corresponding GPIO should be treated as active low. Thus, if the GPIO has active high
|
|
* polarity or if it does not have any polarity, then the `active_low` argument is
|
|
* supposed to be set to 0.
|
|
*
|
|
* Reference:
|
|
* https://www.kernel.org/doc/html/latest/firmware-guide/acpi/gpio-properties.html
|
|
*/
|
|
bool active_low;
|
|
};
|
|
|
|
/* GpioIo-related macros */
|
|
#define ACPI_GPIO_CFG(_gpio, _io_restrict, _active_low) { \
|
|
.type = ACPI_GPIO_TYPE_IO, \
|
|
.pull = ACPI_GPIO_PULL_DEFAULT, \
|
|
.io_restrict = _io_restrict, \
|
|
.active_low = _active_low, \
|
|
.pin_count = 1, \
|
|
.pins = { (_gpio) } }
|
|
|
|
/* Basic output GPIO with default pull settings */
|
|
#define ACPI_GPIO_OUTPUT_CFG(gpio, active_low) \
|
|
ACPI_GPIO_CFG(gpio, ACPI_GPIO_IO_RESTRICT_OUTPUT, active_low)
|
|
|
|
#define ACPI_GPIO_OUTPUT(gpio) ACPI_GPIO_OUTPUT_CFG(gpio, 0)
|
|
#define ACPI_GPIO_OUTPUT_ACTIVE_HIGH(gpio) ACPI_GPIO_OUTPUT_CFG(gpio, 0)
|
|
#define ACPI_GPIO_OUTPUT_ACTIVE_LOW(gpio) ACPI_GPIO_OUTPUT_CFG(gpio, 1)
|
|
|
|
/* Basic input GPIO with default pull settings */
|
|
#define ACPI_GPIO_INPUT_CFG(gpio, polarity) \
|
|
ACPI_GPIO_CFG(gpio, ACPI_GPIO_IO_RESTRICT_INPUT, polarity)
|
|
|
|
#define ACPI_GPIO_INPUT(gpio) ACPI_GPIO_INPUT_CFG(gpio, 0)
|
|
#define ACPI_GPIO_INPUT_ACTIVE_HIGH(gpio) ACPI_GPIO_INPUT_CFG(gpio, 0)
|
|
#define ACPI_GPIO_INPUT_ACTIVE_LOW(gpio) ACPI_GPIO_INPUT_CFG(gpio, 1)
|
|
|
|
/* GpioInt-related macros */
|
|
#define ACPI_GPIO_IRQ_CFG(_gpio, _mode, _polarity, _wake) { \
|
|
.type = ACPI_GPIO_TYPE_INTERRUPT, \
|
|
.pull = ACPI_GPIO_PULL_DEFAULT, \
|
|
.irq.mode = _mode, \
|
|
.irq.polarity = _polarity, \
|
|
.irq.wake = _wake, \
|
|
.pin_count = 1, \
|
|
.pins = { (_gpio) } }
|
|
|
|
#define ACPI_GPIO_IRQ_EDGE(gpio, polarity) \
|
|
ACPI_GPIO_IRQ_CFG(gpio, ACPI_IRQ_EDGE_TRIGGERED, polarity, 0)
|
|
|
|
#define ACPI_GPIO_IRQ_EDGE_WAKE(gpio, polarity) \
|
|
ACPI_GPIO_IRQ_CFG(gpio, ACPI_IRQ_EDGE_TRIGGERED, polarity, ACPI_IRQ_WAKE)
|
|
|
|
#define ACPI_GPIO_IRQ_LEVEL(gpio, polarity) \
|
|
ACPI_GPIO_IRQ_CFG(gpio, ACPI_IRQ_LEVEL_TRIGGERED, polarity, 0)
|
|
|
|
#define ACPI_GPIO_IRQ_LEVEL_WAKE(gpio, polarity) \
|
|
ACPI_GPIO_IRQ_CFG(gpio, ACPI_IRQ_LEVEL_TRIGGERED, polarity, ACPI_IRQ_WAKE)
|
|
|
|
/* Edge Triggered Active High GPIO interrupt */
|
|
#define ACPI_GPIO_IRQ_EDGE_HIGH(gpio) \
|
|
ACPI_GPIO_IRQ_EDGE(gpio, ACPI_IRQ_ACTIVE_HIGH)
|
|
|
|
/* Edge Triggered Active Low GPIO interrupt */
|
|
#define ACPI_GPIO_IRQ_EDGE_LOW(gpio) \
|
|
ACPI_GPIO_IRQ_EDGE(gpio, ACPI_IRQ_ACTIVE_LOW)
|
|
|
|
/* Edge Triggered Active Both GPIO interrupt */
|
|
#define ACPI_GPIO_IRQ_EDGE_BOTH(gpio) \
|
|
ACPI_GPIO_IRQ_EDGE(gpio, ACPI_IRQ_ACTIVE_BOTH)
|
|
|
|
/* Edge Triggered Active High GPIO interrupt with wake */
|
|
#define ACPI_GPIO_IRQ_EDGE_HIGH_WAKE(gpio) \
|
|
ACPI_GPIO_IRQ_EDGE_WAKE(gpio, ACPI_IRQ_ACTIVE_HIGH)
|
|
|
|
/* Edge Triggered Active Low GPIO interrupt with wake */
|
|
#define ACPI_GPIO_IRQ_EDGE_LOW_WAKE(gpio) \
|
|
ACPI_GPIO_IRQ_EDGE_WAKE(gpio, ACPI_IRQ_ACTIVE_LOW)
|
|
|
|
/* Edge Triggered Active Both GPIO interrupt with wake */
|
|
#define ACPI_GPIO_IRQ_EDGE_BOTH_WAKE(gpio) \
|
|
ACPI_GPIO_IRQ_EDGE_WAKE(gpio, ACPI_IRQ_ACTIVE_BOTH)
|
|
|
|
/* Level Triggered Active High GPIO interrupt */
|
|
#define ACPI_GPIO_IRQ_LEVEL_HIGH(gpio) \
|
|
ACPI_GPIO_IRQ_LEVEL(gpio, ACPI_IRQ_ACTIVE_HIGH)
|
|
|
|
/* Level Triggered Active Low GPIO interrupt */
|
|
#define ACPI_GPIO_IRQ_LEVEL_LOW(gpio) \
|
|
ACPI_GPIO_IRQ_LEVEL(gpio, ACPI_IRQ_ACTIVE_LOW)
|
|
|
|
/* Level Triggered Active High GPIO interrupt with wake */
|
|
#define ACPI_GPIO_IRQ_LEVEL_HIGH_WAKE(gpio) \
|
|
ACPI_GPIO_IRQ_LEVEL_WAKE(gpio, ACPI_IRQ_ACTIVE_HIGH)
|
|
|
|
/* Level Triggered Active Low GPIO interrupt with wake */
|
|
#define ACPI_GPIO_IRQ_LEVEL_LOW_WAKE(gpio) \
|
|
ACPI_GPIO_IRQ_LEVEL_WAKE(gpio, ACPI_IRQ_ACTIVE_LOW)
|
|
|
|
/* Write GpioIo() or GpioInt() descriptor to SSDT AML output */
|
|
void acpi_device_write_gpio(const struct acpi_gpio *gpio);
|
|
|
|
/*
|
|
* ACPI Descriptors for Serial Bus interfaces
|
|
*/
|
|
|
|
#define ACPI_SERIAL_BUS_TYPE_I2C 1
|
|
#define ACPI_SERIAL_BUS_TYPE_SPI 2
|
|
#define ACPI_SERIAL_BUS_TYPE_UART 3
|
|
|
|
#define ACPI_I2C_SERIAL_BUS_REVISION_ID 1 /* TODO: upgrade to 2 */
|
|
#define ACPI_I2C_TYPE_SPECIFIC_REVISION_ID 1
|
|
#define ACPI_SPI_SERIAL_BUS_REVISION_ID 1
|
|
#define ACPI_SPI_TYPE_SPECIFIC_REVISION_ID 1
|
|
#define ACPI_UART_SERIAL_BUS_REVISION_ID 1
|
|
#define ACPI_UART_TYPE_SPECIFIC_REVISION_ID 1
|
|
|
|
/*
|
|
* ACPI I2C Bus
|
|
*/
|
|
|
|
struct acpi_i2c {
|
|
/* I2C Address */
|
|
uint16_t address;
|
|
/* 7 or 10 bit Address Mode */
|
|
enum i2c_address_mode mode_10bit;
|
|
/* I2C Bus Speed in Hz */
|
|
enum i2c_speed speed;
|
|
/* Reference to I2C controller */
|
|
const char *resource;
|
|
};
|
|
|
|
/* Write I2cSerialBus() descriptor to SSDT AML output */
|
|
void acpi_device_write_i2c(const struct acpi_i2c *i2c);
|
|
|
|
/*
|
|
* ACPI SPI Bus
|
|
*/
|
|
|
|
struct acpi_spi {
|
|
/* Device selection */
|
|
uint16_t device_select;
|
|
/* Device selection line is active high or low */
|
|
enum spi_polarity device_select_polarity;
|
|
/* 3 or 4 wire SPI connection */
|
|
enum spi_wire_mode wire_mode;
|
|
/* Connection speed in HZ */
|
|
unsigned int speed;
|
|
/* Size in bits of smallest transfer unit */
|
|
u8 data_bit_length;
|
|
/* Phase of clock pulse on which to capture data */
|
|
enum spi_clock_phase clock_phase;
|
|
/* Indicate if clock is high or low during first phase */
|
|
enum spi_polarity clock_polarity;
|
|
/* Reference to SPI controller */
|
|
const char *resource;
|
|
};
|
|
|
|
/* Write SPI Bus descriptor to SSDT AML output */
|
|
void acpi_device_write_spi(const struct acpi_spi *spi);
|
|
|
|
/*
|
|
* ACPI UART Bus
|
|
*/
|
|
|
|
enum acpi_uart_data_bits {
|
|
ACPI_UART_DATA_BITS_5,
|
|
ACPI_UART_DATA_BITS_6,
|
|
ACPI_UART_DATA_BITS_7,
|
|
ACPI_UART_DATA_BITS_8,
|
|
ACPI_UART_DATA_BITS_9
|
|
};
|
|
|
|
enum acpi_uart_stop_bits {
|
|
ACPI_UART_STOP_BITS_0,
|
|
ACPI_UART_STOP_BITS_1,
|
|
ACPI_UART_STOP_BITS_1_5,
|
|
ACPI_UART_STOP_BITS_2
|
|
};
|
|
|
|
enum acpi_uart_lines {
|
|
ACPI_UART_LINE_DTD = BIT(2), /* Data Carrier Detect */
|
|
ACPI_UART_LINE_RI = BIT(3), /* Ring Indicator */
|
|
ACPI_UART_LINE_DSR = BIT(4), /* Data Set Ready */
|
|
ACPI_UART_LINE_DTR = BIT(5), /* Data Terminal Ready */
|
|
ACPI_UART_LINE_CTS = BIT(6), /* Clear to Send */
|
|
ACPI_UART_LINE_RTS = BIT(7) /* Request to Send */
|
|
};
|
|
|
|
enum acpi_uart_endian {
|
|
ACPI_UART_ENDIAN_LITTLE,
|
|
ACPI_UART_ENDIAN_BIG
|
|
};
|
|
|
|
enum acpi_uart_parity {
|
|
ACPI_UART_PARITY_NONE,
|
|
ACPI_UART_PARITY_EVEN,
|
|
ACPI_UART_PARITY_ODD,
|
|
ACPI_UART_PARITY_MARK,
|
|
ACPI_UART_PARITY_SPACE
|
|
};
|
|
|
|
enum acpi_uart_flow_control {
|
|
ACPI_UART_FLOW_NONE,
|
|
ACPI_UART_FLOW_HARDWARE,
|
|
ACPI_UART_FLOW_SOFTWARE
|
|
};
|
|
|
|
struct acpi_uart {
|
|
/* Initial Baud Rate in bits per second */
|
|
uint32_t initial_baud_rate;
|
|
/* Number of bits of data in a packet (value between 5-9) */
|
|
enum acpi_uart_data_bits data_bits;
|
|
/* Number of bits to signal end of packet */
|
|
enum acpi_uart_stop_bits stop_bits;
|
|
/* Bitmask indicating presence or absence of particular line */
|
|
unsigned int lines_in_use;
|
|
/* Specify if the device expects big or little endian format */
|
|
enum acpi_uart_endian endian;
|
|
/* Specify the type of parity bits included after the data in a packet */
|
|
enum acpi_uart_parity parity;
|
|
/* Specify the flow control method */
|
|
enum acpi_uart_flow_control flow_control;
|
|
/* Upper limit in bytes of the buffer sizes for this device */
|
|
uint16_t rx_fifo_bytes;
|
|
uint16_t tx_fifo_bytes;
|
|
/* Set true if UART is shared, false if it is exclusive for one device */
|
|
bool shared;
|
|
/* Reference to UART controller */
|
|
const char *resource;
|
|
};
|
|
|
|
#define ACPI_UART_RAW_DEVICE(baud_rate, fifo_bytes) { \
|
|
.initial_baud_rate = (baud_rate), \
|
|
.data_bits = ACPI_UART_DATA_BITS_8, \
|
|
.stop_bits = ACPI_UART_STOP_BITS_1, \
|
|
.endian = ACPI_UART_ENDIAN_LITTLE, \
|
|
.parity = ACPI_UART_PARITY_NONE, \
|
|
.flow_control = ACPI_UART_FLOW_NONE, \
|
|
.rx_fifo_bytes = (fifo_bytes), \
|
|
.tx_fifo_bytes = (fifo_bytes), \
|
|
.shared = false }
|
|
|
|
/* Write UARTSerialBusV2() descriptor to SSDT AML output */
|
|
void acpi_device_write_uart(const struct acpi_uart *uart);
|
|
|
|
/* GPIO/timing information for the power on/off sequences */
|
|
struct acpi_power_res_params {
|
|
/* GPIO used to take device out of reset or to put it into reset. */
|
|
struct acpi_gpio *reset_gpio;
|
|
/* Delay to be inserted after device is taken out of reset.
|
|
* (_ON method delay)
|
|
*/
|
|
unsigned int reset_delay_ms;
|
|
/* Delay to be inserted after device is put into reset.
|
|
* (_OFF method delay)
|
|
*/
|
|
unsigned int reset_off_delay_ms;
|
|
/* GPIO used to enable device. */
|
|
struct acpi_gpio *enable_gpio;
|
|
/* Delay to be inserted after device is enabled.
|
|
* (_ON method delay)
|
|
*/
|
|
unsigned int enable_delay_ms;
|
|
/* Delay to be inserted after device is disabled.
|
|
* (_OFF method delay)
|
|
*/
|
|
unsigned int enable_off_delay_ms;
|
|
/* GPIO used to stop operation of device. */
|
|
struct acpi_gpio *stop_gpio;
|
|
/* Delay to be inserted after disabling stop.
|
|
* (_ON method delay)
|
|
*/
|
|
unsigned int stop_delay_ms;
|
|
/* Delay to be inserted after enabling stop.
|
|
* (_OFF method delay)
|
|
*/
|
|
unsigned int stop_off_delay_ms;
|
|
|
|
/* Write a _STA method that uses the state of the GPIOs to determine if
|
|
* the PowerResource is ON or OFF. If this is false, the _STA method
|
|
* will always return ON.
|
|
*/
|
|
bool use_gpio_for_status;
|
|
};
|
|
|
|
/*
|
|
* Add a basic PowerResource block for a device that includes
|
|
* GPIOs to control enable, reset and stop operation of the device. Each
|
|
* GPIO is optional, but at least one must be provided.
|
|
*
|
|
* Reset - Put the device into / take the device out of reset.
|
|
* Enable - Enable / disable power to device.
|
|
* Stop - Stop / start operation of device.
|
|
*/
|
|
void acpi_device_add_power_res(const struct acpi_power_res_params *params);
|
|
|
|
/*
|
|
* Writing Device Properties objects via _DSD
|
|
*
|
|
* http://uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
|
|
* http://uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.pdf
|
|
*
|
|
* The Device Property Hierarchy can be multiple levels deep with multiple
|
|
* children possible in each level. In order to support this flexibility
|
|
* the device property hierarchy must be built up before being written out.
|
|
*
|
|
* For example:
|
|
*
|
|
* // Child table with string and integer
|
|
* struct acpi_dp *child = acpi_dp_new_table("CHLD");
|
|
* acpi_dp_add_string(child, "childstring", "CHILD");
|
|
* acpi_dp_add_integer(child, "childint", 100);
|
|
*
|
|
* // _DSD table with integer and gpio and child pointer
|
|
* struct acpi_dp *dsd = acpi_dp_new_table("_DSD");
|
|
* acpi_dp_add_integer(dsd, "number1", 1);
|
|
* acpi_dp_add_gpio(dsd, "gpio", "\_SB.PCI0.GPIO", 0, 0, 1);
|
|
* acpi_dp_add_child(dsd, "child", child);
|
|
*
|
|
* // Write entries into SSDT and clean up resources
|
|
* acpi_dp_write(dsd);
|
|
*
|
|
* Name(_DSD, Package() {
|
|
* ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301")
|
|
* Package() {
|
|
* Package() { "gpio", Package() { \_SB.PCI0.GPIO, 0, 0, 0 } }
|
|
* Package() { "number1", 1 }
|
|
* }
|
|
* ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b")
|
|
* Package() {
|
|
* Package() { "child", CHLD }
|
|
* }
|
|
* }
|
|
* Name(CHLD, Package() {
|
|
* ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301")
|
|
* Package() {
|
|
* Package() { "childstring", "CHILD" }
|
|
* Package() { "childint", 100 }
|
|
* }
|
|
* }
|
|
*/
|
|
|
|
/* Start a new Device Property table with provided ACPI reference */
|
|
struct acpi_dp *acpi_dp_new_table(const char *ref);
|
|
|
|
/* Add package of device properties with a unique UUID */
|
|
struct acpi_dp *acpi_dp_add_package(struct acpi_dp *dp, struct acpi_dp *package);
|
|
|
|
/* Add integer Device Property */
|
|
struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name,
|
|
uint64_t value);
|
|
|
|
/* Add string Device Property */
|
|
struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name,
|
|
const char *string);
|
|
|
|
/* Add ACPI reference Device Property */
|
|
struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name,
|
|
const char *reference);
|
|
|
|
/* Add an array of Device Properties */
|
|
struct acpi_dp *acpi_dp_add_array(struct acpi_dp *dp, struct acpi_dp *array);
|
|
|
|
/* Add an array of integers Device Property */
|
|
struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name,
|
|
const uint64_t *array, int len);
|
|
|
|
/* Add a GPIO binding Device Property */
|
|
struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
|
|
const char *ref, int index, int pin,
|
|
int active_low);
|
|
|
|
struct acpi_gpio_res_params {
|
|
/* Reference to the parent device. */
|
|
const char *ref;
|
|
/* Index to the GpioIo resource within the _CRS. */
|
|
int index;
|
|
/* Index to the pin within the GpioIo resource, usually 0. */
|
|
int pin;
|
|
/* Flag to indicate if pin is active low. */
|
|
int active_low;
|
|
};
|
|
|
|
/* Add a GPIO binding device property for array of GPIOs */
|
|
struct acpi_dp *acpi_dp_add_gpio_array(struct acpi_dp *dp, const char *name,
|
|
const struct acpi_gpio_res_params *params,
|
|
size_t param_count);
|
|
|
|
/* Add a child table of Device Properties */
|
|
struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name,
|
|
struct acpi_dp *child);
|
|
|
|
/* Add a list of Device Properties, returns the number of properties added */
|
|
size_t acpi_dp_add_property_list(struct acpi_dp *dp,
|
|
const struct acpi_dp *property_list,
|
|
size_t property_count);
|
|
|
|
/* Write Device Property hierarchy and clean up resources */
|
|
void acpi_dp_write(struct acpi_dp *table);
|
|
|
|
/*
|
|
* Helper function to write a PCI device with _ADR object defined.
|
|
*
|
|
* IMPORTANT: Scope of a device created in SSDT cannot be used to add ACPI nodes under that
|
|
* scope in DSDT. So, if there are any references to this PCI device scope required from static
|
|
* asl files, do not use this function and instead add the device to DSDT as well.
|
|
*/
|
|
void acpi_device_write_pci_dev(const struct device *dev);
|
|
|
|
#endif /* __ACPI_ACPI_DEVICE_H__ */
|