kconfig: Add new functions to kconfigfunctions to use EDT
Add a new set of functions that utilize EDT so we can move away from the
generated .conf file.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
diff --git a/scripts/kconfig/kconfigfunctions.py b/scripts/kconfig/kconfigfunctions.py
index a2dc124..938dd32 100644
--- a/scripts/kconfig/kconfigfunctions.py
+++ b/scripts/kconfig/kconfigfunctions.py
@@ -5,6 +5,12 @@
# SPDX-License-Identifier: Apache-2.0
import os
+import sys
+
+ZEPHYR_BASE = os.environ.get("ZEPHYR_BASE")
+sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/dts"))
+
+import edtlib
# Types we support
# 'string', 'int', 'hex', 'bool'
@@ -13,6 +19,15 @@
dt_defines = {}
if not doc_mode:
+ DTS_POST_CPP = os.environ["DTS_POST_CPP"]
+ BINDINGS_DIR = os.environ.get("DTS_ROOT_BINDINGS")
+
+ # if a board port doesn't use DTS than these might not be set
+ if os.path.isfile(DTS_POST_CPP) and BINDINGS_DIR is not None:
+ edt = edtlib.EDT(DTS_POST_CPP, [BINDINGS_DIR])
+ else:
+ edt = None
+
# The env var 'GENERATED_DTS_BOARD_CONF' must be set unless we are in
# doc mode
GENERATED_DTS_BOARD_CONF = os.environ['GENERATED_DTS_BOARD_CONF']
@@ -91,8 +106,194 @@
return dt_defines[name].strip('"')
+
+def dt_chosen_label(kconf, _, chosen):
+ """
+ This function takes a 'chosen' property and treats that property as a path
+ to a EDT device. If it finds a EDT device, it will look to see if that
+ device has a "label" property and return the value of that "label", if not
+ we return an empty string.
+ """
+ if doc_mode or edt is None:
+ return ""
+
+ dev = edt.chosen_dev(chosen)
+ if not dev:
+ return ""
+
+ if "label" not in dev.props:
+ return ""
+
+ return dev.props["label"].val
+
+
+def _dev_reg_addr(dev, index, unit):
+ if not dev:
+ return "0x0"
+
+ if not dev.regs:
+ return "0x0"
+
+ if int(index) >= len(dev.regs):
+ return "0x0"
+
+ return hex(dev.regs[int(index)].addr >> _dt_units_to_scale(unit))
+
+
+def _dev_reg_size(dev, index, unit):
+ if not dev:
+ return "0"
+
+ if not dev.regs:
+ return "0"
+
+ if int(index) >= len(dev.regs):
+ return "0"
+
+ return str(dev.regs[int(index)].size >> _dt_units_to_scale(unit))
+
+
+def dt_chosen_reg_addr(kconf, _, chosen, index=0, unit=None):
+ """
+ This function takes a 'chosen' property and treats that property as a path
+ to a EDT device. If it finds a EDT device, it will look to see if that
+ device has a register at the give 'index' and return the address value of
+ that reg, if not we return 0.
+
+ The function will divide the value based on 'unit':
+ None No division
+ 'k' or 'K' divide by 1024 (1 << 10)
+ 'm' or 'M' divide by 1,048,576 (1 << 20)
+ 'g' or 'G' divide by 1,073,741,824 (1 << 30)
+ """
+ if doc_mode or edt is None:
+ return "0x0"
+
+ dev = edt.chosen_dev(chosen)
+
+ return _dev_reg_addr(dev, index, unit)
+
+
+def dt_chosen_reg_size(kconf, _, chosen, index=0, unit=None):
+ """
+ This function takes a 'chosen' property and treats that property as a path
+ to a EDT device. If it finds a EDT device, it will look to see if that
+ device has a register at the give 'index' and return the size value of
+ that reg, if not we return 0.
+
+ The function will divide the value based on 'unit':
+ None No division
+ 'k' or 'K' divide by 1024 (1 << 10)
+ 'm' or 'M' divide by 1,048,576 (1 << 20)
+ 'g' or 'G' divide by 1,073,741,824 (1 << 30)
+ """
+ if doc_mode or edt is None:
+ return "0"
+
+ dev = edt.chosen_dev(chosen)
+
+ return _dev_reg_size(dev, index, unit)
+
+
+def dt_node_reg_addr(kconf, _, path, index=0, unit=None):
+ """
+ This function takes a 'path' and looks for a EDT device at that path.
+ If it finds a EDT device, it will look to see if that device has a
+ register at the give 'index' and return the address value of that reg, if
+ not we return 0.
+
+ The function will divide the value based on 'unit':
+ None No division
+ 'k' or 'K' divide by 1024 (1 << 10)
+ 'm' or 'M' divide by 1,048,576 (1 << 20)
+ 'g' or 'G' divide by 1,073,741,824 (1 << 30)
+ """
+ if doc_mode or edt is None:
+ return "0"
+
+ try:
+ dev = edt.get_dev(path)
+ except edtlib.EDTError:
+ return "0"
+
+ return _dev_reg_addr(dev, index, unit)
+
+
+def dt_node_reg_size(kconf, _, path, index=0, unit=None):
+ """
+ This function takes a 'path' and looks for a EDT device at that path.
+ If it finds a EDT device, it will look to see if that device has a
+ register at the give 'index' and return the size value of that reg, if
+ not we return 0.
+
+ The function will divide the value based on 'unit':
+ None No division
+ 'k' or 'K' divide by 1024 (1 << 10)
+ 'm' or 'M' divide by 1,048,576 (1 << 20)
+ 'g' or 'G' divide by 1,073,741,824 (1 << 30)
+ """
+ if doc_mode or edt is None:
+ return "0"
+
+ try:
+ dev = edt.get_dev(path)
+ except edtlib.EDTError:
+ return "0"
+
+ return _dev_reg_size(dev, index, unit)
+
+
+def dt_node_has_bool_prop(kconf, _, path, prop):
+ """
+ This function takes a 'path' and looks for a EDT device at that path.
+ If it finds a EDT device, it will look to see if that device has a
+ boolean property by the name of 'prop'. If the 'prop' exists it will
+ return "y" otherwise we return "n".
+ """
+ if doc_mode or edt is None:
+ return "n"
+
+ try:
+ dev = edt.get_dev(path)
+ except edtlib.EDTError:
+ return "n"
+
+ if prop not in dev.props:
+ return "n"
+
+ if dev.props[prop].type != "boolean":
+ return "n"
+
+ if dev.props[prop].val:
+ return "y"
+
+ return "n"
+
+
+def dt_compat_enabled(kconf, _, compat):
+ """
+ This function takes a 'compat' and returns "y" if we find an "enabled"
+ compatible device in the EDT otherwise we return "n"
+ """
+ if doc_mode or edt is None:
+ return "n"
+
+ for dev in edt.devices:
+ if compat in dev.compats and dev.enabled:
+ return "y"
+
+ return "n"
+
+
functions = {
"dt_int_val": (dt_int_val, 1, 2),
"dt_hex_val": (dt_hex_val, 1, 2),
"dt_str_val": (dt_str_val, 1, 1),
+ "dt_compat_enabled": (dt_compat_enabled, 1, 1),
+ "dt_chosen_label": (dt_chosen_label, 1, 1),
+ "dt_chosen_reg_addr": (dt_chosen_reg_addr, 1, 3),
+ "dt_chosen_reg_size": (dt_chosen_reg_size, 1, 3),
+ "dt_node_reg_addr": (dt_node_reg_addr, 1, 3),
+ "dt_node_reg_size": (dt_node_reg_size, 1, 3),
+ "dt_node_has_bool_prop": (dt_node_has_bool_prop, 2, 2),
}