1#!/usr/bin/python3
2# Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
3# SPDX-License-Identifier: Apache-2.0
4
5import os
6import sys
7import yaml
8import argparse
9from pathlib import Path
10
11file_out_head = '''
12/*
13 * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
14 *
15 * SPDX-License-Identifier: Apache-2.0
16 *
17 * NOTE: Autogenerated file using esp_genpinctrl.py
18 */
19
20#ifndef INC_DT_BINDS_PINCTRL_{SOC}_PINCTRL_HAL_H_
21#define INC_DT_BINDS_PINCTRL_{SOC}_PINCTRL_HAL_H_
22
23'''
24
25file_out_tail = '''
26#endif /* INC_DT_BINDS_PINCTRL_{SOC}_PINCTRL_HAL_H_ */
27'''
28
29file_out_path = 'include/dt-bindings/pinctrl/'
30file_out_temp = '{SOC}-pinctrl-temp.h'
31file_out_name = '{SOC}-pinctrl.h'
32file_tmp_abs = ''
33
34line_comment = ''
35
36
37def err(source, msg):
38    global file_tmp_abs
39    os.remove(file_tmp_abs)
40    sys.exit('ERR(' + source + '):' + msg)
41
42
43def get_pin_ios(pins):
44    ios = []
45    for io in pins:
46        if type(io) is int:
47            ios.append(io)
48        elif type(io) is list and io.__len__() == 2:
49            for io_num in range(io[0], 1 + io[1]):
50                ios.append(io_num)
51        else:
52            err('gpio', 'bad type / wrong list size')
53
54    return ios
55
56
57def get_gpios(pin_info):
58    if 'gpio' in pin_info:
59        return get_pin_ios(pin_info.get('gpio'))
60    else:
61        err('gpio', 'missing property')
62
63
64def get_pin_sigi(pin_info):
65    sigi = 'ESP_'
66    if 'sigi' in pin_info:
67        sigi = sigi + pin_info['sigi'].upper()
68    else:
69        sigi = sigi + 'NOSIG'
70
71    return sigi
72
73
74def get_pin_sigo(pin_info):
75    sigo = 'ESP_'
76    if 'sigo' in pin_info:
77        sigo = sigo + pin_info['sigo'].upper()
78    else:
79        sigo = sigo + 'NOSIG'
80
81    return sigo
82
83
84def get_pinmux(dev_name, pin_name, pin_info, io):
85    sigi = get_pin_sigi(pin_info)
86    sigo = get_pin_sigo(pin_info)
87    global line_comment
88
89    pinmux = dev_name.upper() + '_' + pin_name.upper() + '_GPIO' + str(io)
90    pinmux = '#define ' + pinmux + ' \\\n'
91    pinmux = pinmux + '\tESP32_PINMUX(' + str(io) + ', ' + sigi + ', ' + sigo + ')\n\n'
92
93    if bool(line_comment):
94        pinmux = line_comment + pinmux
95        line_comment = ''
96
97    return pinmux
98
99
100def main(pcfg_in):
101    stream = open(pcfg_in, 'r')
102    pcfg_data = yaml.load(stream, Loader=yaml.FullLoader)
103    soc = os.path.basename(pcfg_in).replace('.yml', '')
104
105    file_out_abs = Path(Path(__file__).resolve().parents[3], file_out_path + soc + '-pinctrl.h')
106    global file_tmp_abs
107    file_tmp_abs = Path(Path(__file__).resolve().parents[3], file_out_path + soc + '-pinctrl-temp.h')
108
109    # sorts by dev name, which keeps git
110    # diffs minimal and easily trackable
111    all_data = sorted(pcfg_data.items())
112
113    f = open(file_tmp_abs, 'w')
114    f.write(file_out_head.replace('{SOC}', soc.upper()))
115
116    for (dev_name, dev_info) in all_data:
117
118        # sorts by pin name, which keeps git
119        # diffs minimal and easily trackable
120        dev_info = sorted(dev_info.items())
121
122        for (pin_name, pin_info) in dev_info:
123            global line_comment
124            line_comment = '/* ' + dev_name.upper() + '_' + pin_name.upper() + ' */\n'
125            ios = get_gpios(pin_info)
126            for io in ios:
127                pinmux = get_pinmux(dev_name, pin_name, pin_info, io)
128                f.write(pinmux)
129
130    f.write(file_out_tail.replace('{SOC}', soc.upper()))
131    f.close()
132
133    if os.path.exists(file_out_abs):
134        os.remove(file_out_abs)
135
136    os.rename(file_tmp_abs, file_out_abs)
137
138
139if __name__ == '__main__':
140    parser = argparse.ArgumentParser()
141    parser.add_argument(
142        '-p',
143        '--path',
144        type=Path,
145        required=True,
146        help='Path to target file',
147    )
148    args = parser.parse_args()
149
150    main(args.path)
151