1 /* 2 * Copyright (c) 2021 Nordic Semiconductor ASA 3 * SPDX-License-Identifier: Apache-2.0 4 */ 5 6 #ifndef ZEPHYR_INCLUDE_DEVICETREE_PINCTRL_H_ 7 #define ZEPHYR_INCLUDE_DEVICETREE_PINCTRL_H_ 8 9 /** 10 * @file 11 * @brief Devicetree pin control helpers 12 */ 13 14 /** 15 * @defgroup devicetree-pinctrl Pin control 16 * @ingroup devicetree 17 * @{ 18 */ 19 20 /** 21 * @brief Get a node identifier for a phandle in a pinctrl property by index 22 * 23 * Example devicetree fragment: 24 * 25 * n: node { 26 * pinctrl-0 = <&foo &bar>; 27 * pinctrl-1 = <&baz &blub>; 28 * } 29 * 30 * Example usage: 31 * 32 * DT_PINCTRL_BY_IDX(DT_NODELABEL(n), 0, 1) // DT_NODELABEL(bar) 33 * DT_PINCTRL_BY_IDX(DT_NODELABEL(n), 1, 0) // DT_NODELABEL(baz) 34 * 35 * @param node_id node with a pinctrl-'pc_idx' property 36 * @param pc_idx index of the pinctrl property itself 37 * @param idx index into the value of the pinctrl property 38 * @return node identifier for the phandle at index 'idx' in 'pinctrl-'pc_idx'' 39 */ 40 #define DT_PINCTRL_BY_IDX(node_id, pc_idx, idx) \ 41 DT_CAT6(node_id, _P_pinctrl_, pc_idx, _IDX_, idx, _PH) 42 43 /** 44 * @brief Get a node identifier from a pinctrl-0 property 45 * 46 * This is equivalent to: 47 * 48 * DT_PINCTRL_BY_IDX(node_id, 0, idx) 49 * 50 * It is provided for convenience since pinctrl-0 is commonly used. 51 * 52 * @param node_id node with a pinctrl-0 property 53 * @param idx index into the pinctrl-0 property 54 * @return node identifier for the phandle at index idx in the pinctrl-0 55 * property of that node 56 */ 57 #define DT_PINCTRL_0(node_id, idx) DT_PINCTRL_BY_IDX(node_id, 0, idx) 58 59 /** 60 * @brief Get a node identifier for a phandle inside a pinctrl node by name 61 * 62 * Example devicetree fragment: 63 * 64 * n: node { 65 * pinctrl-0 = <&foo &bar>; 66 * pinctrl-1 = <&baz &blub>; 67 * pinctrl-names = "default", "sleep"; 68 * }; 69 * 70 * Example usage: 71 * 72 * DT_PINCTRL_BY_NAME(DT_NODELABEL(n), default, 1) // DT_NODELABEL(bar) 73 * DT_PINCTRL_BY_NAME(DT_NODELABEL(n), sleep, 0) // DT_NODELABEL(baz) 74 * 75 * @param node_id node with a named pinctrl property 76 * @param name lowercase-and-underscores pinctrl property name 77 * @param idx index into the value of the named pinctrl property 78 * @return node identifier for the phandle at that index in the pinctrl 79 * property 80 */ 81 #define DT_PINCTRL_BY_NAME(node_id, name, idx) \ 82 DT_CAT6(node_id, _PINCTRL_NAME_, name, _IDX_, idx, _PH) 83 84 /** 85 * @brief Convert a pinctrl name to its corresponding index 86 * 87 * Example devicetree fragment: 88 * 89 * n: node { 90 * pinctrl-0 = <&foo &bar>; 91 * pinctrl-1 = <&baz &blub>; 92 * pinctrl-names = "default", "sleep"; 93 * }; 94 * 95 * Example usage: 96 * 97 * DT_PINCTRL_NAME_TO_IDX(DT_NODELABEL(n), default) // 0 98 * DT_PINCTRL_NAME_TO_IDX(DT_NODELABEL(n), sleep) // 1 99 * 100 * @param node_id node identifier with a named pinctrl property 101 * @param name lowercase-and-underscores name name of the pinctrl whose index to get 102 * @return integer literal for the index of the pinctrl property with that name 103 */ 104 #define DT_PINCTRL_NAME_TO_IDX(node_id, name) \ 105 DT_CAT4(node_id, _PINCTRL_NAME_, name, _IDX) 106 107 /** 108 * @brief Convert a pinctrl property index to its name as a token 109 * 110 * This allows you to get a pinctrl property's name, and "remove the 111 * quotes" from it. 112 * 113 * DT_PINCTRL_IDX_TO_NAME_TOKEN() can only be used if the node has a 114 * pinctrl-'pc_idx' property and a pinctrl-names property element for 115 * that index. It is an error to use it in other circumstances. 116 * 117 * Example devicetree fragment: 118 * 119 * n: node { 120 * pinctrl-0 = <...>; 121 * pinctrl-1 = <...>; 122 * pinctrl-names = "default", "f.o.o2"; 123 * }; 124 * 125 * Example usage: 126 * 127 * DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_NODELABEL(n), 0) // default 128 * DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_NODELABEL(n), 1) // f_o_o2 129 * 130 * The same caveats and restrictions that apply to DT_STRING_TOKEN()'s 131 * return value also apply here. 132 * 133 * @param node_id node identifier 134 * @param pc_idx index of a pinctrl property in that node 135 * @return name of the pinctrl property, as a token, without any quotes 136 * and with non-alphanumeric characters converted to underscores 137 */ 138 #define DT_PINCTRL_IDX_TO_NAME_TOKEN(node_id, pc_idx) \ 139 DT_CAT4(node_id, _PINCTRL_IDX_, pc_idx, _TOKEN) 140 141 /** 142 * @brief Like DT_PINCTRL_IDX_TO_NAME_TOKEN(), but with an uppercased result 143 * 144 * This does the a similar conversion as 145 * DT_PINCTRL_IDX_TO_NAME_TOKEN(node_id, pc_idx). The only difference 146 * is that alphabetical characters in the result are uppercased. 147 * 148 * Example devicetree fragment: 149 * 150 * n: node { 151 * pinctrl-0 = <...>; 152 * pinctrl-1 = <...>; 153 * pinctrl-names = "default", "f.o.o2"; 154 * }; 155 * 156 * Example usage: 157 * 158 * DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_NODELABEL(n), 0) // DEFAULT 159 * DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_NODELABEL(n), 1) // F_O_O2 160 * 161 * The same caveats and restrictions that apply to 162 * DT_STRING_UPPER_TOKEN()'s return value also apply here. 163 */ 164 #define DT_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(node_id, pc_idx) \ 165 DT_CAT4(node_id, _PINCTRL_IDX_, pc_idx, _UPPER_TOKEN) 166 167 /** 168 * @brief Get the number of phandles in a pinctrl property 169 * 170 * Example devicetree fragment: 171 * 172 * n1: node-1 { 173 * pinctrl-0 = <&foo &bar>; 174 * }; 175 * 176 * n2: node-2 { 177 * pinctrl-0 = <&baz>; 178 * }; 179 * 180 * Example usage: 181 * 182 * DT_NUM_PINCTRLS_BY_IDX(DT_NODELABEL(n1), 0) // 2 183 * DT_NUM_PINCTRLS_BY_IDX(DT_NODELABEL(n2), 0) // 1 184 * 185 * @param node_id node identifier with a pinctrl property 186 * @param pc_idx index of the pinctrl property itself 187 * @return number of phandles in the property with that index 188 */ 189 #define DT_NUM_PINCTRLS_BY_IDX(node_id, pc_idx) \ 190 DT_CAT4(node_id, _P_pinctrl_, pc_idx, _LEN) 191 192 /** 193 * @brief Like DT_NUM_PINCTRLS_BY_IDX(), but by name instead 194 * 195 * Example devicetree fragment: 196 * 197 * n: node { 198 * pinctrl-0 = <&foo &bar>; 199 * pinctrl-1 = <&baz> 200 * pinctrl-names = "default", "sleep"; 201 * }; 202 * 203 * Example usage: 204 * 205 * DT_NUM_PINCTRLS_BY_NAME(DT_NODELABEL(n), default) // 2 206 * DT_NUM_PINCTRLS_BY_NAME(DT_NODELABEL(n), sleep) // 1 207 * 208 * @param node_id node identifier with a pinctrl property 209 * @param name lowercase-and-underscores name name of the pinctrl property 210 * @return number of phandles in the property with that name 211 */ 212 #define DT_NUM_PINCTRLS_BY_NAME(node_id, name) \ 213 DT_NUM_PINCTRLS_BY_IDX(node_id, DT_PINCTRL_NAME_TO_IDX(node_id, name)) 214 215 /** 216 * @brief Get the number of pinctrl properties in a node 217 * 218 * This expands to 0 if there are no pinctrl-i properties. 219 * Otherwise, it expands to the number of such properties. 220 * 221 * Example devicetree fragment: 222 * 223 * n1: node-1 { 224 * pinctrl-0 = <...>; 225 * pinctrl-1 = <...>; 226 * }; 227 * 228 * n2: node-2 { 229 * }; 230 * 231 * Example usage: 232 * 233 * DT_NUM_PINCTRL_STATES(DT_NODELABEL(n1)) // 2 234 * DT_NUM_PINCTRL_STATES(DT_NODELABEL(n2)) // 0 235 * 236 * @param node_id node identifier; may or may not have any pinctrl properties 237 * @return number of pinctrl properties in the node 238 */ 239 #define DT_NUM_PINCTRL_STATES(node_id) DT_CAT(node_id, _PINCTRL_NUM) 240 241 /** 242 * @brief Test if a node has a pinctrl property with an index 243 * 244 * This expands to 1 if the pinctrl-'idx' property exists. 245 * Otherwise, it expands to 0. 246 * 247 * Example devicetree fragment: 248 * 249 * n1: node-1 { 250 * pinctrl-0 = <...>; 251 * pinctrl-1 = <...>; 252 * }; 253 * 254 * n2: node-2 { 255 * }; 256 * 257 * Example usage: 258 * 259 * DT_PINCTRL_HAS_IDX(DT_NODELABEL(n1), 0) // 1 260 * DT_PINCTRL_HAS_IDX(DT_NODELABEL(n1), 1) // 1 261 * DT_PINCTRL_HAS_IDX(DT_NODELABEL(n1), 2) // 0 262 * DT_PINCTRL_HAS_IDX(DT_NODELABEL(n2), 0) // 0 263 * 264 * @param node_id node identifier; may or may not have any pinctrl properties 265 * @param pc_idx index of a pinctrl property whose existence to check 266 * @return 1 if the property exists, 0 otherwise 267 */ 268 #define DT_PINCTRL_HAS_IDX(node_id, pc_idx) \ 269 IS_ENABLED(DT_CAT4(node_id, _PINCTRL_IDX_, pc_idx, _EXISTS)) 270 271 /** 272 * @brief Test if a node has a pinctrl property with a name 273 * 274 * This expands to 1 if the named pinctrl property exists. 275 * Otherwise, it expands to 0. 276 * 277 * Example devicetree fragment: 278 * 279 * n1: node-1 { 280 * pinctrl-0 = <...>; 281 * pinctrl-names = "default"; 282 * }; 283 * 284 * n2: node-2 { 285 * }; 286 * 287 * Example usage: 288 * 289 * DT_PINCTRL_HAS_NAME(DT_NODELABEL(n1), default) // 1 290 * DT_PINCTRL_HAS_NAME(DT_NODELABEL(n1), sleep) // 0 291 * DT_PINCTRL_HAS_NAME(DT_NODELABEL(n2), default) // 0 292 * 293 * @param node_id node identifier; may or may not have any pinctrl properties 294 * @param name lowercase-and-underscores pinctrl property name to check 295 * @return 1 if the property exists, 0 otherwise 296 */ 297 #define DT_PINCTRL_HAS_NAME(node_id, name) \ 298 IS_ENABLED(DT_CAT4(node_id, _PINCTRL_NAME_, name, _EXISTS)) 299 300 /** 301 * @brief Get a node identifier for a phandle in a pinctrl property by index 302 * for a DT_DRV_COMPAT instance 303 * 304 * This is equivalent to DT_PINCTRL_BY_IDX(DT_DRV_INST(inst), pc_idx, idx). 305 * 306 * @param inst instance number 307 * @param pc_idx index of the pinctrl property itself 308 * @param idx index into the value of the pinctrl property 309 * @return node identifier for the phandle at index 'idx' in 'pinctrl-'pc_idx'' 310 */ 311 #define DT_INST_PINCTRL_BY_IDX(inst, pc_idx, idx) \ 312 DT_PINCTRL_BY_IDX(DT_DRV_INST(inst), pc_idx, idx) 313 314 /** 315 * @brief Get a node identifier from a pinctrl-0 property for a 316 * DT_DRV_COMPAT instance 317 * 318 * This is equivalent to: 319 * 320 * DT_PINCTRL_BY_IDX(DT_DRV_INST(inst), 0, idx) 321 * 322 * It is provided for convenience since pinctrl-0 is commonly used. 323 * 324 * @param inst instance number 325 * @param idx index into the pinctrl-0 property 326 * @return node identifier for the phandle at index idx in the pinctrl-0 327 * property of that instance 328 */ 329 #define DT_INST_PINCTRL_0(inst, idx) \ 330 DT_PINCTRL_BY_IDX(DT_DRV_INST(inst), 0, idx) 331 332 /** 333 * @brief Get a node identifier for a phandle inside a pinctrl node 334 * for a DT_DRV_COMPAT instance 335 * 336 * This is equivalent to DT_PINCTRL_BY_NAME(DT_DRV_INST(inst), name, idx). 337 * 338 * @param inst instance number 339 * @param name lowercase-and-underscores pinctrl property name 340 * @param idx index into the value of the named pinctrl property 341 * @return node identifier for the phandle at that index in the pinctrl 342 * property 343 */ 344 #define DT_INST_PINCTRL_BY_NAME(inst, name, idx) \ 345 DT_PINCTRL_BY_NAME(DT_DRV_INST(inst), name, idx) 346 347 /** 348 * @brief Convert a pinctrl name to its corresponding index 349 * for a DT_DRV_COMPAT instance 350 * 351 * This is equivalent to DT_PINCTRL_NAME_TO_IDX(DT_DRV_INST(inst), 352 * name). 353 * 354 * @param inst instance number 355 * @param name lowercase-and-underscores name of the pinctrl whose index to get 356 * @return integer literal for the index of the pinctrl property with that name 357 */ 358 #define DT_INST_PINCTRL_NAME_TO_IDX(inst, name) \ 359 DT_PINCTRL_NAME_TO_IDX(DT_DRV_INST(inst), name) 360 361 /** 362 * @brief Convert a pinctrl index to its name as an uppercased token 363 * 364 * This is equivalent to 365 * DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_DRV_INST(inst), pc_idx). 366 * 367 * @param inst instance number 368 * @param pc_idx index of the pinctrl property itself 369 * @return name of the pin control property as a token 370 */ 371 #define DT_INST_PINCTRL_IDX_TO_NAME_TOKEN(inst, pc_idx) \ 372 DT_PINCTRL_IDX_TO_NAME_TOKEN(DT_DRV_INST(inst), pc_idx) 373 374 /** 375 * @brief Convert a pinctrl index to its name as an uppercased token 376 * 377 * This is equivalent to 378 * DT_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(DT_DRV_INST(inst), idx). 379 * 380 * @param inst instance number 381 * @param pc_idx index of the pinctrl property itself 382 * @return name of the pin control property as an uppercase token 383 */ 384 #define DT_INST_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(inst, pc_idx) \ 385 DT_PINCTRL_IDX_TO_NAME_UPPER_TOKEN(DT_DRV_INST(inst), pc_idx) 386 387 /** 388 * @brief Get the number of phandles in a pinctrl property 389 * for a DT_DRV_COMPAT instance 390 * 391 * This is equivalent to DT_NUM_PINCTRLS_BY_IDX(DT_DRV_INST(inst), 392 * pc_idx). 393 * 394 * @param inst instance number 395 * @param pc_idx index of the pinctrl property itself 396 * @return number of phandles in the property with that index 397 */ 398 #define DT_INST_NUM_PINCTRLS_BY_IDX(inst, pc_idx) \ 399 DT_NUM_PINCTRLS_BY_IDX(DT_DRV_INST(inst), pc_idx) 400 401 /** 402 * @brief Like DT_INST_NUM_PINCTRLS_BY_IDX(), but by name instead 403 * 404 * This is equivalent to DT_NUM_PINCTRLS_BY_NAME(DT_DRV_INST(inst), 405 * name). 406 * 407 * @param inst instance number 408 * @param name lowercase-and-underscores name of the pinctrl property 409 * @return number of phandles in the property with that name 410 */ 411 #define DT_INST_NUM_PINCTRLS_BY_NAME(inst, name) \ 412 DT_NUM_PINCTRLS_BY_NAME(DT_DRV_INST(inst), name) 413 414 /** 415 * @brief Get the number of pinctrl properties in a DT_DRV_COMPAT instance 416 * 417 * This is equivalent to DT_NUM_PINCTRL_STATES(DT_DRV_INST(inst)). 418 * 419 * @param inst instance number 420 * @return number of pinctrl properties in the instance 421 */ 422 #define DT_INST_NUM_PINCTRL_STATES(inst) \ 423 DT_NUM_PINCTRL_STATES(DT_DRV_INST(inst)) 424 425 /** 426 * @brief Test if a DT_DRV_COMPAT instance has a pinctrl property 427 * with an index 428 * 429 * This is equivalent to DT_PINCTRL_HAS_IDX(DT_DRV_INST(inst), pc_idx). 430 * 431 * @param inst instance number 432 * @param pc_idx index of a pinctrl property whose existence to check 433 * @return 1 if the property exists, 0 otherwise 434 */ 435 #define DT_INST_PINCTRL_HAS_IDX(inst, pc_idx) \ 436 DT_PINCTRL_HAS_IDX(DT_DRV_INST(inst), pc_idx) 437 438 /** 439 * @brief Test if a DT_DRV_COMPAT instance has a pinctrl property with a name 440 * 441 * This is equivalent to DT_PINCTRL_HAS_NAME(DT_DRV_INST(inst), name). 442 * 443 * @param inst instance number 444 * @param name lowercase-and-underscores pinctrl property name to check 445 * @return 1 if the property exists, 0 otherwise 446 */ 447 #define DT_INST_PINCTRL_HAS_NAME(inst, name) \ 448 DT_PINCTRL_HAS_NAME(DT_DRV_INST(inst), name) 449 450 451 /** 452 * @} 453 */ 454 455 #endif /* ZEPHYR_INCLUDE_DEVICETREE_PINCTRL_H_ */ 456