blob: fcf04a29a15d4b4227232607fb999d47a6070f49 [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
428def _dt_node_has_prop_generic(node_search_function, search_arg, prop):
429 """
430 This function takes the 'node_search_function' and uses it to search for
431 a node with 'search_arg' and if node exists, then checks if 'prop'
432 exists inside the node and returns "y". Otherwise, it returns "n".
433 """
Erwan Gourioub7110282021-01-07 12:06:31 +0100434 try:
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100435 node = node_search_function(search_arg)
Erwan Gourioub7110282021-01-07 12:06:31 +0100436 except edtlib.EDTError:
437 return "n"
438
439 if node is None:
440 return "n"
441
442 if prop in node.props:
443 return "y"
444
445 return "n"
Kumar Gala57353972019-08-28 09:30:23 -0500446
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100447def dt_node_has_prop(kconf, _, path, prop):
448 """
449 This function takes a 'path' and looks for an EDT node at that path. If it
450 finds an EDT node, it will look to see if that node has a property
451 by the name of 'prop'. If the 'prop' exists it will return "y" otherwise
452 it returns "n".
453 """
454 if doc_mode or edt is None:
455 return "n"
456
457 return _dt_node_has_prop_generic(edt.get_node, path, prop)
458
459def dt_nodelabel_has_prop(kconf, _, label, prop):
460 """
461 This function takes a 'label' and looks for an EDT node with that label.
462 If it finds an EDT node, it will look to see if that node has a property
463 by the name of 'prop'. If the 'prop' exists it will return "y" otherwise
464 it returns "n".
465 """
466 if doc_mode or edt is None:
467 return "n"
468
469 return _dt_node_has_prop_generic(edt.label2node.get, label, prop)
470
David Leach1e5a8302021-11-08 23:24:22 -0600471def dt_node_int_prop(kconf, name, path, prop, unit=None):
Kumar Gala338b43192020-04-03 05:02:35 -0500472 """
473 This function takes a 'path' and property name ('prop') looks for an EDT
474 node at that path. If it finds an EDT node, it will look to see if that
475 node has a property called 'prop' and if that 'prop' is an integer type
476 will return the value of the property 'prop' as either a string int or
477 string hex value, if not we return 0.
Kumar Gala338b43192020-04-03 05:02:35 -0500478
David Leach1e5a8302021-11-08 23:24:22 -0600479 The function will divide the value based on 'unit':
480 None No division
481 'k' or 'K' divide by 1024 (1 << 10)
482 'm' or 'M' divide by 1,048,576 (1 << 20)
483 'g' or 'G' divide by 1,073,741,824 (1 << 30)
Daniel DeGrasse6064da82022-05-25 17:38:59 -0500484 'kb' or 'Kb' divide by 8192 (1 << 13)
485 'mb' or 'Mb' divide by 8,388,608 (1 << 23)
486 'gb' or 'Gb' divide by 8,589,934,592 (1 << 33)
David Leach1e5a8302021-11-08 23:24:22 -0600487 """
Kumar Gala338b43192020-04-03 05:02:35 -0500488 if doc_mode or edt is None:
489 return "0"
490
491 try:
492 node = edt.get_node(path)
493 except edtlib.EDTError:
494 return "0"
495
496 if name == "dt_node_int_prop_int":
David Leach1e5a8302021-11-08 23:24:22 -0600497 return str(_node_int_prop(node, prop, unit))
Kumar Gala338b43192020-04-03 05:02:35 -0500498 if name == "dt_node_int_prop_hex":
David Leach1e5a8302021-11-08 23:24:22 -0600499 return hex(_node_int_prop(node, prop, unit))
Kumar Gala338b43192020-04-03 05:02:35 -0500500
Eivind Jølsgard3865e082022-03-18 10:50:00 +0100501
502def dt_node_array_prop(kconf, name, path, prop, index, unit=None):
503 """
504 This function takes a 'path', property name ('prop') and index ('index')
505 and looks for an EDT node at that path. If it finds an EDT node, it will
506 look to see if that node has a property called 'prop' and if that 'prop'
507 is an array type will return the value of the property 'prop' at the given
508 'index' as either a string int or string hex value. If not found we return 0.
509
510 The function will divide the value based on 'unit':
511 None No division
512 'k' or 'K' divide by 1024 (1 << 10)
513 'm' or 'M' divide by 1,048,576 (1 << 20)
514 'g' or 'G' divide by 1,073,741,824 (1 << 30)
515 """
516 if doc_mode or edt is None:
517 return "0"
518
519 try:
520 node = edt.get_node(path)
521 except edtlib.EDTError:
522 return "0"
523 if name == "dt_node_array_prop_int":
524 return str(_node_array_prop(node, prop, index, unit))
525 if name == "dt_node_array_prop_hex":
526 return hex(_node_array_prop(node, prop, index, unit))
527
528
Johann Fischer73199f22021-11-18 17:12:23 +0100529def dt_node_str_prop_equals(kconf, _, path, prop, val):
530 """
531 This function takes a 'path' and property name ('prop') looks for an EDT
532 node at that path. If it finds an EDT node, it will look to see if that
533 node has a property 'prop' of type string. If that 'prop' is equal to 'val'
534 it will return "y" otherwise return "n".
535 """
536
537 if doc_mode or edt is None:
538 return "n"
539
540 try:
541 node = edt.get_node(path)
542 except edtlib.EDTError:
543 return "n"
544
545 if prop not in node.props:
546 return "n"
547
548 if node.props[prop].type != "string":
549 return "n"
550
551 if node.props[prop].val == val:
552 return "y"
553
554 return "n"
Kumar Gala338b43192020-04-03 05:02:35 -0500555
Andrzej Głąbek9f2a27b2022-03-15 14:08:21 +0100556
557def dt_has_compat(kconf, _, compat):
558 """
559 This function takes a 'compat' and returns "y" if any compatible node
560 can be found in the EDT, otherwise it returns "n".
561 """
562 if doc_mode or edt is None:
563 return "n"
564
565 return "y" if compat in edt.compat2nodes else "n"
566
567
Kumar Gala57353972019-08-28 09:30:23 -0500568def dt_compat_enabled(kconf, _, compat):
569 """
Martí Bolívar81650082020-10-05 20:02:13 -0700570 This function takes a 'compat' and returns "y" if we find a status "okay"
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200571 compatible node in the EDT otherwise we return "n"
Kumar Gala57353972019-08-28 09:30:23 -0500572 """
573 if doc_mode or edt is None:
574 return "n"
575
Martí Bolívar81650082020-10-05 20:02:13 -0700576 return "y" if compat in edt.compat2okay else "n"
Kumar Gala57353972019-08-28 09:30:23 -0500577
578
Martí Bolívar3cd4f6c2020-04-10 15:37:58 -0700579def dt_compat_on_bus(kconf, _, compat, bus):
580 """
581 This function takes a 'compat' and returns "y" if we find an "enabled"
582 compatible node in the EDT which is on bus 'bus'. It returns "n" otherwise.
583 """
584 if doc_mode or edt is None:
585 return "n"
586
Andrzej Głąbekf9c1f892021-02-03 13:53:48 +0100587 if compat in edt.compat2okay:
588 for node in edt.compat2okay[compat]:
Daniel Leung418c9152022-08-26 10:52:32 -0700589 if node.on_buses is not None and bus in node.on_buses:
Andrzej Głąbekf9c1f892021-02-03 13:53:48 +0100590 return "y"
Martí Bolívar3cd4f6c2020-04-10 15:37:58 -0700591
592 return "n"
593
594
Andrzej Głąbek3331a202020-02-14 11:53:21 +0100595def dt_nodelabel_has_compat(kconf, _, label, compat):
596 """
Andrzej Głąbekcd00a3a2022-03-28 12:16:51 +0200597 This function takes a 'label' and looks for an EDT node with that label.
598 If it finds such node, it returns "y" if this node is compatible with
599 the provided 'compat'. Otherwise, it return "n" .
600 """
601 if doc_mode or edt is None:
602 return "n"
603
604 node = edt.label2node.get(label)
605
606 if node and compat in node.compats:
607 return "y"
608
609 return "n"
610
611
612def dt_nodelabel_enabled_with_compat(kconf, _, label, compat):
613 """
Andrzej Głąbek3331a202020-02-14 11:53:21 +0100614 This function takes a 'label' and returns "y" if an "enabled" node with
615 such label can be found in the EDT and that node is compatible with the
616 provided 'compat', otherwise it returns "n".
617 """
618 if doc_mode or edt is None:
619 return "n"
620
Andrzej Głąbekf9c1f892021-02-03 13:53:48 +0100621 if compat in edt.compat2okay:
622 for node in edt.compat2okay[compat]:
623 if label in node.labels:
624 return "y"
Andrzej Głąbek3331a202020-02-14 11:53:21 +0100625
626 return "n"
627
628
Martí Bolívar1fff2352020-04-22 18:06:18 -0700629def dt_nodelabel_path(kconf, _, label):
630 """
631 This function takes a node label (not a label property) and
632 returns the path to the node which has that label, or an empty
633 string if there is no such node.
634 """
635 if doc_mode or edt is None:
636 return ""
637
638 node = edt.label2node.get(label)
639
640 return node.path if node else ""
641
642
Erwan Gouriou17537c72019-11-22 10:06:57 +0100643def shields_list_contains(kconf, _, shield):
644 """
645 Return "n" if cmake environment variable 'SHIELD_AS_LIST' doesn't exist.
646 Return "y" if 'shield' is present list obtained after 'SHIELD_AS_LIST'
647 has been split using ";" as a separator and "n" otherwise.
648 """
649 try:
650 list = os.environ['SHIELD_AS_LIST']
651 except KeyError:
652 return "n"
653
654 return "y" if shield in list.split(";") else "n"
655
656
Martí Bolívar006319f2020-07-21 15:20:18 -0700657# Keys in this dict are the function names as they appear
658# in Kconfig files. The values are tuples in this form:
659#
660# (python_function, minimum_number_of_args, maximum_number_of_args)
661#
662# Each python function is given a kconf object and its name in the
663# Kconfig file, followed by arguments from the Kconfig file.
664#
665# See the kconfiglib documentation for more details.
Kumar Gala87915cd2018-11-15 11:51:50 -0600666functions = {
Andrzej Głąbek9f2a27b2022-03-15 14:08:21 +0100667 "dt_has_compat": (dt_has_compat, 1, 1),
Kumar Gala57353972019-08-28 09:30:23 -0500668 "dt_compat_enabled": (dt_compat_enabled, 1, 1),
Martí Bolívar3cd4f6c2020-04-10 15:37:58 -0700669 "dt_compat_on_bus": (dt_compat_on_bus, 2, 2),
Kumar Gala57353972019-08-28 09:30:23 -0500670 "dt_chosen_label": (dt_chosen_label, 1, 1),
Kumar Gala07e5d892019-11-04 10:20:59 -0600671 "dt_chosen_enabled": (dt_chosen_enabled, 1, 1),
Martí Bolívar7ff3ebc2020-04-23 12:28:06 -0700672 "dt_chosen_path": (dt_chosen_path, 1, 1),
Daniel DeGrassefbefc502022-04-11 11:53:03 -0500673 "dt_chosen_has_compat": (dt_chosen_has_compat, 2, 2),
Martí Bolívar24677f92020-04-28 16:52:35 -0700674 "dt_path_enabled": (dt_node_enabled, 1, 1),
675 "dt_alias_enabled": (dt_node_enabled, 1, 1),
Kumar Gala0353d222020-02-13 23:43:42 -0600676 "dt_nodelabel_enabled": (dt_nodelabel_enabled, 1, 1),
Andrzej Głąbekcd00a3a2022-03-28 12:16:51 +0200677 "dt_nodelabel_enabled_with_compat": (dt_nodelabel_enabled_with_compat, 2, 2),
Ulf Magnussonb4e18072019-12-23 11:07:27 +0100678 "dt_chosen_reg_addr_int": (dt_chosen_reg, 1, 3),
679 "dt_chosen_reg_addr_hex": (dt_chosen_reg, 1, 3),
680 "dt_chosen_reg_size_int": (dt_chosen_reg, 1, 3),
681 "dt_chosen_reg_size_hex": (dt_chosen_reg, 1, 3),
682 "dt_node_reg_addr_int": (dt_node_reg, 1, 3),
683 "dt_node_reg_addr_hex": (dt_node_reg, 1, 3),
684 "dt_node_reg_size_int": (dt_node_reg, 1, 3),
685 "dt_node_reg_size_hex": (dt_node_reg, 1, 3),
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100686 "dt_node_bool_prop": (dt_node_bool_prop, 2, 2),
687 "dt_nodelabel_bool_prop": (dt_nodelabel_bool_prop, 2, 2),
Erwan Gourioub7110282021-01-07 12:06:31 +0100688 "dt_node_has_prop": (dt_node_has_prop, 2, 2),
Michał Barnaśa1ab8da2022-03-08 17:44:04 +0100689 "dt_nodelabel_has_prop": (dt_nodelabel_has_prop, 2, 2),
David Leach1e5a8302021-11-08 23:24:22 -0600690 "dt_node_int_prop_int": (dt_node_int_prop, 2, 3),
691 "dt_node_int_prop_hex": (dt_node_int_prop, 2, 3),
Eivind Jølsgard3865e082022-03-18 10:50:00 +0100692 "dt_node_array_prop_int": (dt_node_array_prop, 3, 4),
693 "dt_node_array_prop_hex": (dt_node_array_prop, 3, 4),
Johann Fischer73199f22021-11-18 17:12:23 +0100694 "dt_node_str_prop_equals": (dt_node_str_prop_equals, 3, 3),
Andrzej Głąbek3331a202020-02-14 11:53:21 +0100695 "dt_nodelabel_has_compat": (dt_nodelabel_has_compat, 2, 2),
Martí Bolívar1fff2352020-04-22 18:06:18 -0700696 "dt_nodelabel_path": (dt_nodelabel_path, 1, 1),
Erwan Gouriou17537c72019-11-22 10:06:57 +0100697 "shields_list_contains": (shields_list_contains, 1, 1),
Kumar Gala87915cd2018-11-15 11:51:50 -0600698}