1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #ifndef __ACPI_ACPI_DEVICE_H__ 4 #define __ACPI_ACPI_DEVICE_H__ 5 6 #include <device/i2c.h> 7 #include <spi-generic.h> 8 #include <types.h> 9 10 enum acpi_dp_type { 11 ACPI_DP_TYPE_UNKNOWN, 12 ACPI_DP_TYPE_INTEGER, 13 ACPI_DP_TYPE_STRING, 14 ACPI_DP_TYPE_REFERENCE, 15 ACPI_DP_TYPE_TABLE, 16 ACPI_DP_TYPE_ARRAY, 17 ACPI_DP_TYPE_CHILD, 18 ACPI_DP_TYPE_PACKAGE, 19 }; 20 21 struct acpi_dp { 22 enum acpi_dp_type type; 23 const char *name; 24 const char *uuid; 25 struct acpi_dp *next; 26 union { 27 struct acpi_dp *child; 28 struct acpi_dp *array; 29 }; 30 union { 31 uint64_t integer; 32 const char *string; 33 }; 34 }; 35 36 #define ACPI_DESCRIPTOR_LARGE (1 << 7) 37 #define ACPI_DESCRIPTOR_INTERRUPT (ACPI_DESCRIPTOR_LARGE | 9) 38 #define ACPI_DESCRIPTOR_GPIO (ACPI_DESCRIPTOR_LARGE | 12) 39 #define ACPI_DESCRIPTOR_SERIAL_BUS (ACPI_DESCRIPTOR_LARGE | 14) 40 41 /* 42 * PRP0001 is a special DT namespace link device ID. It provides a means to use 43 * existing DT-compatible device identification in ACPI. When this _HID is used 44 * by an ACPI device, the ACPI subsystem in OS looks up "compatible" property in 45 * device object's _DSD and will use the value of that property to identify the 46 * corresponding device in analogy with the original DT device identification 47 * algorithm. 48 * More details can be found in Linux kernel documentation: 49 * Documentation/acpi/enumeration.txt 50 */ 51 #define ACPI_DT_NAMESPACE_HID "PRP0001" 52 53 struct device; 54 const char *acpi_device_name(const struct device *dev); 55 const char *acpi_device_hid(const struct device *dev); 56 uint32_t acpi_device_uid(const struct device *dev); 57 const char *acpi_device_path(const struct device *dev); 58 const char *acpi_device_scope(const struct device *dev); 59 const char *acpi_device_path_join(const struct device *dev, const char *name); 60 int acpi_device_status(const struct device *dev); 61 void acpi_device_write_uid(const struct device *dev); 62 63 /* 64 * ACPI Descriptor for extended Interrupt() 65 */ 66 67 enum acpi_irq_mode { 68 ACPI_IRQ_EDGE_TRIGGERED, 69 ACPI_IRQ_LEVEL_TRIGGERED 70 }; 71 72 enum acpi_irq_polarity { 73 ACPI_IRQ_ACTIVE_LOW, 74 ACPI_IRQ_ACTIVE_HIGH, 75 ACPI_IRQ_ACTIVE_BOTH 76 }; 77 78 enum acpi_irq_shared { 79 ACPI_IRQ_EXCLUSIVE, 80 ACPI_IRQ_SHARED 81 }; 82 83 enum acpi_irq_wake { 84 ACPI_IRQ_NO_WAKE, 85 ACPI_IRQ_WAKE 86 }; 87 88 struct acpi_irq { 89 unsigned int pin; 90 enum acpi_irq_mode mode; 91 enum acpi_irq_polarity polarity; 92 enum acpi_irq_shared shared; 93 enum acpi_irq_wake wake; 94 }; 95 96 #define ACPI_IRQ_CFG(_pin, _mode, _pol, _shared, _wake) { \ 97 .pin = (_pin), \ 98 .mode = (_mode), \ 99 .polarity = (_pol), \ 100 .shared = (_shared), \ 101 .wake = (_wake) } 102 103 #define ACPI_IRQ_EDGE_LOW(x) \ 104 ACPI_IRQ_CFG((x), ACPI_IRQ_EDGE_TRIGGERED, ACPI_IRQ_ACTIVE_LOW, \ 105 ACPI_IRQ_EXCLUSIVE, ACPI_IRQ_NO_WAKE) 106 107 #define ACPI_IRQ_EDGE_HIGH(x) \ 108 ACPI_IRQ_CFG((x), ACPI_IRQ_EDGE_TRIGGERED, ACPI_IRQ_ACTIVE_HIGH, \ 109 ACPI_IRQ_EXCLUSIVE, ACPI_IRQ_NO_WAKE) 110 111 #define ACPI_IRQ_LEVEL_LOW(x) \ 112 ACPI_IRQ_CFG((x), ACPI_IRQ_LEVEL_TRIGGERED, ACPI_IRQ_ACTIVE_LOW, \ 113 ACPI_IRQ_SHARED, ACPI_IRQ_NO_WAKE) 114 115 #define ACPI_IRQ_LEVEL_HIGH(x) \ 116 ACPI_IRQ_CFG((x), ACPI_IRQ_LEVEL_TRIGGERED, ACPI_IRQ_ACTIVE_HIGH, \ 117 ACPI_IRQ_SHARED, ACPI_IRQ_NO_WAKE) 118 119 #define ACPI_IRQ_WAKE_EDGE_LOW(x) \ 120 ACPI_IRQ_CFG((x), ACPI_IRQ_EDGE_TRIGGERED, ACPI_IRQ_ACTIVE_LOW, \ 121 ACPI_IRQ_EXCLUSIVE, ACPI_IRQ_WAKE) 122 123 #define ACPI_IRQ_WAKE_EDGE_HIGH(x) \ 124 ACPI_IRQ_CFG((x), ACPI_IRQ_EDGE_TRIGGERED, ACPI_IRQ_ACTIVE_HIGH, \ 125 ACPI_IRQ_EXCLUSIVE, ACPI_IRQ_WAKE) 126 127 #define ACPI_IRQ_WAKE_LEVEL_LOW(x) \ 128 ACPI_IRQ_CFG((x), ACPI_IRQ_LEVEL_TRIGGERED, ACPI_IRQ_ACTIVE_LOW, \ 129 ACPI_IRQ_SHARED, ACPI_IRQ_WAKE) 130 131 #define ACPI_IRQ_WAKE_LEVEL_HIGH(x) \ 132 ACPI_IRQ_CFG((x), ACPI_IRQ_LEVEL_TRIGGERED, ACPI_IRQ_ACTIVE_HIGH, \ 133 ACPI_IRQ_SHARED, ACPI_IRQ_WAKE) 134 135 /* Write extended Interrupt() descriptor to SSDT AML output */ 136 void acpi_device_write_interrupt(const struct acpi_irq *irq); 137 138 /* 139 * ACPI Descriptors for GpioIo() and GpioInterrupt() 140 */ 141 142 enum acpi_gpio_type { 143 ACPI_GPIO_TYPE_INTERRUPT, 144 ACPI_GPIO_TYPE_IO 145 }; 146 147 enum acpi_gpio_pull { 148 ACPI_GPIO_PULL_DEFAULT, 149 ACPI_GPIO_PULL_UP, 150 ACPI_GPIO_PULL_DOWN, 151 ACPI_GPIO_PULL_NONE 152 }; 153 154 enum acpi_gpio_io_restrict { 155 ACPI_GPIO_IO_RESTRICT_NONE, 156 ACPI_GPIO_IO_RESTRICT_INPUT, 157 ACPI_GPIO_IO_RESTRICT_OUTPUT, 158 ACPI_GPIO_IO_RESTRICT_PRESERVE 159 }; 160 161 #define ACPI_GPIO_REVISION_ID 1 162 #define ACPI_GPIO_MAX_PINS 8 163 164 struct acpi_gpio { 165 int pin_count; 166 uint16_t pins[ACPI_GPIO_MAX_PINS]; 167 168 enum acpi_gpio_type type; 169 enum acpi_gpio_pull pull; 170 const char *resource; 171 172 /* GpioInt */ 173 uint16_t interrupt_debounce_timeout; /* 1/100 ms */ 174 struct acpi_irq irq; 175 176 /* GpioIo */ 177 uint16_t output_drive_strength; /* 1/100 mA */ 178 int io_shared; 179 enum acpi_gpio_io_restrict io_restrict; 180 /* 181 * As per ACPI spec, GpioIo does not have any polarity associated with it. Linux kernel 182 * uses `active_low` argument within GPIO _DSD property to allow BIOS to indicate if the 183 * corresponding GPIO should be treated as active low. Thus, if the GPIO has active high 184 * polarity or if it does not have any polarity, then the `active_low` argument is 185 * supposed to be set to 0. 186 * 187 * Reference: 188 * https://www.kernel.org/doc/html/latest/firmware-guide/acpi/gpio-properties.html 189 */ 190 bool active_low; 191 }; 192 193 /* GpioIo-related macros */ 194 #define ACPI_GPIO_CFG(_gpio, _io_restrict, _active_low) { \ 195 .type = ACPI_GPIO_TYPE_IO, \ 196 .pull = ACPI_GPIO_PULL_DEFAULT, \ 197 .io_restrict = _io_restrict, \ 198 .active_low = _active_low, \ 199 .pin_count = 1, \ 200 .pins = { (_gpio) } } 201 202 /* Basic output GPIO with default pull settings */ 203 #define ACPI_GPIO_OUTPUT_CFG(gpio, active_low) \ 204 ACPI_GPIO_CFG(gpio, ACPI_GPIO_IO_RESTRICT_OUTPUT, active_low) 205 206 #define ACPI_GPIO_OUTPUT(gpio) ACPI_GPIO_OUTPUT_CFG(gpio, 0) 207 #define ACPI_GPIO_OUTPUT_ACTIVE_HIGH(gpio) ACPI_GPIO_OUTPUT_CFG(gpio, 0) 208 #define ACPI_GPIO_OUTPUT_ACTIVE_LOW(gpio) ACPI_GPIO_OUTPUT_CFG(gpio, 1) 209 210 /* Basic input GPIO with default pull settings */ 211 #define ACPI_GPIO_INPUT_CFG(gpio, polarity) \ 212 ACPI_GPIO_CFG(gpio, ACPI_GPIO_IO_RESTRICT_INPUT, polarity) 213 214 #define ACPI_GPIO_INPUT(gpio) ACPI_GPIO_INPUT_CFG(gpio, 0) 215 #define ACPI_GPIO_INPUT_ACTIVE_HIGH(gpio) ACPI_GPIO_INPUT_CFG(gpio, 0) 216 #define ACPI_GPIO_INPUT_ACTIVE_LOW(gpio) ACPI_GPIO_INPUT_CFG(gpio, 1) 217 218 /* GpioInt-related macros */ 219 #define ACPI_GPIO_IRQ_CFG(_gpio, _mode, _polarity, _wake) { \ 220 .type = ACPI_GPIO_TYPE_INTERRUPT, \ 221 .pull = ACPI_GPIO_PULL_DEFAULT, \ 222 .irq.mode = _mode, \ 223 .irq.polarity = _polarity, \ 224 .irq.wake = _wake, \ 225 .pin_count = 1, \ 226 .pins = { (_gpio) } } 227 228 #define ACPI_GPIO_IRQ_EDGE(gpio, polarity) \ 229 ACPI_GPIO_IRQ_CFG(gpio, ACPI_IRQ_EDGE_TRIGGERED, polarity, 0) 230 231 #define ACPI_GPIO_IRQ_EDGE_WAKE(gpio, polarity) \ 232 ACPI_GPIO_IRQ_CFG(gpio, ACPI_IRQ_EDGE_TRIGGERED, polarity, ACPI_IRQ_WAKE) 233 234 #define ACPI_GPIO_IRQ_LEVEL(gpio, polarity) \ 235 ACPI_GPIO_IRQ_CFG(gpio, ACPI_IRQ_LEVEL_TRIGGERED, polarity, 0) 236 237 #define ACPI_GPIO_IRQ_LEVEL_WAKE(gpio, polarity) \ 238 ACPI_GPIO_IRQ_CFG(gpio, ACPI_IRQ_LEVEL_TRIGGERED, polarity, ACPI_IRQ_WAKE) 239 240 /* Edge Triggered Active High GPIO interrupt */ 241 #define ACPI_GPIO_IRQ_EDGE_HIGH(gpio) \ 242 ACPI_GPIO_IRQ_EDGE(gpio, ACPI_IRQ_ACTIVE_HIGH) 243 244 /* Edge Triggered Active Low GPIO interrupt */ 245 #define ACPI_GPIO_IRQ_EDGE_LOW(gpio) \ 246 ACPI_GPIO_IRQ_EDGE(gpio, ACPI_IRQ_ACTIVE_LOW) 247 248 /* Edge Triggered Active Both GPIO interrupt */ 249 #define ACPI_GPIO_IRQ_EDGE_BOTH(gpio) \ 250 ACPI_GPIO_IRQ_EDGE(gpio, ACPI_IRQ_ACTIVE_BOTH) 251 252 /* Edge Triggered Active High GPIO interrupt with wake */ 253 #define ACPI_GPIO_IRQ_EDGE_HIGH_WAKE(gpio) \ 254 ACPI_GPIO_IRQ_EDGE_WAKE(gpio, ACPI_IRQ_ACTIVE_HIGH) 255 256 /* Edge Triggered Active Low GPIO interrupt with wake */ 257 #define ACPI_GPIO_IRQ_EDGE_LOW_WAKE(gpio) \ 258 ACPI_GPIO_IRQ_EDGE_WAKE(gpio, ACPI_IRQ_ACTIVE_LOW) 259 260 /* Edge Triggered Active Both GPIO interrupt with wake */ 261 #define ACPI_GPIO_IRQ_EDGE_BOTH_WAKE(gpio) \ 262 ACPI_GPIO_IRQ_EDGE_WAKE(gpio, ACPI_IRQ_ACTIVE_BOTH) 263 264 /* Level Triggered Active High GPIO interrupt */ 265 #define ACPI_GPIO_IRQ_LEVEL_HIGH(gpio) \ 266 ACPI_GPIO_IRQ_LEVEL(gpio, ACPI_IRQ_ACTIVE_HIGH) 267 268 /* Level Triggered Active Low GPIO interrupt */ 269 #define ACPI_GPIO_IRQ_LEVEL_LOW(gpio) \ 270 ACPI_GPIO_IRQ_LEVEL(gpio, ACPI_IRQ_ACTIVE_LOW) 271 272 /* Level Triggered Active High GPIO interrupt with wake */ 273 #define ACPI_GPIO_IRQ_LEVEL_HIGH_WAKE(gpio) \ 274 ACPI_GPIO_IRQ_LEVEL_WAKE(gpio, ACPI_IRQ_ACTIVE_HIGH) 275 276 /* Level Triggered Active Low GPIO interrupt with wake */ 277 #define ACPI_GPIO_IRQ_LEVEL_LOW_WAKE(gpio) \ 278 ACPI_GPIO_IRQ_LEVEL_WAKE(gpio, ACPI_IRQ_ACTIVE_LOW) 279 280 /* Write GpioIo() or GpioInt() descriptor to SSDT AML output */ 281 void acpi_device_write_gpio(const struct acpi_gpio *gpio); 282 283 /* 284 * ACPI Descriptors for Serial Bus interfaces 285 */ 286 287 #define ACPI_SERIAL_BUS_TYPE_I2C 1 288 #define ACPI_SERIAL_BUS_TYPE_SPI 2 289 #define ACPI_SERIAL_BUS_TYPE_UART 3 290 291 #define ACPI_I2C_SERIAL_BUS_REVISION_ID 1 /* TODO: upgrade to 2 */ 292 #define ACPI_I2C_TYPE_SPECIFIC_REVISION_ID 1 293 #define ACPI_SPI_SERIAL_BUS_REVISION_ID 1 294 #define ACPI_SPI_TYPE_SPECIFIC_REVISION_ID 1 295 #define ACPI_UART_SERIAL_BUS_REVISION_ID 1 296 #define ACPI_UART_TYPE_SPECIFIC_REVISION_ID 1 297 298 /* 299 * ACPI I2C Bus 300 */ 301 302 struct acpi_i2c { 303 /* I2C Address */ 304 uint16_t address; 305 /* 7 or 10 bit Address Mode */ 306 enum i2c_address_mode mode_10bit; 307 /* I2C Bus Speed in Hz */ 308 enum i2c_speed speed; 309 /* Reference to I2C controller */ 310 const char *resource; 311 }; 312 313 /* Write I2cSerialBus() descriptor to SSDT AML output */ 314 void acpi_device_write_i2c(const struct acpi_i2c *i2c); 315 316 /* Write GPIO descriptor of DSD property */ 317 int acpi_device_write_dsd_gpio(struct acpi_gpio *gpio, int *curr_index); 318 319 /* 320 * ACPI SPI Bus 321 */ 322 323 struct acpi_spi { 324 /* Device selection */ 325 uint16_t device_select; 326 /* Device selection line is active high or low */ 327 enum spi_polarity device_select_polarity; 328 /* 3 or 4 wire SPI connection */ 329 enum spi_wire_mode wire_mode; 330 /* Connection speed in HZ */ 331 unsigned int speed; 332 /* Size in bits of smallest transfer unit */ 333 u8 data_bit_length; 334 /* Phase of clock pulse on which to capture data */ 335 enum spi_clock_phase clock_phase; 336 /* Indicate if clock is high or low during first phase */ 337 enum spi_polarity clock_polarity; 338 /* Reference to SPI controller */ 339 const char *resource; 340 }; 341 342 /* Write SPI Bus descriptor to SSDT AML output */ 343 void acpi_device_write_spi(const struct acpi_spi *spi); 344 345 /* 346 * ACPI UART Bus 347 */ 348 349 enum acpi_uart_data_bits { 350 ACPI_UART_DATA_BITS_5, 351 ACPI_UART_DATA_BITS_6, 352 ACPI_UART_DATA_BITS_7, 353 ACPI_UART_DATA_BITS_8, 354 ACPI_UART_DATA_BITS_9 355 }; 356 357 enum acpi_uart_stop_bits { 358 ACPI_UART_STOP_BITS_0, 359 ACPI_UART_STOP_BITS_1, 360 ACPI_UART_STOP_BITS_1_5, 361 ACPI_UART_STOP_BITS_2 362 }; 363 364 enum acpi_uart_lines { 365 ACPI_UART_LINE_DTD = BIT(2), /* Data Carrier Detect */ 366 ACPI_UART_LINE_RI = BIT(3), /* Ring Indicator */ 367 ACPI_UART_LINE_DSR = BIT(4), /* Data Set Ready */ 368 ACPI_UART_LINE_DTR = BIT(5), /* Data Terminal Ready */ 369 ACPI_UART_LINE_CTS = BIT(6), /* Clear to Send */ 370 ACPI_UART_LINE_RTS = BIT(7) /* Request to Send */ 371 }; 372 373 enum acpi_uart_endian { 374 ACPI_UART_ENDIAN_LITTLE, 375 ACPI_UART_ENDIAN_BIG 376 }; 377 378 enum acpi_uart_parity { 379 ACPI_UART_PARITY_NONE, 380 ACPI_UART_PARITY_EVEN, 381 ACPI_UART_PARITY_ODD, 382 ACPI_UART_PARITY_MARK, 383 ACPI_UART_PARITY_SPACE 384 }; 385 386 enum acpi_uart_flow_control { 387 ACPI_UART_FLOW_NONE, 388 ACPI_UART_FLOW_HARDWARE, 389 ACPI_UART_FLOW_SOFTWARE 390 }; 391 392 struct acpi_uart { 393 /* Initial Baud Rate in bits per second */ 394 uint32_t initial_baud_rate; 395 /* Number of bits of data in a packet (value between 5-9) */ 396 enum acpi_uart_data_bits data_bits; 397 /* Number of bits to signal end of packet */ 398 enum acpi_uart_stop_bits stop_bits; 399 /* Bitmask indicating presence or absence of particular line */ 400 unsigned int lines_in_use; 401 /* Specify if the device expects big or little endian format */ 402 enum acpi_uart_endian endian; 403 /* Specify the type of parity bits included after the data in a packet */ 404 enum acpi_uart_parity parity; 405 /* Specify the flow control method */ 406 enum acpi_uart_flow_control flow_control; 407 /* Upper limit in bytes of the buffer sizes for this device */ 408 uint16_t rx_fifo_bytes; 409 uint16_t tx_fifo_bytes; 410 /* Set true if UART is shared, false if it is exclusive for one device */ 411 bool shared; 412 /* Reference to UART controller */ 413 const char *resource; 414 }; 415 416 #define ACPI_UART_RAW_DEVICE(baud_rate, fifo_bytes) { \ 417 .initial_baud_rate = (baud_rate), \ 418 .data_bits = ACPI_UART_DATA_BITS_8, \ 419 .stop_bits = ACPI_UART_STOP_BITS_1, \ 420 .endian = ACPI_UART_ENDIAN_LITTLE, \ 421 .parity = ACPI_UART_PARITY_NONE, \ 422 .flow_control = ACPI_UART_FLOW_NONE, \ 423 .rx_fifo_bytes = (fifo_bytes), \ 424 .tx_fifo_bytes = (fifo_bytes), \ 425 .shared = false } 426 427 /* Write UARTSerialBusV2() descriptor to SSDT AML output */ 428 void acpi_device_write_uart(const struct acpi_uart *uart); 429 430 /* GPIO/timing information for the power on/off sequences */ 431 struct acpi_power_res_params { 432 /* GPIO used to take device out of reset or to put it into reset. */ 433 struct acpi_gpio *reset_gpio; 434 /* Delay to be inserted after device is taken out of reset. 435 * (_ON method delay) 436 */ 437 unsigned int reset_delay_ms; 438 /* Delay to be inserted after device is put into reset. 439 * (_OFF method delay) 440 */ 441 unsigned int reset_off_delay_ms; 442 /* GPIO used to enable device. */ 443 struct acpi_gpio *enable_gpio; 444 /* Delay to be inserted after device is enabled. 445 * (_ON method delay) 446 */ 447 unsigned int enable_delay_ms; 448 /* Delay to be inserted after device is disabled. 449 * (_OFF method delay) 450 */ 451 unsigned int enable_off_delay_ms; 452 /* GPIO used to stop operation of device. */ 453 struct acpi_gpio *stop_gpio; 454 /* Delay to be inserted after disabling stop. 455 * (_ON method delay) 456 */ 457 unsigned int stop_delay_ms; 458 /* Delay to be inserted after enabling stop. 459 * (_OFF method delay) 460 */ 461 unsigned int stop_off_delay_ms; 462 463 /* Write a _STA method that uses the state of the GPIOs to determine if 464 * the PowerResource is ON or OFF. If this is false, the _STA method 465 * will always return ON. 466 */ 467 bool use_gpio_for_status; 468 }; 469 470 /* 471 * Add a basic PowerResource block for a device that includes 472 * GPIOs to control enable, reset and stop operation of the device. Each 473 * GPIO is optional, but at least one must be provided. 474 * 475 * Reset - Put the device into / take the device out of reset. 476 * Enable - Enable / disable power to device. 477 * Stop - Stop / start operation of device. 478 */ 479 void acpi_device_add_power_res(const struct acpi_power_res_params *params); 480 481 /* 482 * Writing Device Properties objects via _DSD 483 * 484 * http://uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf 485 * http://uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.pdf 486 * 487 * The Device Property Hierarchy can be multiple levels deep with multiple 488 * children possible in each level. In order to support this flexibility 489 * the device property hierarchy must be built up before being written out. 490 * 491 * For example: 492 * 493 * // Child table with string and integer 494 * struct acpi_dp *child = acpi_dp_new_table("CHLD"); 495 * acpi_dp_add_string(child, "childstring", "CHILD"); 496 * acpi_dp_add_integer(child, "childint", 100); 497 * 498 * // _DSD table with integer and gpio and child pointer 499 * struct acpi_dp *dsd = acpi_dp_new_table("_DSD"); 500 * acpi_dp_add_integer(dsd, "number1", 1); 501 * acpi_dp_add_gpio(dsd, "gpio", "\_SB.PCI0.GPIO", 0, 0, 1); 502 * acpi_dp_add_child(dsd, "child", child); 503 * 504 * // Write entries into SSDT and clean up resources 505 * acpi_dp_write(dsd); 506 * 507 * Name(_DSD, Package() { 508 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") 509 * Package() { 510 * Package() { "gpio", Package() { \_SB.PCI0.GPIO, 0, 0, 0 } } 511 * Package() { "number1", 1 } 512 * } 513 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b") 514 * Package() { 515 * Package() { "child", CHLD } 516 * } 517 * } 518 * Name(CHLD, Package() { 519 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") 520 * Package() { 521 * Package() { "childstring", "CHILD" } 522 * Package() { "childint", 100 } 523 * } 524 * } 525 */ 526 527 /* Start a new Device Property table with provided ACPI reference */ 528 struct acpi_dp *acpi_dp_new_table(const char *ref); 529 530 /* Add package of device properties with a unique UUID */ 531 struct acpi_dp *acpi_dp_add_package(struct acpi_dp *dp, struct acpi_dp *package); 532 533 /* Add integer Device Property */ 534 struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name, 535 uint64_t value); 536 537 /* Add string Device Property */ 538 struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name, 539 const char *string); 540 541 /* Add ACPI reference Device Property */ 542 struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name, 543 const char *reference); 544 545 /* Add an array of Device Properties */ 546 struct acpi_dp *acpi_dp_add_array(struct acpi_dp *dp, struct acpi_dp *array); 547 548 /* Add an array of integers Device Property */ 549 struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name, 550 const uint64_t *array, int len); 551 552 /* Add a GPIO binding Device Property */ 553 struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name, 554 const char *ref, int index, int pin, 555 int active_low); 556 557 struct acpi_gpio_res_params { 558 /* Reference to the parent device. */ 559 const char *ref; 560 /* Index to the GpioIo resource within the _CRS. */ 561 int index; 562 /* Index to the pin within the GpioIo resource, usually 0. */ 563 int pin; 564 /* Flag to indicate if pin is active low. */ 565 int active_low; 566 }; 567 568 /* Add a GPIO binding device property for array of GPIOs */ 569 struct acpi_dp *acpi_dp_add_gpio_array(struct acpi_dp *dp, const char *name, 570 const struct acpi_gpio_res_params *params, 571 size_t param_count); 572 573 /* Add a child table of Device Properties */ 574 struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name, 575 struct acpi_dp *child); 576 577 /* Add a list of Device Properties, returns the number of properties added */ 578 size_t acpi_dp_add_property_list(struct acpi_dp *dp, 579 const struct acpi_dp *property_list, 580 size_t property_count); 581 582 /* Write Device Property hierarchy and clean up resources */ 583 void acpi_dp_write(struct acpi_dp *table); 584 585 /* 586 * Helper function to write a PCI device with _ADR object defined. 587 * 588 * IMPORTANT: Scope of a device created in SSDT cannot be used to add ACPI nodes under that 589 * scope in DSDT. So, if there are any references to this PCI device scope required from static 590 * asl files, do not use this function and instead add the device to DSDT as well. 591 */ 592 void acpi_device_write_pci_dev(const struct device *dev); 593 594 /* Helper function to add ExternalFacingPort to _DSD in the current scope */ 595 void acpi_device_add_external_facing_port(struct acpi_dp *dsd); 596 597 /* Helper function to add HotPlugSupportInD3 to _DSD in the current scope */ 598 void acpi_device_add_hotplug_support_in_d3(struct acpi_dp *dsd); 599 600 /* Helper function to add DmaProperty to _DSD in the current scope */ 601 void acpi_device_add_dma_property(struct acpi_dp *dsd); 602 603 /* Helper function to add StorageD3Enable to _DSD in the current scope */ 604 void acpi_device_add_storage_d3_enable(struct acpi_dp *dsd); 605 606 #endif /* __ACPI_ACPI_DEVICE_H__ */ 607