Mika Westerberg | 0d9a693 | 2014-10-29 15:41:01 +0100 | [diff] [blame] | 1 | _DSD Device Properties Related to GPIO |
| 2 | -------------------------------------- |
| 3 | |
Rafael J. Wysocki | a00212e | 2015-05-04 01:58:27 +0200 | [diff] [blame] | 4 | With the release of ACPI 5.1, the _DSD configuration object finally |
| 5 | allows names to be given to GPIOs (and other things as well) returned |
| 6 | by _CRS. Previously, we were only able to use an integer index to find |
Mika Westerberg | 0d9a693 | 2014-10-29 15:41:01 +0100 | [diff] [blame] | 7 | the corresponding GPIO, which is pretty error prone (it depends on |
| 8 | the _CRS output ordering, for example). |
| 9 | |
| 10 | With _DSD we can now query GPIOs using a name instead of an integer |
| 11 | index, like the ASL example below shows: |
| 12 | |
| 13 | // Bluetooth device with reset and shutdown GPIOs |
| 14 | Device (BTH) |
| 15 | { |
| 16 | Name (_HID, ...) |
| 17 | |
| 18 | Name (_CRS, ResourceTemplate () |
| 19 | { |
| 20 | GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly, |
| 21 | "\\_SB.GPO0", 0, ResourceConsumer) {15} |
| 22 | GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly, |
| 23 | "\\_SB.GPO0", 0, ResourceConsumer) {27, 31} |
| 24 | }) |
| 25 | |
| 26 | Name (_DSD, Package () |
| 27 | { |
| 28 | ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), |
| 29 | Package () |
| 30 | { |
Mika Westerberg | 060d791 | 2016-09-23 17:57:06 +0300 | [diff] [blame] | 31 | Package () {"reset-gpios", Package() {^BTH, 1, 1, 0 }}, |
| 32 | Package () {"shutdown-gpios", Package() {^BTH, 0, 0, 0 }}, |
Mika Westerberg | 0d9a693 | 2014-10-29 15:41:01 +0100 | [diff] [blame] | 33 | } |
| 34 | }) |
| 35 | } |
| 36 | |
| 37 | The format of the supported GPIO property is: |
| 38 | |
| 39 | Package () { "name", Package () { ref, index, pin, active_low }} |
| 40 | |
| 41 | ref - The device that has _CRS containing GpioIo()/GpioInt() resources, |
| 42 | typically this is the device itself (BTH in our case). |
| 43 | index - Index of the GpioIo()/GpioInt() resource in _CRS starting from zero. |
| 44 | pin - Pin in the GpioIo()/GpioInt() resource. Typically this is zero. |
| 45 | active_low - If 1 the GPIO is marked as active_low. |
| 46 | |
| 47 | Since ACPI GpioIo() resource does not have a field saying whether it is |
| 48 | active low or high, the "active_low" argument can be used here. Setting |
| 49 | it to 1 marks the GPIO as active low. |
| 50 | |
Mika Westerberg | 060d791 | 2016-09-23 17:57:06 +0300 | [diff] [blame] | 51 | In our Bluetooth example the "reset-gpios" refers to the second GpioIo() |
Mika Westerberg | 0d9a693 | 2014-10-29 15:41:01 +0100 | [diff] [blame] | 52 | resource, second pin in that resource with the GPIO number of 31. |
Rafael J. Wysocki | e36d453 | 2014-11-03 23:39:57 +0100 | [diff] [blame] | 53 | |
Mika Westerberg | 6f7194a | 2016-10-21 17:21:29 +0300 | [diff] [blame] | 54 | It is possible to leave holes in the array of GPIOs. This is useful in |
| 55 | cases like with SPI host controllers where some chip selects may be |
| 56 | implemented as GPIOs and some as native signals. For example a SPI host |
| 57 | controller can have chip selects 0 and 2 implemented as GPIOs and 1 as |
| 58 | native: |
| 59 | |
| 60 | Package () { |
| 61 | "cs-gpios", |
| 62 | Package () { |
| 63 | ^GPIO, 19, 0, 0, // chip select 0: GPIO |
| 64 | 0, // chip select 1: native signal |
| 65 | ^GPIO, 20, 0, 0, // chip select 2: GPIO |
| 66 | } |
| 67 | } |
| 68 | |
Mika Westerberg | c80f1ba | 2016-10-21 17:21:30 +0300 | [diff] [blame] | 69 | Other supported properties |
| 70 | -------------------------- |
| 71 | |
| 72 | Following Device Tree compatible device properties are also supported by |
| 73 | _DSD device properties for GPIO controllers: |
| 74 | |
| 75 | - gpio-hog |
| 76 | - output-high |
| 77 | - output-low |
| 78 | - input |
| 79 | - line-name |
| 80 | |
| 81 | Example: |
| 82 | |
| 83 | Name (_DSD, Package () { |
| 84 | // _DSD Hierarchical Properties Extension UUID |
| 85 | ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), |
| 86 | Package () { |
| 87 | Package () {"hog-gpio8", "G8PU"} |
| 88 | } |
| 89 | }) |
| 90 | |
| 91 | Name (G8PU, Package () { |
| 92 | ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), |
| 93 | Package () { |
| 94 | Package () {"gpio-hog", 1}, |
| 95 | Package () {"gpios", Package () {8, 0}}, |
| 96 | Package () {"output-high", 1}, |
| 97 | Package () {"line-name", "gpio8-pullup"}, |
| 98 | } |
| 99 | }) |
| 100 | |
Mika Westerberg | 4035cc1 | 2016-10-21 17:21:32 +0300 | [diff] [blame] | 101 | - gpio-line-names |
| 102 | |
| 103 | Example: |
| 104 | |
| 105 | Package () { |
| 106 | "gpio-line-names", |
| 107 | Package () { |
| 108 | "SPI0_CS_N", "EXP2_INT", "MUX6_IO", "UART0_RXD", "MUX7_IO", |
| 109 | "LVL_C_A1", "MUX0_IO", "SPI1_MISO" |
| 110 | } |
| 111 | } |
| 112 | |
Mika Westerberg | c80f1ba | 2016-10-21 17:21:30 +0300 | [diff] [blame] | 113 | See Documentation/devicetree/bindings/gpio/gpio.txt for more information |
| 114 | about these properties. |
| 115 | |
Rafael J. Wysocki | e36d453 | 2014-11-03 23:39:57 +0100 | [diff] [blame] | 116 | ACPI GPIO Mappings Provided by Drivers |
| 117 | -------------------------------------- |
| 118 | |
| 119 | There are systems in which the ACPI tables do not contain _DSD but provide _CRS |
| 120 | with GpioIo()/GpioInt() resources and device drivers still need to work with |
| 121 | them. |
| 122 | |
| 123 | In those cases ACPI device identification objects, _HID, _CID, _CLS, _SUB, _HRV, |
| 124 | available to the driver can be used to identify the device and that is supposed |
| 125 | to be sufficient to determine the meaning and purpose of all of the GPIO lines |
| 126 | listed by the GpioIo()/GpioInt() resources returned by _CRS. In other words, |
| 127 | the driver is supposed to know what to use the GpioIo()/GpioInt() resources for |
| 128 | once it has identified the device. Having done that, it can simply assign names |
| 129 | to the GPIO lines it is going to use and provide the GPIO subsystem with a |
| 130 | mapping between those names and the ACPI GPIO resources corresponding to them. |
| 131 | |
| 132 | To do that, the driver needs to define a mapping table as a NULL-terminated |
| 133 | array of struct acpi_gpio_mapping objects that each contain a name, a pointer |
| 134 | to an array of line data (struct acpi_gpio_params) objects and the size of that |
| 135 | array. Each struct acpi_gpio_params object consists of three fields, |
| 136 | crs_entry_index, line_index, active_low, representing the index of the target |
| 137 | GpioIo()/GpioInt() resource in _CRS starting from zero, the index of the target |
| 138 | line in that resource starting from zero, and the active-low flag for that line, |
| 139 | respectively, in analogy with the _DSD GPIO property format specified above. |
| 140 | |
| 141 | For the example Bluetooth device discussed previously the data structures in |
| 142 | question would look like this: |
| 143 | |
| 144 | static const struct acpi_gpio_params reset_gpio = { 1, 1, false }; |
| 145 | static const struct acpi_gpio_params shutdown_gpio = { 0, 0, false }; |
| 146 | |
| 147 | static const struct acpi_gpio_mapping bluetooth_acpi_gpios[] = { |
Mika Westerberg | 060d791 | 2016-09-23 17:57:06 +0300 | [diff] [blame] | 148 | { "reset-gpios", &reset_gpio, 1 }, |
| 149 | { "shutdown-gpios", &shutdown_gpio, 1 }, |
Rafael J. Wysocki | e36d453 | 2014-11-03 23:39:57 +0100 | [diff] [blame] | 150 | { }, |
| 151 | }; |
| 152 | |
| 153 | Next, the mapping table needs to be passed as the second argument to |
| 154 | acpi_dev_add_driver_gpios() that will register it with the ACPI device object |
| 155 | pointed to by its first argument. That should be done in the driver's .probe() |
| 156 | routine. On removal, the driver should unregister its GPIO mapping table by |
| 157 | calling acpi_dev_remove_driver_gpios() on the ACPI device object where that |
| 158 | table was previously registered. |