blob: 182c6949ebca162afe6f5919087ac74a61ab9810 [file] [log] [blame]
Madhurima Paruchurifa738b02022-10-26 13:34:09 +00001#!/usr/bin/env python3
2
3# Copyright (c) 2022 The Chromium OS Authors
4# SPDX-License-Identifier: Apache-2.0
5
6"""This file contains a Python script which parses through Zephyr device tree using
7EDT.pickle generated at build and generates a XML file containing USB VIF policies"""
8
9import argparse
Keith Short52e6b4e2023-03-24 15:17:31 -060010import inspect
Madhurima Paruchurifa738b02022-10-26 13:34:09 +000011import os
12import pickle
13import sys
14import xml.etree.ElementTree as ET
15
Madhurima Paruchuria19d9052023-03-28 19:11:58 +000016from constants import dt_constants
17from constants import other_constants
18from constants import pdo_constants
19from constants import vif_element_constants
20from constants import xml_constants
Madhurima Paruchurifa738b02022-10-26 13:34:09 +000021
22SCRIPTS_DIR = os.path.join(os.path.dirname(__file__), "..")
23sys.path.insert(0, os.path.join(SCRIPTS_DIR, 'dts', 'python-devicetree', 'src'))
24
Keith Short52e6b4e2023-03-24 15:17:31 -060025
Madhurima Paruchuria19d9052023-03-28 19:11:58 +000026def get_value_attribute(data):
27 if not isinstance(data, str):
28 data = str(data)
29 return {other_constants.VALUE: data}
Madhurima Paruchurifa738b02022-10-26 13:34:09 +000030
31
32def get_vif_element_name(name):
Madhurima Paruchuria19d9052023-03-28 19:11:58 +000033 return xml_constants.XML_ELEMENT_NAME_PREFIX + ":" + dt_constants.DT_VIF_ELEMENTS.get(
Madhurima Paruchurifa738b02022-10-26 13:34:09 +000034 name, name)
35
36
37def get_root():
Madhurima Paruchuria19d9052023-03-28 19:11:58 +000038 xml_root = ET.Element(
39 get_vif_element_name(xml_constants.XML_ROOT_ELEMENT_NAME))
40 add_attributes_to_xml_element(xml_root,
41 xml_constants.XML_NAMESPACE_ATTRIBUTES)
Madhurima Paruchurifa738b02022-10-26 13:34:09 +000042 return xml_root
43
44
45def add_attributes_to_xml_element(xml_ele, attributes):
46 for key, value in attributes.items():
47 xml_ele.set(key, value)
48
49
50def add_element_to_xml(xml_ele, name, text=None, attributes=None):
Madhurima Paruchuria19d9052023-03-28 19:11:58 +000051 new_xml_ele = ET.SubElement(xml_ele, get_vif_element_name(name))
52 if text:
53 new_xml_ele.text = str(text)
54 if attributes:
55 add_attributes_to_xml_element(new_xml_ele, attributes)
56 return new_xml_ele
Madhurima Paruchurifa738b02022-10-26 13:34:09 +000057
58
59def add_elements_to_xml(xml_ele, elements):
60 for element_name in elements:
Madhurima Paruchuria19d9052023-03-28 19:11:58 +000061 text = elements[element_name].get(other_constants.TEXT, None)
62 attributes = elements[element_name].get(other_constants.ATTRIBUTES,
63 None)
64 new_xml_ele = add_element_to_xml(xml_ele, element_name, text,
65 attributes)
66 if other_constants.CHILD in elements[element_name]:
67 add_elements_to_xml(new_xml_ele,
68 elements[element_name][other_constants.CHILD])
69
70
71def add_vif_spec_from_source_to_xml(xml_ele, source_xml_ele):
72 prefix = '{' + xml_constants.XML_VIF_NAMESPACE + '}'
73 for child in source_xml_ele:
74 element_name = child.tag[len(prefix):]
75 if element_name in xml_constants.VIF_SPEC_ELEMENTS_FROM_SOURCE_XML:
76 add_element_to_xml(xml_ele, element_name, child.text,
77 child.attrib)
Madhurima Paruchurifa738b02022-10-26 13:34:09 +000078
79
80def is_simple_datatype(value):
81 if isinstance(value, (str, int, bool)):
82 return True
83 return False
84
85
86def get_pdo_type(pdo_value):
87 return pdo_value >> 30
88
89
90def get_xml_bool_value(value):
91 if value:
Madhurima Paruchuria19d9052023-03-28 19:11:58 +000092 return other_constants.TRUE
93 return other_constants.FALSE
Madhurima Paruchurifa738b02022-10-26 13:34:09 +000094
95
Madhurima Paruchuria19d9052023-03-28 19:11:58 +000096def parse_and_add_sink_pdo_to_xml(xml_ele, pdo_value, pdo_info):
Madhurima Paruchurifa738b02022-10-26 13:34:09 +000097 power_mw = 0
Madhurima Paruchuria19d9052023-03-28 19:11:58 +000098 xml_ele = add_element_to_xml(xml_ele, vif_element_constants.SINK_PDO)
Madhurima Paruchurifa738b02022-10-26 13:34:09 +000099 pdo_type = get_pdo_type(pdo_value)
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000100
101 if pdo_type == pdo_constants.PDO_TYPE_FIXED:
102 # As per USB PD specification Revision 3.1, Version 1.6, Table 6-16 Fixed supply PDO - Sink
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000103 current = pdo_value & 0x3ff
104 current_ma = current * 10
105 voltage = (pdo_value >> 10) & 0x3ff
106 voltage_mv = voltage * 50
107 power_mw = (current_ma * voltage_mv) // 1000
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000108
109 if pdo_value & (1 << 28):
110 pdo_info[vif_element_constants.HIGHER_CAPABILITY_SET] = True
111 pdo_info[
112 vif_element_constants.FR_SWAP_REQD_TYPE_C_CURRENT_AS_INITIAL_SOURCE] = pdo_value & (
113 3 << 23)
114 add_element_to_xml(xml_ele, vif_element_constants.SINK_PDO_VOLTAGE,
115 f'{voltage_mv} mV',
116 get_value_attribute(voltage))
117 add_element_to_xml(xml_ele, vif_element_constants.SINK_PDO_OP_CURRENT,
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000118 f'{current_ma} mA',
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000119 get_value_attribute(current))
120 elif pdo_type == pdo_constants.PDO_TYPE_BATTERY:
121 # As per USB PD specification Revision 3.1, Version 1.6, Table 6-18 Battery supply PDO - Sink
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000122 max_voltage = (pdo_value >> 20) & 0x3ff
123 max_voltage_mv = max_voltage * 50
124 min_voltage = (pdo_value >> 10) & 0x3ff
125 min_voltage_mv = min_voltage * 50
126 power = pdo_value & 0x3ff
127 power_mw = power * 250
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000128
129 add_element_to_xml(xml_ele, vif_element_constants.SINK_PDO_MIN_VOLTAGE,
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000130 f'{min_voltage_mv} mV',
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000131 get_value_attribute(min_voltage))
132 add_element_to_xml(xml_ele, vif_element_constants.SINK_PDO_MAX_VOLTAGE,
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000133 f'{max_voltage_mv} mV',
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000134 get_value_attribute(max_voltage))
135 add_element_to_xml(xml_ele, vif_element_constants.SINK_PDO_OP_POWER,
136 f'{power_mw} mW',
137 get_value_attribute(power))
138 elif pdo_type == pdo_constants.PDO_TYPE_VARIABLE:
139 # As per USB PD specification Revision 3.1, Version 1.6, Table 6-17 Variable supply (non-Battery) PDO - Sink
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000140 max_voltage = (pdo_value >> 20) & 0x3ff
141 max_voltage_mv = max_voltage * 50
142 min_voltage = (pdo_value >> 10) & 0x3ff
143 min_voltage_mv = min_voltage * 50
144 current = pdo_value & 0x3ff
145 current_ma = current * 10
146 power_mw = (current_ma * max_voltage_mv) // 1000
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000147
148 add_element_to_xml(xml_ele, vif_element_constants.SINK_PDO_MIN_VOLTAGE,
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000149 f'{min_voltage_mv} mV',
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000150 get_value_attribute(min_voltage))
151 add_element_to_xml(xml_ele, vif_element_constants.SINK_PDO_MAX_VOLTAGE,
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000152 f'{max_voltage_mv} mV',
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000153 get_value_attribute(max_voltage))
154 add_element_to_xml(xml_ele, vif_element_constants.SINK_PDO_OP_CURRENT,
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000155 f'{current_ma} mA',
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000156 get_value_attribute(current))
157 elif pdo_type == pdo_constants.PDO_TYPE_AUGUMENTED:
158 # As per USB PD specification Revision 3.1, Version 1.6, Table 6-19 Programmable Power supply APDO - Sink
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000159 pps = (pdo_value >> 28) & 0x03
160 if pps:
161 raise ValueError(f'ERROR: Invalid PDO_TYPE {pdo_value}')
162 pps_max_voltage = (pdo_value >> 17) & 0xff
163 pps_max_voltage_mv = pps_max_voltage * 100
164 pps_min_voltage = (pdo_value >> 8) & 0xff
165 pps_min_voltage_mv = pps_min_voltage * 100
166 pps_current = pdo_value & 0x7f
167 pps_current_ma = pps_current * 50
168 power_mw = (pps_current_ma * pps_max_voltage_mv) // 1000
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000169
170 add_element_to_xml(xml_ele, vif_element_constants.SINK_PDO_MIN_VOLTAGE,
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000171 f'{pps_min_voltage_mv} mV',
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000172 get_value_attribute(pps_min_voltage))
173 add_element_to_xml(xml_ele, vif_element_constants.SINK_PDO_MAX_VOLTAGE,
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000174 f'{pps_max_voltage_mv} mV',
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000175 get_value_attribute(pps_max_voltage))
176 add_element_to_xml(xml_ele, vif_element_constants.SINK_PDO_OP_CURRENT,
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000177 f'{pps_current_ma} mA',
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000178 get_value_attribute(pps_current))
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000179 else:
180 raise ValueError(f'ERROR: Invalid PDO_TYPE {pdo_value}')
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000181
182 add_element_to_xml(xml_ele, vif_element_constants.SINK_PDO_SUPPLY_TYPE,
183 pdo_constants.PDO_TYPES[pdo_type],
184 get_value_attribute(pdo_type))
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000185 return power_mw
186
187
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000188def parse_and_add_sink_pdos_to_xml(xml_ele, sink_pdos):
189 new_xml_ele = add_element_to_xml(xml_ele, dt_constants.SINK_PDOS)
190 snk_max_power = 0
191 pdo_info = dict()
192
193 for pdo_value in sink_pdos:
194 power_mv = parse_and_add_sink_pdo_to_xml(new_xml_ele, pdo_value,
195 pdo_info)
196 if power_mv > snk_max_power:
197 snk_max_power = power_mv
198
199 add_element_to_xml(xml_ele, vif_element_constants.PD_POWER_AS_SINK,
200 f'{snk_max_power} mW',
201 get_value_attribute(snk_max_power))
202 add_element_to_xml(xml_ele, vif_element_constants.HIGHER_CAPABILITY_SET,
203 None, get_value_attribute(get_xml_bool_value(
204 vif_element_constants.HIGHER_CAPABILITY_SET in
205 pdo_info)))
206 fr_swap_required_type_c_current_as_initial_source = pdo_info[
207 vif_element_constants.FR_SWAP_REQD_TYPE_C_CURRENT_AS_INITIAL_SOURCE]
208 add_element_to_xml(xml_ele,
209 vif_element_constants.FR_SWAP_REQD_TYPE_C_CURRENT_AS_INITIAL_SOURCE,
210 other_constants.FR_SWAP_REQD_TYPE_C_CURRENT_AS_INITIAL_SOURCE_VALUES[
211 fr_swap_required_type_c_current_as_initial_source],
212 get_value_attribute(
213 fr_swap_required_type_c_current_as_initial_source))
214 add_element_to_xml(xml_ele, vif_element_constants.NUM_SNK_PDOS, None,
215 get_value_attribute(len(sink_pdos)))
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000216
217
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000218def parse_and_add_component_to_xml(xml_ele, node):
219 add_element_to_xml(xml_ele, vif_element_constants.USB_PD_SUPPORT, None,
220 get_value_attribute(get_xml_bool_value(
221 not node.props[dt_constants.PD_DISABLE].val)))
222
223 if not node.props[dt_constants.PD_DISABLE].val:
224 power_role = node.props[dt_constants.POWER_ROLE].val
225 add_element_to_xml(xml_ele, vif_element_constants.PD_PORT_TYPE,
226 other_constants.PD_PORT_TYPE_VALUES[power_role][1],
227 get_value_attribute(
228 other_constants.PD_PORT_TYPE_VALUES[
229 power_role][0]))
230 add_element_to_xml(xml_ele, vif_element_constants.TYPE_C_STATE_MACHINE,
231 other_constants.TYPE_C_STATE_MACHINE_VALUES[
232 power_role][1],
233 get_value_attribute(
234 other_constants.TYPE_C_STATE_MACHINE_VALUES[
235 power_role][0]))
236
237 if dt_constants.SINK_PDOS in node.props:
238 parse_and_add_sink_pdos_to_xml(xml_ele,
239 node.props[dt_constants.SINK_PDOS].val)
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000240
241
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000242def get_source_xml_root(source_xml_file):
243 return ET.parse(source_xml_file).getroot()
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000244
245
246def parse_args():
Jamie McCraeec704442023-01-04 16:08:36 +0000247 parser = argparse.ArgumentParser(allow_abbrev=False)
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000248 parser.add_argument("--edt-pickle", required=True,
249 help="path to read the pickled edtlib.EDT object from")
250 parser.add_argument("--compatible", required=True,
251 help="device tree compatible to be parsed")
252 parser.add_argument("--vif-out", required=True,
253 help="path to write VIF policies to")
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000254 parser.add_argument("--vif-source-xml", required=True,
255 help="XML file containing high level VIF specifications")
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000256 return parser.parse_args()
257
258
Madhurima Paruchuria19d9052023-03-28 19:11:58 +0000259def main():
260 global edtlib
261
262 args = parse_args()
263 with open(args.edt_pickle, 'rb') as f:
264 edt = pickle.load(f)
265 edtlib = inspect.getmodule(edt)
266
267 xml_root = get_root()
268 source_xml_root = get_source_xml_root(args.vif_source_xml)
269 add_elements_to_xml(xml_root, xml_constants.VIF_SPEC_ELEMENTS)
270 add_vif_spec_from_source_to_xml(xml_root, source_xml_root)
271
272 for node in edt.compat2nodes[args.compatible]:
273 xml_ele = add_element_to_xml(xml_root, vif_element_constants.COMPONENT)
274 parse_and_add_component_to_xml(xml_ele, node)
275
276 tree = ET.ElementTree(xml_root)
277 tree.write(args.vif_out, xml_declaration=True,
278 encoding=xml_constants.XML_ENCODING)
279
280
Madhurima Paruchurifa738b02022-10-26 13:34:09 +0000281if __name__ == "__main__":
282 main()