blob: 2d433bbd5ddf1a89fbd5d6fc1b96243b0eef56da [file] [log] [blame]
Kumar Galab109a0a2022-07-01 18:49:15 -05001#!/usr/bin/env python3
2#
3# Copyright (c) 2022 Kumar Gala <galak@kernel.org>
4#
5# SPDX-License-Identifier: Apache-2.0
6
7import argparse
8import os
9import sys
10import re
11
12import yaml
13try:
14 # Use the C LibYAML parser if available, rather than the Python parser.
Moritz Fischer7dd05962022-12-20 09:01:19 -080015 from yaml import CSafeLoader as SafeLoader
Kumar Galab109a0a2022-07-01 18:49:15 -050016except ImportError:
Moritz Fischer7dd05962022-12-20 09:01:19 -080017 from yaml import SafeLoader # type: ignore
Kumar Galab109a0a2022-07-01 18:49:15 -050018
19sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'python-devicetree',
20 'src'))
21
22def binding_paths(bindings_dirs):
23 # Returns a list with the paths to all bindings (.yaml files) in
24 # 'bindings_dirs'
25
26 binding_paths = []
27
28 for bindings_dir in bindings_dirs:
29 for root, _, filenames in os.walk(bindings_dir):
30 for filename in filenames:
31 if filename.endswith(".yaml") or filename.endswith(".yml"):
32 binding_paths.append(os.path.join(root, filename))
33
34 return binding_paths
35
36def parse_args():
37 # Returns parsed command-line arguments
38
Jamie McCraeec704442023-01-04 16:08:36 +000039 parser = argparse.ArgumentParser(allow_abbrev=False)
Kumar Galab109a0a2022-07-01 18:49:15 -050040 parser.add_argument("--kconfig-out", required=True,
41 help="path to write the Kconfig file")
42 parser.add_argument("--bindings-dirs", nargs='+', required=True,
43 help="directory with bindings in YAML format, "
44 "we allow multiple")
45
46 return parser.parse_args()
47
48def printfile(s):
49 print(s, file=kconfig_file)
50
51def str2ident(s):
52 # Converts 's' to a form suitable for (part of) an identifier
53
54 return re.sub('[-,.@/+]', '_', s.upper())
55
56def compat2kconfig(compat):
57 compat_ident = str2ident(compat)
58
59 printfile(f'')
60 printfile(f'DT_COMPAT_{compat_ident} := {compat}')
61 printfile(f'')
62 printfile(f'config DT_HAS_{compat_ident}_ENABLED')
63 printfile(f'\tdef_bool $(dt_compat_enabled,$(DT_COMPAT_{compat_ident}))')
64
65def main():
66 global kconfig_file
67 args = parse_args()
68
69 compat_list = []
70
71 for binding_path in binding_paths(args.bindings_dirs):
72 with open(binding_path, encoding="utf-8") as f:
73 contents = f.read()
74
75 try:
76 # Parsed PyYAML output (Python lists/dictionaries/strings/etc.,
77 # representing the file)
Moritz Fischer7dd05962022-12-20 09:01:19 -080078 raw = yaml.load(contents, Loader=SafeLoader)
Kumar Galab109a0a2022-07-01 18:49:15 -050079 except yaml.YAMLError as e:
80 print(f"WARNING: '{binding_path}' appears in binding "
81 f"directories but isn't valid YAML: {e}")
82 continue
Allan Norgaard23cacb32023-01-11 15:38:41 +010083 if raw is None or 'compatible' not in raw:
Kumar Galab109a0a2022-07-01 18:49:15 -050084 continue
85
86 compat_list.append(raw['compatible'])
87
88 # Remove any duplicates and sort the list
89 compat_list = sorted(set(compat_list))
90
91 with open(args.kconfig_out, "w", encoding="utf-8") as kconfig_file:
92 printfile(f'# Generated devicetree Kconfig')
93 printfile(f'#')
94 printfile(f'# SPDX-License-Identifier: Apache-2.0')
95
96 for c in compat_list:
97 compat2kconfig(c)
98
99
100if __name__ == "__main__":
101 main()