122 lines
4.2 KiB
Python
Executable File
122 lines
4.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#coding=utf-8
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
# Copyright (C) 2024 ArtInChip Technology Co., Ltd
|
|
# Author: ArtInChip
|
|
import sys
|
|
import os
|
|
|
|
|
|
def print_error(string):
|
|
print("\t\033[1;31;40m" + string + "\033[0m")
|
|
|
|
|
|
def print_pass(string):
|
|
print("\t\033[1;32;40m" + string + "\033[0m")
|
|
|
|
|
|
def print_warning(string):
|
|
print("\t\033[1;33;40m" + string + "\033[0m")
|
|
|
|
|
|
def check_pinmux(dtbname):
|
|
if not os.path.isfile(dtbname):
|
|
return
|
|
|
|
try:
|
|
import fdt
|
|
except ImportError:
|
|
print_warning("The fdt package is not installed, skip pinmux conflict check.")
|
|
sys.exit()
|
|
|
|
pinmux_conflict = False
|
|
# Each node referenced has a phandle value. The value of pinctrl-0
|
|
# indicates which node it refers to. So, we can find the pinmux node uses
|
|
# through pinctrl-0 value. The key of phandle_dict is phandle value,
|
|
# the value of phandle_dict is node path.
|
|
phandle_dict = {}
|
|
# The key of pinmux_dict is pin index, the value of pinmux_dict is the node
|
|
# which use the pin
|
|
pinmux_dict = {}
|
|
|
|
# open dtb file and parse it
|
|
with open(dtbname, "rb") as f:
|
|
dtb_data = f.read()
|
|
dt1 = fdt.parse_dtb(dtb_data)
|
|
|
|
# Traversing all of the phandle property of DTS, and add it to phandle_dict
|
|
for path, nodes, props in dt1.walk():
|
|
node = dt1.get_node(path)
|
|
phandle = node.get_property("phandle")
|
|
if phandle:
|
|
phandle_dict[phandle.value] = path
|
|
|
|
for path, nodes, props in dt1.walk():
|
|
node = dt1.get_node(path)
|
|
pinctrl = node.get_property("pinctrl-0")
|
|
status = node.get_property("status")
|
|
|
|
if not status or status.value == "okay":
|
|
# check -gpios pinmux
|
|
for i in range(0, len(props)):
|
|
if props[i].name.find("-gpios") != -1:
|
|
gpio_node = dt1.get_node(phandle_dict[props[i].data[0]])
|
|
port = gpio_node.get_property("artinchip,bank-port")
|
|
pin = props[i].data[1]
|
|
pin_index = port.value << 8 | pin
|
|
|
|
if pin_index in pinmux_dict:
|
|
if not pinmux_conflict:
|
|
pinmux_conflict = True
|
|
print_error(props[i].name +\
|
|
" pinmux conflicts with " + \
|
|
pinmux_dict[pin_index])
|
|
# if is PN port, then should set port.value to 13
|
|
if port.value == 6:
|
|
port.value = 13
|
|
print_error("\tThe conflicting pin: P"+ \
|
|
chr(ord('A') + port.value) + str(pin))
|
|
else:
|
|
pinmux_dict[pin_index] = path
|
|
|
|
# check pinctrl-0 pinmux
|
|
if pinctrl:
|
|
for i in range(0, len(pinctrl.data)):
|
|
func_node = dt1.get_node(phandle_dict[pinctrl.data[i]])
|
|
|
|
pinmux = []
|
|
|
|
for pins in func_node.nodes:
|
|
if pins.get_property('pinmux') is not None:
|
|
pinmux += pins.get_property('pinmux')
|
|
|
|
for j in range(0, len(pinmux)):
|
|
port = pinmux[j] >> 16
|
|
pin = pinmux[j] >> 8 & 0xff
|
|
pin_index = pinmux[j] >> 8
|
|
|
|
if pin_index in pinmux_dict:
|
|
if path == pinmux_dict[pin_index]:
|
|
continue
|
|
pinmux_conflict = True
|
|
print_error(node.name + \
|
|
" pinmux conflicts with " + \
|
|
pinmux_dict[pin_index])
|
|
print_error("\tThe conflicting pin: P" + \
|
|
chr(ord('A') + port) + str(pin))
|
|
else:
|
|
pinmux_dict[pin_index] = path
|
|
|
|
if not pinmux_conflict:
|
|
print_pass("No conflict in pinmux")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# check dtb file is exist or not
|
|
if not os.path.isfile(sys.argv[1]):
|
|
print_error(sys.argv[1] + " not exist")
|
|
sys.exit()
|
|
|
|
check_pinmux(sys.argv[1])
|