1.. SPDX-License-Identifier: GPL-2.0 2 3====================================== 4_DSD Device Properties Related to GPIO 5====================================== 6 7With the release of ACPI 5.1, the _DSD configuration object finally 8allows names to be given to GPIOs (and other things as well) returned 9by _CRS. Previously, we were only able to use an integer index to find 10the corresponding GPIO, which is pretty error prone (it depends on 11the _CRS output ordering, for example). 12 13With _DSD we can now query GPIOs using a name instead of an integer 14index, like the ASL example below shows:: 15 16 // Bluetooth device with reset and shutdown GPIOs 17 Device (BTH) 18 { 19 Name (_HID, ...) 20 21 Name (_CRS, ResourceTemplate () 22 { 23 GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly, 24 "\\_SB.GPO0", 0, ResourceConsumer) {15} 25 GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly, 26 "\\_SB.GPO0", 0, ResourceConsumer) {27, 31} 27 }) 28 29 Name (_DSD, Package () 30 { 31 ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 32 Package () 33 { 34 Package () {"reset-gpios", Package() {^BTH, 1, 1, 0 }}, 35 Package () {"shutdown-gpios", Package() {^BTH, 0, 0, 0 }}, 36 } 37 }) 38 } 39 40The format of the supported GPIO property is:: 41 42 Package () { "name", Package () { ref, index, pin, active_low }} 43 44ref 45 The device that has _CRS containing GpioIo()/GpioInt() resources, 46 typically this is the device itself (BTH in our case). 47index 48 Index of the GpioIo()/GpioInt() resource in _CRS starting from zero. 49pin 50 Pin in the GpioIo()/GpioInt() resource. Typically this is zero. 51active_low 52 If 1 the GPIO is marked as active_low. 53 54Since ACPI GpioIo() resource does not have a field saying whether it is 55active low or high, the "active_low" argument can be used here. Setting 56it to 1 marks the GPIO as active low. 57 58In our Bluetooth example the "reset-gpios" refers to the second GpioIo() 59resource, second pin in that resource with the GPIO number of 31. 60 61It is possible to leave holes in the array of GPIOs. This is useful in 62cases like with SPI host controllers where some chip selects may be 63implemented as GPIOs and some as native signals. For example a SPI host 64controller can have chip selects 0 and 2 implemented as GPIOs and 1 as 65native:: 66 67 Package () { 68 "cs-gpios", 69 Package () { 70 ^GPIO, 19, 0, 0, // chip select 0: GPIO 71 0, // chip select 1: native signal 72 ^GPIO, 20, 0, 0, // chip select 2: GPIO 73 } 74 } 75 76Other supported properties 77========================== 78 79Following Device Tree compatible device properties are also supported by 80_DSD device properties for GPIO controllers: 81 82- gpio-hog 83- output-high 84- output-low 85- input 86- line-name 87 88Example:: 89 90 Name (_DSD, Package () { 91 // _DSD Hierarchical Properties Extension UUID 92 ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), 93 Package () { 94 Package () {"hog-gpio8", "G8PU"} 95 } 96 }) 97 98 Name (G8PU, Package () { 99 ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 100 Package () { 101 Package () {"gpio-hog", 1}, 102 Package () {"gpios", Package () {8, 0}}, 103 Package () {"output-high", 1}, 104 Package () {"line-name", "gpio8-pullup"}, 105 } 106 }) 107 108- gpio-line-names 109 110Example:: 111 112 Package () { 113 "gpio-line-names", 114 Package () { 115 "SPI0_CS_N", "EXP2_INT", "MUX6_IO", "UART0_RXD", "MUX7_IO", 116 "LVL_C_A1", "MUX0_IO", "SPI1_MISO" 117 } 118 } 119 120See Documentation/devicetree/bindings/gpio/gpio.txt for more information 121about these properties. 122 123ACPI GPIO Mappings Provided by Drivers 124====================================== 125 126There are systems in which the ACPI tables do not contain _DSD but provide _CRS 127with GpioIo()/GpioInt() resources and device drivers still need to work with 128them. 129 130In those cases ACPI device identification objects, _HID, _CID, _CLS, _SUB, _HRV, 131available to the driver can be used to identify the device and that is supposed 132to be sufficient to determine the meaning and purpose of all of the GPIO lines 133listed by the GpioIo()/GpioInt() resources returned by _CRS. In other words, 134the driver is supposed to know what to use the GpioIo()/GpioInt() resources for 135once it has identified the device. Having done that, it can simply assign names 136to the GPIO lines it is going to use and provide the GPIO subsystem with a 137mapping between those names and the ACPI GPIO resources corresponding to them. 138 139To do that, the driver needs to define a mapping table as a NULL-terminated 140array of struct acpi_gpio_mapping objects that each contain a name, a pointer 141to an array of line data (struct acpi_gpio_params) objects and the size of that 142array. Each struct acpi_gpio_params object consists of three fields, 143crs_entry_index, line_index, active_low, representing the index of the target 144GpioIo()/GpioInt() resource in _CRS starting from zero, the index of the target 145line in that resource starting from zero, and the active-low flag for that line, 146respectively, in analogy with the _DSD GPIO property format specified above. 147 148For the example Bluetooth device discussed previously the data structures in 149question would look like this:: 150 151 static const struct acpi_gpio_params reset_gpio = { 1, 1, false }; 152 static const struct acpi_gpio_params shutdown_gpio = { 0, 0, false }; 153 154 static const struct acpi_gpio_mapping bluetooth_acpi_gpios[] = { 155 { "reset-gpios", &reset_gpio, 1 }, 156 { "shutdown-gpios", &shutdown_gpio, 1 }, 157 { }, 158 }; 159 160Next, the mapping table needs to be passed as the second argument to 161acpi_dev_add_driver_gpios() that will register it with the ACPI device object 162pointed to by its first argument. That should be done in the driver's .probe() 163routine. On removal, the driver should unregister its GPIO mapping table by 164calling acpi_dev_remove_driver_gpios() on the ACPI device object where that 165table was previously registered. 166 167Using the _CRS fallback 168======================= 169 170If a device does not have _DSD or the driver does not create ACPI GPIO 171mapping, the Linux GPIO framework refuses to return any GPIOs. This is 172because the driver does not know what it actually gets. For example if we 173have a device like below:: 174 175 Device (BTH) 176 { 177 Name (_HID, ...) 178 179 Name (_CRS, ResourceTemplate () { 180 GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone, 181 "\\_SB.GPO0", 0, ResourceConsumer) {15} 182 GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone, 183 "\\_SB.GPO0", 0, ResourceConsumer) {27} 184 }) 185 } 186 187The driver might expect to get the right GPIO when it does:: 188 189 desc = gpiod_get(dev, "reset", GPIOD_OUT_LOW); 190 191but since there is no way to know the mapping between "reset" and 192the GpioIo() in _CRS desc will hold ERR_PTR(-ENOENT). 193 194The driver author can solve this by passing the mapping explictly 195(the recommended way and documented in the above chapter). 196 197The ACPI GPIO mapping tables should not contaminate drivers that are not 198knowing about which exact device they are servicing on. It implies that 199the ACPI GPIO mapping tables are hardly linked to ACPI ID and certain 200objects, as listed in the above chapter, of the device in question. 201 202Getting GPIO descriptor 203======================= 204 205There are two main approaches to get GPIO resource from ACPI:: 206 207 desc = gpiod_get(dev, connection_id, flags); 208 desc = gpiod_get_index(dev, connection_id, index, flags); 209 210We may consider two different cases here, i.e. when connection ID is 211provided and otherwise. 212 213Case 1:: 214 215 desc = gpiod_get(dev, "non-null-connection-id", flags); 216 desc = gpiod_get_index(dev, "non-null-connection-id", index, flags); 217 218Case 2:: 219 220 desc = gpiod_get(dev, NULL, flags); 221 desc = gpiod_get_index(dev, NULL, index, flags); 222 223Case 1 assumes that corresponding ACPI device description must have 224defined device properties and will prevent to getting any GPIO resources 225otherwise. 226 227Case 2 explicitly tells GPIO core to look for resources in _CRS. 228 229Be aware that gpiod_get_index() in cases 1 and 2, assuming that there 230are two versions of ACPI device description provided and no mapping is 231present in the driver, will return different resources. That's why a 232certain driver has to handle them carefully as explained in previous 233chapter. 234