1#!/usr/bin/env python
2
3"""
4Copyright (c) 2025 Silicon Laboratories Inc.
5
6SPDX-License-Identifier: Apache-2.0
7"""
8import argparse
9import datetime
10import re
11from pathlib import Path
12
13devices = {
14  "xg21": {
15    "bits": "platform/Device/SiliconLabs/EFR32MG21/Include/efr32mg21_iadc.h",
16    "values": {
17      "SUPPLY": {
18        0: "AVDD",
19        1: "IOVDD",
20        4: "DVDD",
21        7: "DECOUPLE"
22      }
23    }
24  },
25  "xg22": {
26    "bits": "platform/Device/SiliconLabs/EFR32BG22/Include/efr32bg22_iadc.h",
27    "values": {
28      "SUPPLY": {
29        0: "AVDD",
30        1: "IOVDD",
31        4: "DVDD",
32        7: "DECOUPLE"
33      }
34    }
35  },
36  "xg23": {
37    "bits": "platform/Device/SiliconLabs/EFR32FG23/Include/efr32fg23_iadc.h",
38    "values": {
39      "SUPPLY": {
40        0: "AVDD",
41        1: "IOVDD",
42        4: "DVDD",
43        7: "DECOUPLE"
44      }
45    }
46  },
47  "xg24": {
48    "bits": "platform/Device/SiliconLabs/EFR32MG24/Include/efr32mg24_iadc.h",
49    "values": {
50      "SUPPLY": {
51        0: "AVDD",
52        1: "IOVDD",
53        4: "DVDD",
54        7: "DECOUPLE"
55      }
56    }
57  },
58  "xg27": {
59    "bits": "platform/Device/SiliconLabs/EFR32BG27/Include/efr32bg27_iadc.h",
60    "values": {
61      "SUPPLY": {
62        0: "AVDD",
63        1: "IOVDD",
64        2: "VBAT",
65        4: "DVDD",
66        7: "DECOUPLE"
67      }
68    }
69  },
70  "xg29": {
71    "bits": "platform/Device/SiliconLabs/EFR32BG29/Include/efr32bg29_iadc.h",
72    "values": {
73      "SUPPLY": {
74        0: "AVDD",
75        1: "IOVDD",
76        2: "VBAT",
77        4: "DVDD",
78        7: "DECOUPLE"
79      }
80    }
81  }
82}
83
84alias = {
85  "PADANA0": "AIN0",
86  "PADANA1": "AIN1",
87  "PADANA2": "AIN2",
88  "PADANA3": "AIN3",
89}
90
91def insert(values, key, val):
92  if key in values:
93    assert values[key] == val, f"{key} = {values[key]} from a previous device, new value = {val}"
94  else:
95    values[key] = val
96
97
98if __name__ == "__main__":
99  parser = argparse.ArgumentParser(description="Generate headers for ADC for Series 2 "
100                                   "devices. The headers are used from DeviceTree, and represent "
101                                   "every ADC input as a DT compatible macro.")
102  parser.add_argument("--out", "-o", type=Path, default=Path(__file__).parent / "out",
103                      help="Output directory. Defaults to the directory ./out/ relative to the "
104                      "script. Set to $ZEPHYR_BASE/include/zephyr/dt-bindings/adc/ "
105                      "to directly generate output into the expected location within the Zephyr "
106                      "main tree.")
107  parser.add_argument("--sdk", "-s", type=Path, default=Path(__file__).parent.parent / "simplicity_sdk",
108                      help="Path to Simplicity SDK to extract data from. Defaults to the directory "
109                       "../simplicity_sdk relative to the script.")
110  args = parser.parse_args()
111
112  args.out.mkdir(exist_ok=True)
113
114  values = {}
115  for device, data_source in devices.items():
116    print(f"Parse ADC data for {device}")
117
118    with (args.sdk / data_source["bits"]).open() as f:
119      for line in f:
120        if m := re.match(r"#define _IADC_SINGLE_PORT(POS|NEG)_([^\s]+)\s+(0x[0-9A-F]*)UL", line):
121          port = m.group(2)
122          port_base = int(m.group(3), base=16) * 16
123          if port in ["MASK", "DEFAULT"]:
124             continue
125          if port in data_source["values"]:
126            for value, key in data_source["values"][port].items():
127              insert(values, key, port_base + value)
128          elif port.startswith("PORT"):
129            for pin in range(16):
130              insert(values, f"P{port[4]}{pin}", port_base + pin)
131          else:
132            insert(values, alias.get(port,port), port_base)
133
134  file = [
135    "/*",
136    f" * Copyright (c) {datetime.date.today().year} Silicon Laboratories Inc.",
137    " *",
138    " * SPDX-License-Identifier: Apache-2.0",
139    " *",
140    f" * This file was generated by the script {Path(__file__).name} in the hal_silabs module.",
141    " * Do not manually edit.",
142    " */",
143    "",
144    f"#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ADC_SILABS_ADC_H_",
145    f"#define ZEPHYR_INCLUDE_DT_BINDINGS_ADC_SILABS_ADC_H_",
146    "",
147  ]
148
149  max_key = max(len(k) for k in values)
150  for k, v in sorted(values.items(), key=lambda i: (i[1],i[0])):
151    file.append(f"#define IADC_INPUT_{k}{' ' * (max_key - len(k) + 1)}0x{v:x}")
152
153  file.append("")
154  file.append(f"#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ADC_SILABS_ADC_H_ */")
155  file.append("")
156
157  outfile = args.out / f"silabs-adc.h"
158  outfile.write_text("\n".join(file))
159