]>
Commit | Line | Data |
---|---|---|
0d9a693c MW |
1 | _DSD Device Properties Related to GPIO |
2 | -------------------------------------- | |
3 | ||
a00212e2 RW |
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 | |
0d9a693c MW |
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 | { | |
060d791f MW |
31 | Package () {"reset-gpios", Package() {^BTH, 1, 1, 0 }}, |
32 | Package () {"shutdown-gpios", Package() {^BTH, 0, 0, 0 }}, | |
0d9a693c MW |
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 | ||
060d791f | 51 | In our Bluetooth example the "reset-gpios" refers to the second GpioIo() |
0d9a693c | 52 | resource, second pin in that resource with the GPIO number of 31. |
e36d453e | 53 | |
6f7194a1 MW |
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 | ||
c80f1ba7 MW |
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 | ||
4035cc15 MW |
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 | ||
c80f1ba7 MW |
113 | See Documentation/devicetree/bindings/gpio/gpio.txt for more information |
114 | about these properties. | |
115 | ||
e36d453e RW |
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[] = { | |
060d791f MW |
148 | { "reset-gpios", &reset_gpio, 1 }, |
149 | { "shutdown-gpios", &shutdown_gpio, 1 }, | |
e36d453e RW |
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. | |
ed7fcf1e AS |
159 | |
160 | Using the _CRS fallback | |
161 | ----------------------- | |
162 | ||
163 | If a device does not have _DSD or the driver does not create ACPI GPIO | |
164 | mapping, the Linux GPIO framework refuses to return any GPIOs. This is | |
165 | because the driver does not know what it actually gets. For example if we | |
166 | have a device like below: | |
167 | ||
168 | Device (BTH) | |
169 | { | |
170 | Name (_HID, ...) | |
171 | ||
172 | Name (_CRS, ResourceTemplate () { | |
173 | GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone, | |
174 | "\\_SB.GPO0", 0, ResourceConsumer) {15} | |
175 | GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone, | |
176 | "\\_SB.GPO0", 0, ResourceConsumer) {27} | |
177 | }) | |
178 | } | |
179 | ||
180 | The driver might expect to get the right GPIO when it does: | |
181 | ||
182 | desc = gpiod_get(dev, "reset", GPIOD_OUT_LOW); | |
183 | ||
184 | but since there is no way to know the mapping between "reset" and | |
185 | the GpioIo() in _CRS desc will hold ERR_PTR(-ENOENT). | |
186 | ||
187 | The driver author can solve this by passing the mapping explictly | |
188 | (the recommended way and documented in the above chapter). | |
189 | ||
190 | The ACPI GPIO mapping tables should not contaminate drivers that are not | |
191 | knowing about which exact device they are servicing on. It implies that | |
192 | the ACPI GPIO mapping tables are hardly linked to ACPI ID and certain | |
193 | objects, as listed in the above chapter, of the device in question. | |
194 | ||
195 | Getting GPIO descriptor | |
196 | ----------------------- | |
197 | ||
198 | There are two main approaches to get GPIO resource from ACPI: | |
199 | desc = gpiod_get(dev, connection_id, flags); | |
200 | desc = gpiod_get_index(dev, connection_id, index, flags); | |
201 | ||
202 | We may consider two different cases here, i.e. when connection ID is | |
203 | provided and otherwise. | |
204 | ||
205 | Case 1: | |
206 | desc = gpiod_get(dev, "non-null-connection-id", flags); | |
207 | desc = gpiod_get_index(dev, "non-null-connection-id", index, flags); | |
208 | ||
209 | Case 2: | |
210 | desc = gpiod_get(dev, NULL, flags); | |
211 | desc = gpiod_get_index(dev, NULL, index, flags); | |
212 | ||
213 | Case 1 assumes that corresponding ACPI device description must have | |
214 | defined device properties and will prevent to getting any GPIO resources | |
215 | otherwise. | |
216 | ||
217 | Case 2 explicitly tells GPIO core to look for resources in _CRS. | |
218 | ||
219 | Be aware that gpiod_get_index() in cases 1 and 2, assuming that there | |
220 | are two versions of ACPI device description provided and no mapping is | |
221 | present in the driver, will return different resources. That's why a | |
222 | certain driver has to handle them carefully as explained in previous | |
223 | chapter. |