blob: 86f35177a2f62dd9217fbb703987a4e7b73882dd [file] [log] [blame]
Kumar Gala87915cd2018-11-15 11:51:50 -06001# Copyright (c) 2018-2019 Linaro
Carles Cufifa26ef02019-01-30 17:54:21 +01002# Copyright (c) 2019 Nordic Semiconductor ASA
Kumar Gala87915cd2018-11-15 11:51:50 -06003#
4# SPDX-License-Identifier: Apache-2.0
5
6import os
Martí Bolívar269f3502020-07-01 12:17:02 -07007import pickle
Kumar Gala57353972019-08-28 09:30:23 -05008import sys
Henrik Brix Andersenc6b30942022-05-18 17:35:23 +02009from pathlib import Path
Kumar Gala57353972019-08-28 09:30:23 -050010
Henrik Brix Andersenc6b30942022-05-18 17:35:23 +020011ZEPHYR_BASE = str(Path(__file__).resolve().parents[2])
Martí Bolívar53328472021-03-26 16:18:58 -070012sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts", "dts",
13 "python-devicetree", "src"))
Kumar Gala57353972019-08-28 09:30:23 -050014
Martí Bolívar53328472021-03-26 16:18:58 -070015from devicetree import edtlib
Kumar Gala87915cd2018-11-15 11:51:50 -060016
17# Types we support
18# 'string', 'int', 'hex', 'bool'
19
Carles Cufifa26ef02019-01-30 17:54:21 +010020doc_mode = os.environ.get('KCONFIG_DOC_MODE') == "1"
Sebastian Bøecd435432019-02-11 15:57:34 +010021
Ulf Magnussonba312fe2019-03-20 19:30:29 +010022if not doc_mode:
Martí Bolívar269f3502020-07-01 12:17:02 -070023 EDT_PICKLE = os.environ.get("EDT_PICKLE")
Kumar Gala9aefdaf2020-04-15 10:32:41 -050024
Martí Bolívar269f3502020-07-01 12:17:02 -070025 # The "if" handles a missing dts.
26 if EDT_PICKLE is not None and os.path.isfile(EDT_PICKLE):
27 with open(EDT_PICKLE, 'rb') as f:
28 edt = pickle.load(f)
Kumar Gala57353972019-08-28 09:30:23 -050029 else:
30 edt = None
31
Kumar Gala1baf2f32019-09-04 14:14:26 -050032
33def _warn(kconf, msg):
34 print("{}:{}: WARNING: {}".format(kconf.filename, kconf.linenr, msg))
35
36
Kumar Gala87915cd2018-11-15 11:51:50 -060037def _dt_units_to_scale(unit):
38 if not unit:
39 return 0
40 if unit in {'k', 'K'}:
41 return 10
42 if unit in {'m', 'M'}:
43 return 20
44 if unit in {'g', 'G'}:
45 return 30
Daniel DeGrasse6064da82022-05-25 17:38:59 -050046 if unit in {'kb', 'Kb'}:
47 return 13
48 if unit in {'mb', 'Mb'}:
49 return 23
50 if unit in {'gb', 'Gb'}:
51 return 33
Kumar Gala87915cd2018-11-15 11:51:50 -060052
Kumar Gala57353972019-08-28 09:30:23 -050053
54def dt_chosen_label(kconf, _, chosen):
55 """
56 This function takes a 'chosen' property and treats that property as a path
Ulf Magnusson73ac1462019-09-23 05:14:18 +020057 to an EDT node. If it finds an EDT node, it will look to see if that node
Martí Bolívarb3151bc2022-08-18 16:13:50 -070058 has a "label" property and return the value of that "label". If not, we
59 return the node's name in the devicetree.
Kumar Gala57353972019-08-28 09:30:23 -050060 """
61 if doc_mode or edt is None:
62 return ""
63
Ulf Magnusson73ac1462019-09-23 05:14:18 +020064 node = edt.chosen_node(chosen)
65 if not node:
Kumar Gala57353972019-08-28 09:30:23 -050066 return ""
67
Ulf Magnusson73ac1462019-09-23 05:14:18 +020068 if "label" not in node.props:
Kumar Gala57538262022-08-04 11:23:13 -050069 return node.name
Kumar Gala57353972019-08-28 09:30:23 -050070
Ulf Magnusson73ac1462019-09-23 05:14:18 +020071 return node.props["label"].val
Kumar Gala57353972019-08-28 09:30:23 -050072
73
Kumar Gala07e5d892019-11-04 10:20:59 -060074def dt_chosen_enabled(kconf, _, chosen):
75 """
76 This function returns "y" if /chosen contains a property named 'chosen'
77 that points to an enabled node, and "n" otherwise
78 """
79 if doc_mode or edt is None:
80 return "n"
81
82 node = edt.chosen_node(chosen)
Martí Bolívar81650082020-10-05 20:02:13 -070083 return "y" if node and node.status == "okay" else "n"
Kumar Gala07e5d892019-11-04 10:20:59 -060084
Kumar Gala0353d222020-02-13 23:43:42 -060085
Martí Bolívar7ff3ebc2020-04-23 12:28:06 -070086def dt_chosen_path(kconf, _, chosen):
87 """
88 This function takes a /chosen node property and returns the path
89 to the node in the property value, or the empty string.
90 """
91 if doc_mode or edt is None:
92 return "n"
93
94 node = edt.chosen_node(chosen)
95
96 return node.path if node else ""
97
Daniel DeGrassefbefc502022-04-11 11:53:03 -050098def dt_chosen_has_compat(kconf, _, chosen, compat):
99 """
100 This function takes a /chosen node property and returns 'y' if the
101 chosen node has the provided compatible string 'compat'
102 """
103 if doc_mode or edt is None:
104 return "n"
105
106 node = edt.chosen_node(chosen)
107
108 if node is None:
109 return "n"
110
111 if compat in node.compats:
112 return "y"
113
114 return "n"
Martí Bolívar7ff3ebc2020-04-23 12:28:06 -0700115
Martí Bolívar24677f92020-04-28 16:52:35 -0700116def dt_node_enabled(kconf, name, node):
117 """
118 This function is used to test if a node is enabled (has status
119 'okay') or not.
120
121 The 'node' argument is a string which is either a path or an
122 alias, or both, depending on 'name'.
123
124 If 'name' is 'dt_path_enabled', 'node' is an alias or a path. If
125 'name' is 'dt_alias_enabled, 'node' is an alias.
126 """
127
128 if doc_mode or edt is None:
129 return "n"
130
131 if name == "dt_alias_enabled":
132 if node.startswith("/"):
133 # EDT.get_node() works with either aliases or paths. If we
134 # are specifically being asked about an alias, reject paths.
135 return "n"
136 else:
137 # Make sure this is being called appropriately.
138 assert name == "dt_path_enabled"
139
140 try:
141 node = edt.get_node(node)
142 except edtlib.EDTError:
143 return "n"
144
Martí Bolívar81650082020-10-05 20:02:13 -0700145 return "y" if node and node.status == "okay" else "n"
Martí Bolívar24677f92020-04-28 16:52:35 -0700146
147
Kumar Gala0353d222020-02-13 23:43:42 -0600148def dt_nodelabel_enabled(kconf, _, label):
149 """
Martí Bolívar24677f92020-04-28 16:52:35 -0700150 This function is like dt_node_enabled(), but the 'label' argument
151 should be a node label, like "foo" is here:
152
153 foo: some-node { ... };
Kumar Gala0353d222020-02-13 23:43:42 -0600154 """
155 if doc_mode or edt is None:
156 return "n"
157
Martí Bolívar0682c462020-04-22 17:59:23 -0700158 node = edt.label2node.get(label)
Kumar Gala0353d222020-02-13 23:43:42 -0600159
Martí Bolívar81650082020-10-05 20:02:13 -0700160 return "y" if node and node.status == "okay" else "n"
Kumar Gala0353d222020-02-13 23:43:42 -0600161
162
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200163def _node_reg_addr(node, index, unit):
164 if not node:
Kumar Gala22e74492019-10-23 15:15:59 -0500165 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500166
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200167 if not node.regs:
Kumar Gala22e74492019-10-23 15:15:59 -0500168 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500169
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200170 if int(index) >= len(node.regs):
Kumar Gala22e74492019-10-23 15:15:59 -0500171 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500172
Kumar Gala8af311a2020-03-13 12:43:56 -0500173 if node.regs[int(index)].addr is None:
174 return 0
175
Kumar Gala22e74492019-10-23 15:15:59 -0500176 return node.regs[int(index)].addr >> _dt_units_to_scale(unit)
Kumar Gala57353972019-08-28 09:30:23 -0500177
178
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200179def _node_reg_size(node, index, unit):
180 if not node:
Kumar Gala22e74492019-10-23 15:15:59 -0500181 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500182
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200183 if not node.regs:
Kumar Gala22e74492019-10-23 15:15:59 -0500184 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500185
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200186 if int(index) >= len(node.regs):
Kumar Gala22e74492019-10-23 15:15:59 -0500187 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500188
Kumar Gala8af311a2020-03-13 12:43:56 -0500189 if node.regs[int(index)].size is None:
190 return 0
191
Kumar Gala22e74492019-10-23 15:15:59 -0500192 return node.regs[int(index)].size >> _dt_units_to_scale(unit)
Kumar Gala57353972019-08-28 09:30:23 -0500193
194
David Leach1e5a8302021-11-08 23:24:22 -0600195def _node_int_prop(node, prop, unit=None):
196 """
197 This function takes a 'node' and will look to see if that 'node' has a
198 property called 'prop' and if that 'prop' is an integer type will return
199 the value of the property 'prop' as either a string int or string hex
200 value, if not we return 0.
201
202 The function will divide the value based on 'unit':
203 None No division
204 'k' or 'K' divide by 1024 (1 << 10)
205 'm' or 'M' divide by 1,048,576 (1 << 20)
206 'g' or 'G' divide by 1,073,741,824 (1 << 30)
Daniel DeGrasse6064da82022-05-25 17:38:59 -0500207 'kb' or 'Kb' divide by 8192 (1 << 13)
208 'mb' or 'Mb' divide by 8,388,608 (1 << 23)
209 'gb' or 'Gb' divide by 8,589,934,592 (1 << 33)
David Leach1e5a8302021-11-08 23:24:22 -0600210 """
Kumar Gala338b43192020-04-03 05:02:35 -0500211 if not node:
212 return 0
213
214 if prop not in node.props:
215 return 0
216
217 if node.props[prop].type != "int":
218 return 0
219
David Leach1e5a8302021-11-08 23:24:22 -0600220 return node.props[prop].val >> _dt_units_to_scale(unit)
Kumar Gala338b43192020-04-03 05:02:35 -0500221
222
Eivind Jølsgard3865e082022-03-18 10:50:00 +0100223def _node_array_prop(node, prop, index=0, unit=None):
224 """
225 This function takes a 'node' and will look to see if that 'node' has a
226 property called 'prop' and if that 'prop' is an array type will return
227 the value of the property 'prop' at the given 'index' as either a string int
228 or string hex value. If the property 'prop' is not found or the given 'index'
229 is out of range it will return 0.
230
231 The function will divide the value based on 'unit':
232 None No division
233 'k' or 'K' divide by 1024 (1 << 10)
234 'm' or 'M' divide by 1,048,576 (1 << 20)
235 'g' or 'G' divide by 1,073,741,824 (1 << 30)
236 """
237 if not node:
238 return 0
239
240 if prop not in node.props:
241 return 0
242 if node.props[prop].type != "array":
243 return 0
244 if int(index) >= len(node.props[prop].val):
245 return 0
246 return node.props[prop].val[int(index)] >> _dt_units_to_scale(unit)
247
248
Kumar Gala22e74492019-10-23 15:15:59 -0500249def _dt_chosen_reg_addr(kconf, chosen, index=0, unit=None):
Kumar Gala57353972019-08-28 09:30:23 -0500250 """
251 This function takes a 'chosen' property and treats that property as a path
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200252 to an EDT node. If it finds an EDT node, it will look to see if that
Nazar Kazakovf483b1b2022-03-16 21:07:43 +0000253 node has a register at the given 'index' and return the address value of
Kumar Gala57353972019-08-28 09:30:23 -0500254 that reg, if not we return 0.
255
256 The function will divide the value based on 'unit':
257 None No division
258 'k' or 'K' divide by 1024 (1 << 10)
259 'm' or 'M' divide by 1,048,576 (1 << 20)
260 'g' or 'G' divide by 1,073,741,824 (1 << 30)
Daniel DeGrasse6064da82022-05-25 17:38:59 -0500261 'kb' or 'Kb' divide by 8192 (1 << 13)
262 'mb' or 'Mb' divide by 8,388,608 (1 << 23)
263 'gb' or 'Gb' divide by 8,589,934,592 (1 << 33)
Kumar Gala57353972019-08-28 09:30:23 -0500264 """
265 if doc_mode or edt is None:
Kumar Gala22e74492019-10-23 15:15:59 -0500266 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500267
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200268 node = edt.chosen_node(chosen)
Kumar Gala57353972019-08-28 09:30:23 -0500269
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200270 return _node_reg_addr(node, index, unit)
Kumar Gala57353972019-08-28 09:30:23 -0500271
272
Kumar Gala22e74492019-10-23 15:15:59 -0500273def _dt_chosen_reg_size(kconf, chosen, index=0, unit=None):
Kumar Gala57353972019-08-28 09:30:23 -0500274 """
275 This function takes a 'chosen' property and treats that property as a path
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200276 to an EDT node. If it finds an EDT node, it will look to see if that node
277 has a register at the given 'index' and return the size value of that reg,
278 if not we return 0.
Kumar Gala57353972019-08-28 09:30:23 -0500279
280 The function will divide the value based on 'unit':
281 None No division
282 'k' or 'K' divide by 1024 (1 << 10)
283 'm' or 'M' divide by 1,048,576 (1 << 20)
284 'g' or 'G' divide by 1,073,741,824 (1 << 30)
Daniel DeGrasse6064da82022-05-25 17:38:59 -0500285 'kb' or 'Kb' divide by 8192 (1 << 13)
286 'mb' or 'Mb' divide by 8,388,608 (1 << 23)
287 'gb' or 'Gb' divide by 8,589,934,592 (1 << 33)
Kumar Gala57353972019-08-28 09:30:23 -0500288 """
289 if doc_mode or edt is None:
Kumar Gala22e74492019-10-23 15:15:59 -0500290 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500291
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200292 node = edt.chosen_node(chosen)
Kumar Gala57353972019-08-28 09:30:23 -0500293
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200294 return _node_reg_size(node, index, unit)
Kumar Gala57353972019-08-28 09:30:23 -0500295
296
Kumar Gala22e74492019-10-23 15:15:59 -0500297def dt_chosen_reg(kconf, name, chosen, index=0, unit=None):
298 """
299 This function just routes to the proper function and converts
300 the result to either a string int or string hex value.
301 """
302 if name == "dt_chosen_reg_size_int":
303 return str(_dt_chosen_reg_size(kconf, chosen, index, unit))
304 if name == "dt_chosen_reg_size_hex":
305 return hex(_dt_chosen_reg_size(kconf, chosen, index, unit))
306 if name == "dt_chosen_reg_addr_int":
307 return str(_dt_chosen_reg_addr(kconf, chosen, index, unit))
308 if name == "dt_chosen_reg_addr_hex":
309 return hex(_dt_chosen_reg_addr(kconf, chosen, index, unit))
310
311
312def _dt_node_reg_addr(kconf, path, index=0, unit=None):
Kumar Gala57353972019-08-28 09:30:23 -0500313 """
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200314 This function takes a 'path' and looks for an EDT node at that path. If it
315 finds an EDT node, it will look to see if that node has a register at the
316 given 'index' and return the address value of that reg, if not we return 0.
Kumar Gala57353972019-08-28 09:30:23 -0500317
318 The function will divide the value based on 'unit':
319 None No division
320 'k' or 'K' divide by 1024 (1 << 10)
321 'm' or 'M' divide by 1,048,576 (1 << 20)
322 'g' or 'G' divide by 1,073,741,824 (1 << 30)
Daniel DeGrasse6064da82022-05-25 17:38:59 -0500323 'kb' or 'Kb' divide by 8192 (1 << 13)
324 'mb' or 'Mb' divide by 8,388,608 (1 << 23)
325 'gb' or 'Gb' divide by 8,589,934,592 (1 << 33)
Kumar Gala57353972019-08-28 09:30:23 -0500326 """
327 if doc_mode or edt is None:
Kumar Gala22e74492019-10-23 15:15:59 -0500328 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500329
330 try:
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200331 node = edt.get_node(path)
Kumar Gala57353972019-08-28 09:30:23 -0500332 except edtlib.EDTError:
Kumar Gala22e74492019-10-23 15:15:59 -0500333 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500334
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200335 return _node_reg_addr(node, index, unit)
Kumar Gala57353972019-08-28 09:30:23 -0500336
337
Kumar Gala22e74492019-10-23 15:15:59 -0500338def _dt_node_reg_size(kconf, path, index=0, unit=None):
Kumar Gala57353972019-08-28 09:30:23 -0500339 """
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200340 This function takes a 'path' and looks for an EDT node at that path. If it
341 finds an EDT node, it will look to see if that node has a register at the
342 given 'index' and return the size value of that reg, if not we return 0.
Kumar Gala57353972019-08-28 09:30:23 -0500343
344 The function will divide the value based on 'unit':
345 None No division
346 'k' or 'K' divide by 1024 (1 << 10)
347 'm' or 'M' divide by 1,048,576 (1 << 20)
348 'g' or 'G' divide by 1,073,741,824 (1 << 30)
Daniel DeGrasse6064da82022-05-25 17:38:59 -0500349 'kb' or 'Kb' divide by 8192 (1 << 13)
350 'mb' or 'Mb' divide by 8,388,608 (1 << 23)
351 'gb' or 'Gb' divide by 8,589,934,592 (1 << 33)
Kumar Gala57353972019-08-28 09:30:23 -0500352 """
353 if doc_mode or edt is None:
Kumar Gala22e74492019-10-23 15:15:59 -0500354 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500355
356 try:
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200357 node = edt.get_node(path)
Kumar Gala57353972019-08-28 09:30:23 -0500358 except edtlib.EDTError:
Kumar Gala22e74492019-10-23 15:15:59 -0500359 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500360
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200361 return _node_reg_size(node, index, unit)
Kumar Gala57353972019-08-28 09:30:23 -0500362
363
Kumar Gala22e74492019-10-23 15:15:59 -0500364def dt_node_reg(kconf, name, path, index=0, unit=None):
365 """
366 This function just routes to the proper function and converts
367 the result to either a string int or string hex value.
368 """
369 if name == "dt_node_reg_size_int":
370 return str(_dt_node_reg_size(kconf, path, index, unit))
371 if name == "dt_node_reg_size_hex":
372 return hex(_dt_node_reg_size(kconf, path, index, unit))
373 if name == "dt_node_reg_addr_int":
374 return str(_dt_node_reg_addr(kconf, path, index, unit))
375 if name == "dt_node_reg_addr_hex":
376 return hex(_dt_node_reg_addr(kconf, path, index, unit))
377
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100378def _dt_node_bool_prop_generic(node_search_function, search_arg, prop):
Kumar Gala57353972019-08-28 09:30:23 -0500379 """
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100380 This function takes the 'node_search_function' and uses it to search for
381 a node with 'search_arg' and if node exists, checks if 'prop' exists
382 inside the node and is a boolean, if it is true, returns "y".
383 Otherwise, it returns "n".
Kumar Gala57353972019-08-28 09:30:23 -0500384 """
Kumar Gala57353972019-08-28 09:30:23 -0500385 try:
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100386 node = node_search_function(search_arg)
Kumar Gala57353972019-08-28 09:30:23 -0500387 except edtlib.EDTError:
388 return "n"
389
Andrzej Głąbek23994332022-03-23 14:45:11 +0100390 if node is None:
391 return "n"
392
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200393 if prop not in node.props:
Kumar Gala57353972019-08-28 09:30:23 -0500394 return "n"
395
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200396 if node.props[prop].type != "boolean":
Kumar Gala57353972019-08-28 09:30:23 -0500397 return "n"
398
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200399 if node.props[prop].val:
Kumar Gala57353972019-08-28 09:30:23 -0500400 return "y"
401
402 return "n"
403
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100404def dt_node_bool_prop(kconf, _, path, prop):
Erwan Gourioub7110282021-01-07 12:06:31 +0100405 """
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100406 This function takes a 'path' and looks for an EDT node at that path. If it
407 finds an EDT node, it will look to see if that node has a boolean property
Erwan Gourioub7110282021-01-07 12:06:31 +0100408 by the name of 'prop'. If the 'prop' exists it will return "y" otherwise
409 we return "n".
410 """
Erwan Gourioub7110282021-01-07 12:06:31 +0100411 if doc_mode or edt is None:
412 return "n"
413
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100414 return _dt_node_bool_prop_generic(edt.get_node, path, prop)
415
416def dt_nodelabel_bool_prop(kconf, _, label, prop):
417 """
418 This function takes a 'label' and looks for an EDT node with that label.
419 If it finds an EDT node, it will look to see if that node has a boolean
420 property by the name of 'prop'. If the 'prop' exists it will return "y"
421 otherwise we return "n".
422 """
423 if doc_mode or edt is None:
424 return "n"
425
426 return _dt_node_bool_prop_generic(edt.label2node.get, label, prop)
427
Stephen Stautsd4b8db72022-12-27 11:40:17 +0100428def dt_chosen_bool_prop(kconf, _, chosen, prop):
429 """
430 This function takes a /chosen node property named 'chosen', and
431 looks for the chosen node. If that node exists and has a boolean
432 property 'prop', it returns "y". Otherwise, it returns "n".
433 """
434 if doc_mode or edt is None:
435 return "n"
436
437 return _dt_node_bool_prop_generic(edt.chosen_node, chosen, prop)
438
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100439def _dt_node_has_prop_generic(node_search_function, search_arg, prop):
440 """
441 This function takes the 'node_search_function' and uses it to search for
442 a node with 'search_arg' and if node exists, then checks if 'prop'
443 exists inside the node and returns "y". Otherwise, it returns "n".
444 """
Erwan Gourioub7110282021-01-07 12:06:31 +0100445 try:
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100446 node = node_search_function(search_arg)
Erwan Gourioub7110282021-01-07 12:06:31 +0100447 except edtlib.EDTError:
448 return "n"
449
450 if node is None:
451 return "n"
452
453 if prop in node.props:
454 return "y"
455
456 return "n"
Kumar Gala57353972019-08-28 09:30:23 -0500457
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100458def dt_node_has_prop(kconf, _, path, prop):
459 """
460 This function takes a 'path' and looks for an EDT node at that path. If it
461 finds an EDT node, it will look to see if that node has a property
462 by the name of 'prop'. If the 'prop' exists it will return "y" otherwise
463 it returns "n".
464 """
465 if doc_mode or edt is None:
466 return "n"
467
468 return _dt_node_has_prop_generic(edt.get_node, path, prop)
469
470def dt_nodelabel_has_prop(kconf, _, label, prop):
471 """
472 This function takes a 'label' and looks for an EDT node with that label.
473 If it finds an EDT node, it will look to see if that node has a property
474 by the name of 'prop'. If the 'prop' exists it will return "y" otherwise
475 it returns "n".
476 """
477 if doc_mode or edt is None:
478 return "n"
479
480 return _dt_node_has_prop_generic(edt.label2node.get, label, prop)
481
David Leach1e5a8302021-11-08 23:24:22 -0600482def dt_node_int_prop(kconf, name, path, prop, unit=None):
Kumar Gala338b43192020-04-03 05:02:35 -0500483 """
484 This function takes a 'path' and property name ('prop') looks for an EDT
485 node at that path. If it finds an EDT node, it will look to see if that
486 node has a property called 'prop' and if that 'prop' is an integer type
487 will return the value of the property 'prop' as either a string int or
488 string hex value, if not we return 0.
Kumar Gala338b43192020-04-03 05:02:35 -0500489
David Leach1e5a8302021-11-08 23:24:22 -0600490 The function will divide the value based on 'unit':
491 None No division
492 'k' or 'K' divide by 1024 (1 << 10)
493 'm' or 'M' divide by 1,048,576 (1 << 20)
494 'g' or 'G' divide by 1,073,741,824 (1 << 30)
Daniel DeGrasse6064da82022-05-25 17:38:59 -0500495 'kb' or 'Kb' divide by 8192 (1 << 13)
496 'mb' or 'Mb' divide by 8,388,608 (1 << 23)
497 'gb' or 'Gb' divide by 8,589,934,592 (1 << 33)
David Leach1e5a8302021-11-08 23:24:22 -0600498 """
Kumar Gala338b43192020-04-03 05:02:35 -0500499 if doc_mode or edt is None:
500 return "0"
501
502 try:
503 node = edt.get_node(path)
504 except edtlib.EDTError:
505 return "0"
506
507 if name == "dt_node_int_prop_int":
David Leach1e5a8302021-11-08 23:24:22 -0600508 return str(_node_int_prop(node, prop, unit))
Kumar Gala338b43192020-04-03 05:02:35 -0500509 if name == "dt_node_int_prop_hex":
David Leach1e5a8302021-11-08 23:24:22 -0600510 return hex(_node_int_prop(node, prop, unit))
Kumar Gala338b43192020-04-03 05:02:35 -0500511
Eivind Jølsgard3865e082022-03-18 10:50:00 +0100512
513def dt_node_array_prop(kconf, name, path, prop, index, unit=None):
514 """
515 This function takes a 'path', property name ('prop') and index ('index')
516 and looks for an EDT node at that path. If it finds an EDT node, it will
517 look to see if that node has a property called 'prop' and if that 'prop'
518 is an array type will return the value of the property 'prop' at the given
519 'index' as either a string int or string hex value. If not found we return 0.
520
521 The function will divide the value based on 'unit':
522 None No division
523 'k' or 'K' divide by 1024 (1 << 10)
524 'm' or 'M' divide by 1,048,576 (1 << 20)
525 'g' or 'G' divide by 1,073,741,824 (1 << 30)
526 """
527 if doc_mode or edt is None:
528 return "0"
529
530 try:
531 node = edt.get_node(path)
532 except edtlib.EDTError:
533 return "0"
534 if name == "dt_node_array_prop_int":
535 return str(_node_array_prop(node, prop, index, unit))
536 if name == "dt_node_array_prop_hex":
537 return hex(_node_array_prop(node, prop, index, unit))
538
539
Johann Fischer73199f22021-11-18 17:12:23 +0100540def dt_node_str_prop_equals(kconf, _, path, prop, val):
541 """
542 This function takes a 'path' and property name ('prop') looks for an EDT
543 node at that path. If it finds an EDT node, it will look to see if that
544 node has a property 'prop' of type string. If that 'prop' is equal to 'val'
545 it will return "y" otherwise return "n".
546 """
547
548 if doc_mode or edt is None:
549 return "n"
550
551 try:
552 node = edt.get_node(path)
553 except edtlib.EDTError:
554 return "n"
555
556 if prop not in node.props:
557 return "n"
558
559 if node.props[prop].type != "string":
560 return "n"
561
562 if node.props[prop].val == val:
563 return "y"
564
565 return "n"
Kumar Gala338b43192020-04-03 05:02:35 -0500566
Andrzej Głąbek9f2a27b2022-03-15 14:08:21 +0100567
568def dt_has_compat(kconf, _, compat):
569 """
570 This function takes a 'compat' and returns "y" if any compatible node
571 can be found in the EDT, otherwise it returns "n".
572 """
573 if doc_mode or edt is None:
574 return "n"
575
576 return "y" if compat in edt.compat2nodes else "n"
577
578
Kumar Gala57353972019-08-28 09:30:23 -0500579def dt_compat_enabled(kconf, _, compat):
580 """
Martí Bolívar81650082020-10-05 20:02:13 -0700581 This function takes a 'compat' and returns "y" if we find a status "okay"
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200582 compatible node in the EDT otherwise we return "n"
Kumar Gala57353972019-08-28 09:30:23 -0500583 """
584 if doc_mode or edt is None:
585 return "n"
586
Martí Bolívar81650082020-10-05 20:02:13 -0700587 return "y" if compat in edt.compat2okay else "n"
Kumar Gala57353972019-08-28 09:30:23 -0500588
589
Martí Bolívar3cd4f6c2020-04-10 15:37:58 -0700590def dt_compat_on_bus(kconf, _, compat, bus):
591 """
592 This function takes a 'compat' and returns "y" if we find an "enabled"
593 compatible node in the EDT which is on bus 'bus'. It returns "n" otherwise.
594 """
595 if doc_mode or edt is None:
596 return "n"
597
Andrzej Głąbekf9c1f892021-02-03 13:53:48 +0100598 if compat in edt.compat2okay:
599 for node in edt.compat2okay[compat]:
Daniel Leung418c9152022-08-26 10:52:32 -0700600 if node.on_buses is not None and bus in node.on_buses:
Andrzej Głąbekf9c1f892021-02-03 13:53:48 +0100601 return "y"
Martí Bolívar3cd4f6c2020-04-10 15:37:58 -0700602
603 return "n"
604
605
Andrzej Głąbek3331a202020-02-14 11:53:21 +0100606def dt_nodelabel_has_compat(kconf, _, label, compat):
607 """
Andrzej Głąbekcd00a3a2022-03-28 12:16:51 +0200608 This function takes a 'label' and looks for an EDT node with that label.
609 If it finds such node, it returns "y" if this node is compatible with
610 the provided 'compat'. Otherwise, it return "n" .
611 """
612 if doc_mode or edt is None:
613 return "n"
614
615 node = edt.label2node.get(label)
616
617 if node and compat in node.compats:
618 return "y"
619
620 return "n"
621
Daniel DeGrasse6aa71942022-08-26 12:12:24 -0500622def dt_node_has_compat(kconf, _, path, compat):
623 """
624 This function takes a 'path' and looks for an EDT node at that path. If it
625 finds an EDT node, it returns "y" if this node is compatible with
626 the provided 'compat'. Otherwise, it return "n" .
627 """
628
629 if doc_mode or edt is None:
630 return "n"
631
632 try:
633 node = edt.get_node(path)
634 except edtlib.EDTError:
635 return "n"
636
637 if node and compat in node.compats:
638 return "y"
639
640 return "n"
Andrzej Głąbekcd00a3a2022-03-28 12:16:51 +0200641
642def dt_nodelabel_enabled_with_compat(kconf, _, label, compat):
643 """
Andrzej Głąbek3331a202020-02-14 11:53:21 +0100644 This function takes a 'label' and returns "y" if an "enabled" node with
645 such label can be found in the EDT and that node is compatible with the
646 provided 'compat', otherwise it returns "n".
647 """
648 if doc_mode or edt is None:
649 return "n"
650
Andrzej Głąbekf9c1f892021-02-03 13:53:48 +0100651 if compat in edt.compat2okay:
652 for node in edt.compat2okay[compat]:
653 if label in node.labels:
654 return "y"
Andrzej Głąbek3331a202020-02-14 11:53:21 +0100655
656 return "n"
657
658
Stephen Stautsd4b8db72022-12-27 11:40:17 +0100659def dt_nodelabel_array_prop_has_val(kconf, _, label, prop, val):
660 """
661 This function looks for a node with node label 'label'.
662 If the node exists, it checks if the node node has a property
663 'prop' with type "array". If so, and the property contains
664 an element equal to the integer 'val', it returns "y".
665 Otherwise, it returns "n".
666 """
667 if doc_mode or edt is None:
668 return "n"
669
670 node = edt.label2node.get(label)
671
672 if not node or (prop not in node.props) or (node.props[prop].type != "array"):
673 return "n"
674 else:
675 return "y" if int(val, base=0) in node.props[prop].val else "n"
676
677
Martí Bolívar1fff2352020-04-22 18:06:18 -0700678def dt_nodelabel_path(kconf, _, label):
679 """
680 This function takes a node label (not a label property) and
681 returns the path to the node which has that label, or an empty
682 string if there is no such node.
683 """
684 if doc_mode or edt is None:
685 return ""
686
687 node = edt.label2node.get(label)
688
689 return node.path if node else ""
690
Daniel DeGrassedb9bcd92022-08-26 12:10:14 -0500691def dt_node_parent(kconf, _, path):
692 """
693 This function takes a 'path' and looks for an EDT node at that path. If it
694 finds an EDT node, it will look for the parent of that node. If the parent
695 exists, it will return the path to that parent. Otherwise, an empty string
696 will be returned.
697 """
698 if doc_mode or edt is None:
699 return ""
700
701 try:
702 node = edt.get_node(path)
703 except edtlib.EDTError:
704 return ""
705
706 if node is None:
707 return ""
708
709 return node.parent.path if node.parent else ""
Martí Bolívar1fff2352020-04-22 18:06:18 -0700710
Erwan Gouriou17537c72019-11-22 10:06:57 +0100711def shields_list_contains(kconf, _, shield):
712 """
713 Return "n" if cmake environment variable 'SHIELD_AS_LIST' doesn't exist.
714 Return "y" if 'shield' is present list obtained after 'SHIELD_AS_LIST'
715 has been split using ";" as a separator and "n" otherwise.
716 """
717 try:
718 list = os.environ['SHIELD_AS_LIST']
719 except KeyError:
720 return "n"
721
722 return "y" if shield in list.split(";") else "n"
723
724
Martí Bolívar006319f2020-07-21 15:20:18 -0700725# Keys in this dict are the function names as they appear
726# in Kconfig files. The values are tuples in this form:
727#
728# (python_function, minimum_number_of_args, maximum_number_of_args)
729#
730# Each python function is given a kconf object and its name in the
731# Kconfig file, followed by arguments from the Kconfig file.
732#
733# See the kconfiglib documentation for more details.
Kumar Gala87915cd2018-11-15 11:51:50 -0600734functions = {
Andrzej Głąbek9f2a27b2022-03-15 14:08:21 +0100735 "dt_has_compat": (dt_has_compat, 1, 1),
Kumar Gala57353972019-08-28 09:30:23 -0500736 "dt_compat_enabled": (dt_compat_enabled, 1, 1),
Martí Bolívar3cd4f6c2020-04-10 15:37:58 -0700737 "dt_compat_on_bus": (dt_compat_on_bus, 2, 2),
Kumar Gala57353972019-08-28 09:30:23 -0500738 "dt_chosen_label": (dt_chosen_label, 1, 1),
Kumar Gala07e5d892019-11-04 10:20:59 -0600739 "dt_chosen_enabled": (dt_chosen_enabled, 1, 1),
Martí Bolívar7ff3ebc2020-04-23 12:28:06 -0700740 "dt_chosen_path": (dt_chosen_path, 1, 1),
Daniel DeGrassefbefc502022-04-11 11:53:03 -0500741 "dt_chosen_has_compat": (dt_chosen_has_compat, 2, 2),
Martí Bolívar24677f92020-04-28 16:52:35 -0700742 "dt_path_enabled": (dt_node_enabled, 1, 1),
743 "dt_alias_enabled": (dt_node_enabled, 1, 1),
Kumar Gala0353d222020-02-13 23:43:42 -0600744 "dt_nodelabel_enabled": (dt_nodelabel_enabled, 1, 1),
Andrzej Głąbekcd00a3a2022-03-28 12:16:51 +0200745 "dt_nodelabel_enabled_with_compat": (dt_nodelabel_enabled_with_compat, 2, 2),
Ulf Magnussonb4e18072019-12-23 11:07:27 +0100746 "dt_chosen_reg_addr_int": (dt_chosen_reg, 1, 3),
747 "dt_chosen_reg_addr_hex": (dt_chosen_reg, 1, 3),
748 "dt_chosen_reg_size_int": (dt_chosen_reg, 1, 3),
749 "dt_chosen_reg_size_hex": (dt_chosen_reg, 1, 3),
750 "dt_node_reg_addr_int": (dt_node_reg, 1, 3),
751 "dt_node_reg_addr_hex": (dt_node_reg, 1, 3),
752 "dt_node_reg_size_int": (dt_node_reg, 1, 3),
753 "dt_node_reg_size_hex": (dt_node_reg, 1, 3),
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100754 "dt_node_bool_prop": (dt_node_bool_prop, 2, 2),
755 "dt_nodelabel_bool_prop": (dt_nodelabel_bool_prop, 2, 2),
Stephen Stautsd4b8db72022-12-27 11:40:17 +0100756 "dt_chosen_bool_prop": (dt_chosen_bool_prop, 2, 2),
Erwan Gourioub7110282021-01-07 12:06:31 +0100757 "dt_node_has_prop": (dt_node_has_prop, 2, 2),
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100758 "dt_nodelabel_has_prop": (dt_nodelabel_has_prop, 2, 2),
David Leach1e5a8302021-11-08 23:24:22 -0600759 "dt_node_int_prop_int": (dt_node_int_prop, 2, 3),
760 "dt_node_int_prop_hex": (dt_node_int_prop, 2, 3),
Eivind Jølsgard3865e082022-03-18 10:50:00 +0100761 "dt_node_array_prop_int": (dt_node_array_prop, 3, 4),
762 "dt_node_array_prop_hex": (dt_node_array_prop, 3, 4),
Johann Fischer73199f22021-11-18 17:12:23 +0100763 "dt_node_str_prop_equals": (dt_node_str_prop_equals, 3, 3),
Andrzej Głąbek3331a202020-02-14 11:53:21 +0100764 "dt_nodelabel_has_compat": (dt_nodelabel_has_compat, 2, 2),
Daniel DeGrasse6aa71942022-08-26 12:12:24 -0500765 "dt_node_has_compat": (dt_node_has_compat, 2, 2),
Martí Bolívar1fff2352020-04-22 18:06:18 -0700766 "dt_nodelabel_path": (dt_nodelabel_path, 1, 1),
Daniel DeGrassedb9bcd92022-08-26 12:10:14 -0500767 "dt_node_parent": (dt_node_parent, 1, 1),
Stephen Stautsd4b8db72022-12-27 11:40:17 +0100768 "dt_nodelabel_array_prop_has_val": (dt_nodelabel_array_prop_has_val, 3, 3),
Erwan Gouriou17537c72019-11-22 10:06:57 +0100769 "shields_list_contains": (shields_list_contains, 1, 1),
Kumar Gala87915cd2018-11-15 11:51:50 -0600770}