mirror of https://github.com/OpenIPC/firmware.git
748 lines
19 KiB
Diff
748 lines
19 KiB
Diff
diff -drupN a/scripts/dtc/updatetree.c b/scripts/dtc/updatetree.c
|
|
--- a/scripts/dtc/updatetree.c 1970-01-01 03:00:00.000000000 +0300
|
|
+++ b/scripts/dtc/updatetree.c 2022-06-12 05:28:14.000000000 +0300
|
|
@@ -0,0 +1,743 @@
|
|
+#include "updatetree.h"
|
|
+
|
|
+extern struct script *script;
|
|
+
|
|
+/*public functions */
|
|
+int of_prop_string_count(const char *prop_val, int prop_len)
|
|
+{
|
|
+ int l = 0, i = 0;
|
|
+ const char *p, *end;
|
|
+
|
|
+ p = prop_val;
|
|
+ end = p + prop_len;
|
|
+
|
|
+ for (i = 0; p < end; i++, p += l) {
|
|
+ l = strnlen(p, end - p) + 1;
|
|
+ if (p + l > end)
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return i <= 0 ? -1 : i;
|
|
+}
|
|
+
|
|
+const char *of_prop_next_string(struct property *prop, const char *cur)
|
|
+{
|
|
+ const char *curv = cur;
|
|
+
|
|
+ if (!prop)
|
|
+ return NULL;
|
|
+
|
|
+ if (!cur)
|
|
+ return prop->val.val;
|
|
+
|
|
+ curv += strlen(cur) + 1;
|
|
+ if (curv >= prop->val.val + prop->val.len)
|
|
+ return NULL;
|
|
+
|
|
+ return curv;
|
|
+}
|
|
+
|
|
+int sunxi_get_propval(struct node *node, const char *name)
|
|
+{
|
|
+ unsigned int value;
|
|
+ struct property *prop;
|
|
+ cell_t *info = NULL;
|
|
+
|
|
+ prop = get_property(node, name);
|
|
+ if (prop) {
|
|
+ info = (cell_t *)prop->val.val;
|
|
+ value = fdt32_to_cpu(*info++);
|
|
+ return value;
|
|
+ }
|
|
+
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+int sunxi_gpio_to_name(int port, int port_num, char *name)
|
|
+{
|
|
+ int index;
|
|
+
|
|
+ if (!name)
|
|
+ return -1;
|
|
+
|
|
+ if ((port*32+port_num) >= 1024) {
|
|
+ /* axp gpio name like this : GPIO0/GPIO1/.. */
|
|
+ index = (port-1)*32+port_num - 1024;
|
|
+ sprintf(name, "GPIO%d", index);
|
|
+ } else {
|
|
+ /* sunxi gpio name like this : PA0/PA1/PB0 */
|
|
+ sprintf(name, "P%c%d", ('A' + (port-1)), port_num);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*these functions mainly to process pin subkey*/
|
|
+#define PL_BASE (352)
|
|
+#define AXP_BASE (1024)
|
|
+
|
|
+void sunxi_dt_update_gpio_group(struct dt_info *dti,
|
|
+ struct node *node,
|
|
+ struct script_entry *ep,
|
|
+ struct script_gpio_entry *entry)
|
|
+{
|
|
+ char *pinctrl_name = NULL, *string;
|
|
+ int val32, gpio_index, temp_val, phandle;
|
|
+ char *axp_pin_name[] = {"axp_pio", "axp_gpio0", "axp_gpio1"};
|
|
+ bool axp_pin = false;
|
|
+ int i;
|
|
+
|
|
+ struct data d;
|
|
+ struct property *prop;
|
|
+ struct node *pinctrl_node;
|
|
+
|
|
+ prop = get_property(node, ep->name);
|
|
+ if (prop)
|
|
+ delete_property(prop);
|
|
+
|
|
+ gpio_index = (entry->port - 1) * 32 + entry->port_num;
|
|
+ if (gpio_index < PL_BASE)
|
|
+ pinctrl_name = "pio";
|
|
+ else if (gpio_index < AXP_BASE && gpio_index >= PL_BASE)
|
|
+ pinctrl_name = "r_pio";
|
|
+ else
|
|
+ axp_pin = true;
|
|
+
|
|
+ if (axp_pin) {
|
|
+ for (i = 0; i < 3; i++) {
|
|
+ pinctrl_name = axp_pin_name[i];
|
|
+ pinctrl_node = sunxi_get_node(dti->dt, pinctrl_name);
|
|
+ if (pinctrl_node)
|
|
+ break;
|
|
+ }
|
|
+ } else {
|
|
+ pinctrl_node = sunxi_get_node(dti->dt, pinctrl_name);
|
|
+ }
|
|
+
|
|
+ if (!pinctrl_node) {
|
|
+ printf("warning:can't find gpio node %s\n", pinctrl_name);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ string = malloc(7 * sizeof(unsigned int));
|
|
+ /*set gpio control */
|
|
+ phandle = get_node_phandle(dti->dt, pinctrl_node);
|
|
+ val32 = cpu_to_fdt32(phandle);
|
|
+ memcpy(string, (char *)&val32, sizeof(val32));
|
|
+
|
|
+ /*set gpio bank */
|
|
+ val32 = cpu_to_fdt32(entry->port-1);
|
|
+ memcpy(string + 1 * sizeof(val32), (char *)&val32, sizeof(val32));
|
|
+
|
|
+ /*set gpio bank index */
|
|
+ val32 = cpu_to_fdt32(entry->port_num);
|
|
+ memcpy(string + 2 * sizeof(val32), (char *)&val32, sizeof(val32));
|
|
+
|
|
+ /*set gpio mul */
|
|
+ val32 = cpu_to_fdt32(entry->data[0]);
|
|
+ memcpy(string + 3 * sizeof(val32), (char *)&val32, sizeof(val32));
|
|
+
|
|
+ /*set gpio pull */
|
|
+ temp_val = entry->data[1] < 0 ? 0xFFFFFFFF : entry->data[1];
|
|
+ val32 = cpu_to_fdt32(temp_val);
|
|
+ memcpy(string + 4 * sizeof(val32), (char *)&val32, sizeof(val32));
|
|
+
|
|
+ /*set gpio drive */
|
|
+ temp_val = entry->data[2] < 0 ? 0xFFFFFFFF : entry->data[2];
|
|
+ val32 = cpu_to_fdt32(temp_val);
|
|
+ memcpy(string + 5 * sizeof(val32), (char *)&val32, sizeof(val32));
|
|
+
|
|
+ /*set gpio data */
|
|
+ temp_val = entry->data[3] < 0 ? 0xFFFFFFFF : entry->data[3];
|
|
+ val32 = cpu_to_fdt32(temp_val);
|
|
+ memcpy(string + 6 * sizeof(val32), (char *)&val32, sizeof(val32));
|
|
+
|
|
+ d = data_copy_mem(string, 7 * sizeof(unsigned int));
|
|
+ prop = build_property(ep->name, d);
|
|
+ add_property(node, prop);
|
|
+ free(string);
|
|
+}
|
|
+
|
|
+int sunxi_dt_init_pinconf_prop(struct script_section *section,
|
|
+ struct dt_info *dti,
|
|
+ struct node *node,
|
|
+ int sleep_state)
|
|
+{
|
|
+ int i, len, phandle;
|
|
+ cell_t *cp = NULL;
|
|
+
|
|
+ struct list_entry *o;
|
|
+ struct script_entry *ep;
|
|
+ struct script_gpio_entry *entry;
|
|
+
|
|
+ struct data d0;
|
|
+ struct node *p_node = NULL;
|
|
+ struct property *prop;
|
|
+ struct property *pinctrl;
|
|
+
|
|
+ /*remove pin config */
|
|
+ for_each_entry_in_section(section->entries, o) {
|
|
+ ep = container_of(o, struct script_entry, entries);
|
|
+ entry = container_of(ep, struct script_gpio_entry, entry);
|
|
+
|
|
+ if (entry->data[0] == 2 || entry->data[0] == 3 ||
|
|
+ entry->data[0] == 4 || entry->data[0] == 5 ||
|
|
+ entry->data[0] == 7) {
|
|
+ if (!sleep_state)
|
|
+ prop = get_property(node, "pinctrl-0");
|
|
+ else
|
|
+ prop = get_property(node, "pinctrl-1");
|
|
+
|
|
+ if (prop) {
|
|
+ len = prop->val.len/sizeof(unsigned int);
|
|
+ cp = (cell_t *)prop->val.val;
|
|
+ for (i = 0; i < len; i++) {
|
|
+ phandle = fdt32_to_cpu(*cp++);
|
|
+ p_node = get_node_by_phandle(dti->dt, phandle);
|
|
+ delete_node(p_node);
|
|
+ }
|
|
+ delete_property(prop);
|
|
+ }
|
|
+
|
|
+ /* build pinctrl-0 property */
|
|
+ d0 = data_copy_mem(NULL, 0);
|
|
+ if (!sleep_state)
|
|
+ pinctrl = build_property("pinctrl-0", d0);
|
|
+ else
|
|
+ pinctrl = build_property("pinctrl-1", d0);
|
|
+ add_property(node, pinctrl);
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+
|
|
+}
|
|
+
|
|
+cell_t sunxi_dt_add_new_node_to_pinctrl(struct node *pinctrl_node,
|
|
+ const char *dev_name,
|
|
+ const char *pname,
|
|
+ char *gpio_name,
|
|
+ int gpio_value[],
|
|
+ struct dt_info *dti)
|
|
+{
|
|
+ cell_t phandle;
|
|
+ int i, value_32, len, str_len;
|
|
+ char *label, node_name[32];
|
|
+ struct data d;
|
|
+ struct node *child, *temp_node;
|
|
+ struct property *prop;
|
|
+ child = build_node(NULL, NULL);
|
|
+
|
|
+ /* set label */
|
|
+ str_len = strlen(dev_name)+strlen("_pins_")+2;
|
|
+ label = malloc(str_len);
|
|
+ strcpy(label, dev_name);
|
|
+ strcat(label, "_pins_");
|
|
+
|
|
+ for (i = 0; i < 8; i++) {
|
|
+ label[str_len-2] = (char)(i+'a');
|
|
+ label[str_len-1] = '\0';
|
|
+ temp_node = sunxi_get_node(dti->dt, label);
|
|
+ if (temp_node)
|
|
+ continue;
|
|
+ else
|
|
+ break;
|
|
+ }
|
|
+ add_label(&child->labels, label);
|
|
+
|
|
+ /*set node name*/
|
|
+ str_len = strlen(dev_name)+2;
|
|
+ strcpy(node_name, dev_name);
|
|
+ strcat(node_name, "@");
|
|
+ for (i = 0; i < 8; i++) {
|
|
+ node_name[str_len-1] = (char)(i+'0');
|
|
+ node_name[str_len] = '\0';
|
|
+ temp_node = get_subnode(pinctrl_node, node_name);
|
|
+ if (temp_node)
|
|
+ continue;
|
|
+ else
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* set node name and phandle*/
|
|
+ child->name = xstrdup(node_name);
|
|
+
|
|
+ /* set fullpath */
|
|
+ child->fullpath = join_path(pinctrl_node->fullpath, child->name);
|
|
+
|
|
+ /*set phandle*/
|
|
+ phandle = get_node_phandle(dti->dt, child);
|
|
+ add_child(pinctrl_node, child);
|
|
+
|
|
+ /*add property of pins */
|
|
+ d = data_copy_mem(gpio_name, strlen(gpio_name) + 1);
|
|
+ prop = build_property("allwinner,pins", d);
|
|
+ add_property(child, prop);
|
|
+
|
|
+ d = data_copy_mem(dev_name, strlen(dev_name) + 1);
|
|
+ prop = build_property("allwinner,function", d);
|
|
+ add_property(child, prop);
|
|
+
|
|
+ d = data_copy_mem(pname, strlen(pname) + 1);
|
|
+ prop = build_property("allwinner,pname", d);
|
|
+ add_property(child, prop);
|
|
+
|
|
+ value_32 = cpu_to_fdt32(gpio_value[0]);
|
|
+ len = sizeof(unsigned int);
|
|
+ d = data_copy_mem((char *)&value_32, len);
|
|
+ prop = build_property("allwinner,muxsel", d);
|
|
+ add_property(child, prop);
|
|
+
|
|
+ value_32 = cpu_to_fdt32(gpio_value[1]);
|
|
+ len = sizeof(unsigned int);
|
|
+ d = data_copy_mem((char *)&value_32, len);
|
|
+ prop = build_property("allwinner,pull", d);
|
|
+ add_property(child, prop);
|
|
+
|
|
+ value_32 = cpu_to_fdt32(gpio_value[2]);
|
|
+ len = sizeof(unsigned int);
|
|
+ d = data_copy_mem((char *)&value_32, len);
|
|
+ prop = build_property("allwinner,drive", d);
|
|
+ add_property(child, prop);
|
|
+
|
|
+ value_32 = cpu_to_fdt32(gpio_value[3]);
|
|
+ len = sizeof(unsigned int);
|
|
+ d = data_copy_mem((char *)&value_32, len);
|
|
+ prop = build_property("allwinner,data", d);
|
|
+ add_property(child, prop);
|
|
+
|
|
+ return phandle;
|
|
+
|
|
+}
|
|
+int insert_pinconf_node(const char *section_name,
|
|
+ struct dt_info *dti,
|
|
+ struct node *node,
|
|
+ struct script_entry *ep,
|
|
+ const char *prop_name)
|
|
+{
|
|
+ char gpio_name[32], *string;
|
|
+ cell_t *cp, *info;
|
|
+ int muxsel = 0, pull = 0, data = 0, drive = 0;
|
|
+ int i, ret, len, gpio_value[4], phandle, phandle_count;
|
|
+
|
|
+ struct node *pin_node;
|
|
+ struct property *prop, *prop_temp;
|
|
+ struct script_gpio_entry *entry;
|
|
+
|
|
+ entry = container_of(ep, struct script_gpio_entry, entry);
|
|
+ ret = sunxi_gpio_to_name(entry->port, entry->port_num, gpio_name);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ gpio_value[0] = entry->data[0];
|
|
+ gpio_value[1] = entry->data[1] < 0 ? 0xFFFFFFFF : entry->data[1];
|
|
+ gpio_value[2] = entry->data[2] < 0 ? 0xFFFFFFFF : entry->data[2];
|
|
+ gpio_value[3] = entry->data[3] < 0 ? 0xFFFFFFFF : entry->data[3];
|
|
+
|
|
+ prop = get_property(node, prop_name);
|
|
+ phandle_count = prop->val.len/sizeof(unsigned int);
|
|
+ cp = (cell_t *)prop->val.val;
|
|
+
|
|
+ for (i = 0; i < phandle_count; i++) {
|
|
+ phandle = fdt32_to_cpu(*cp++);
|
|
+ pin_node = get_node_by_phandle(dti->dt, phandle);
|
|
+
|
|
+ if (pin_node) {
|
|
+ /* if find a pinctrl node, check config*/
|
|
+ prop_temp = get_property(pin_node, "allwinner,muxsel");
|
|
+ if (prop_temp) {
|
|
+ info = (cell_t *)prop_temp->val.val;
|
|
+ muxsel = fdt32_to_cpu(*info++);
|
|
+ }
|
|
+ prop_temp = get_property(pin_node, "allwinner,pull");
|
|
+ if (prop_temp) {
|
|
+ info = (cell_t *)prop_temp->val.val;
|
|
+ pull = fdt32_to_cpu(*info++);
|
|
+ }
|
|
+ prop_temp = get_property(pin_node, "allwinner,drive");
|
|
+ if (prop_temp) {
|
|
+ info = (cell_t *)prop_temp->val.val;
|
|
+ drive = fdt32_to_cpu(*info++);
|
|
+ }
|
|
+ prop_temp = get_property(pin_node, "allwinner,data");
|
|
+ if (prop_temp) {
|
|
+ info = (cell_t *)prop_temp->val.val;
|
|
+ data = fdt32_to_cpu(*info++);
|
|
+ }
|
|
+
|
|
+ if (gpio_value[0] == muxsel && gpio_value[1] == pull &&
|
|
+ gpio_value[2] == drive && gpio_value[3] == data) {
|
|
+ prop_temp = get_property(pin_node, "allwinner,pins");
|
|
+ if (prop_temp) {
|
|
+ len = prop_temp->val.len + strlen(gpio_name) + 1;
|
|
+ string = malloc(len);
|
|
+ memcpy(string, prop_temp->val.val, prop_temp->val.len);
|
|
+ memcpy(string + prop_temp->val.len, gpio_name, strlen(gpio_name));
|
|
+ string[len-1] = '\0';
|
|
+ free(prop_temp->val.val);
|
|
+ prop_temp->val.val = malloc(len);
|
|
+ memcpy(prop_temp->val.val, string, len);
|
|
+ prop_temp->val.len = len;
|
|
+ free(string);
|
|
+ }
|
|
+
|
|
+ prop_temp = get_property(pin_node, "allwinner,pname");
|
|
+ if (prop_temp) {
|
|
+ len = prop_temp->val.len + strlen(ep->name) + 1;
|
|
+ string = malloc(len);
|
|
+ memcpy(string, prop_temp->val.val, prop_temp->val.len);
|
|
+ memcpy(string + prop_temp->val.len, ep->name, strlen(ep->name));
|
|
+ string[len-1] = '\0';
|
|
+ free(prop_temp->val.val);
|
|
+ prop_temp->val.val = malloc(len);
|
|
+ memcpy(prop_temp->val.val, string, len);
|
|
+ prop_temp->val.len = len;
|
|
+ free(string);
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+void create_pinconf_node(const char *section_name,
|
|
+ struct dt_info *dti,
|
|
+ struct node *node,
|
|
+ struct script_entry *ep,
|
|
+ struct property *prop)
|
|
+{
|
|
+ int value[4], phandle;
|
|
+ char gpio_name[32], *propname;
|
|
+ struct node *pinctrl = NULL;
|
|
+ struct data d_pinctrl_x;
|
|
+ struct property *pinctrl_x;
|
|
+ struct script_gpio_entry *entry;
|
|
+
|
|
+ entry = container_of(ep, struct script_gpio_entry, entry);
|
|
+ sunxi_gpio_to_name(entry->port, entry->port_num, gpio_name);
|
|
+ value[0] = entry->data[0];
|
|
+ value[1] = entry->data[1] < 0 ? 0xFFFFFFFF : entry->data[1];
|
|
+ value[2] = entry->data[2] < 0 ? 0xFFFFFFFF : entry->data[2];
|
|
+ value[3] = entry->data[3] < 0 ? 0xFFFFFFFF : entry->data[3];
|
|
+
|
|
+ if (entry->port * 32 < PL_BASE)
|
|
+ pinctrl = sunxi_get_node(dti->dt, "pio");
|
|
+ else if (entry->port * 32 >= PL_BASE && entry->port < AXP_BASE)
|
|
+ pinctrl = sunxi_get_node(dti->dt, "r_pio");
|
|
+
|
|
+ phandle = sunxi_dt_add_new_node_to_pinctrl(pinctrl, section_name, ep->name, gpio_name, value, dti);
|
|
+ if (phandle) {
|
|
+ d_pinctrl_x = data_append_cell(prop->val, phandle);
|
|
+ propname = malloc(strlen(prop->name));
|
|
+ strcpy(propname, prop->name);
|
|
+ delete_property(prop);
|
|
+ pinctrl_x = build_property(propname, d_pinctrl_x);
|
|
+ add_property(node, pinctrl_x);
|
|
+ }
|
|
+}
|
|
+
|
|
+void sunxi_dt_update_pin_group_sleep(const char *section_name,
|
|
+ struct dt_info *dti,
|
|
+ struct node *node,
|
|
+ struct script_entry *ep)
|
|
+{
|
|
+ int ret = 0;
|
|
+ char gpio_name[32] = {0};
|
|
+ struct property *prop;
|
|
+ struct script_gpio_entry *entry;
|
|
+
|
|
+ entry = container_of(ep, struct script_gpio_entry, entry);
|
|
+ sunxi_gpio_to_name(entry->port, entry->port_num, gpio_name);
|
|
+ prop = get_property(node, "pinctrl-1");
|
|
+
|
|
+ ret = insert_pinconf_node(section_name, dti, node, ep, "pinctrl-1");
|
|
+ if (ret)
|
|
+ create_pinconf_node(section_name, dti, node, ep, prop);
|
|
+}
|
|
+
|
|
+
|
|
+void sunxi_dt_update_pin_group_default(const char *section_name,
|
|
+ struct dt_info *dti,
|
|
+ struct node *node,
|
|
+ struct script_entry *ep)
|
|
+{
|
|
+ int ret = 0;
|
|
+ char gpio_name[32] = {0};
|
|
+
|
|
+ struct property *prop;
|
|
+ struct script_gpio_entry *entry;
|
|
+
|
|
+ entry = container_of(ep, struct script_gpio_entry, entry);
|
|
+ sunxi_gpio_to_name(entry->port, entry->port_num, gpio_name);
|
|
+ prop = get_property(node, "pinctrl-0");
|
|
+
|
|
+ ret = insert_pinconf_node(section_name, dti, node, ep, "pinctrl-0");
|
|
+ if (ret)
|
|
+ create_pinconf_node(section_name, dti, node, ep, prop);
|
|
+}
|
|
+
|
|
+/*end process pinconf */
|
|
+
|
|
+void sunxi_dt_update_propval_cells(const char *section_name,
|
|
+ struct script_entry *ep,
|
|
+ struct node *node)
|
|
+{
|
|
+ int len;
|
|
+ unsigned int value_32;
|
|
+ char temp[32], *string;
|
|
+ struct data d;
|
|
+ struct property *prop;
|
|
+ struct script_single_entry *entry;
|
|
+
|
|
+ entry = container_of(ep, struct script_single_entry, entry);
|
|
+ strcpy(temp, section_name);
|
|
+ strcat(temp, "_used");
|
|
+
|
|
+ if (strcmp(ep->name, "used") == 0 || strcmp(ep->name, temp) == 0) {
|
|
+
|
|
+ string = entry->value ? "okay" : "disabled";
|
|
+ len = strlen(string) + 1;
|
|
+ prop = get_property(node, "status");
|
|
+
|
|
+ if (prop) {
|
|
+ free(prop->val.val);
|
|
+ prop->val.val = malloc(len);
|
|
+ strcpy(prop->val.val, string);
|
|
+ prop->val.len = len;
|
|
+ } else {
|
|
+ d = data_copy_mem(string, len);
|
|
+ prop = build_property("status", d);
|
|
+ add_property(node, prop);
|
|
+ }
|
|
+ } else {
|
|
+ value_32 = cpu_to_fdt32(entry->value);
|
|
+ len = sizeof(unsigned int);
|
|
+ prop = get_property(node, ep->name);
|
|
+
|
|
+ if (prop) {
|
|
+ free(prop->val.val);
|
|
+ prop->val.val = malloc(len);
|
|
+ memcpy(prop->val.val, &value_32, len);
|
|
+ prop->val.len = len;
|
|
+ } else {
|
|
+ d = data_copy_mem((char *)&value_32, len);
|
|
+ prop = build_property(ep->name, d);
|
|
+ add_property(node, prop);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void sunxi_dt_update_propval_string(const char *section_name,
|
|
+ struct script_entry *ep,
|
|
+ struct node *node)
|
|
+{
|
|
+ int len;
|
|
+ char *string;
|
|
+
|
|
+ struct data d;
|
|
+ struct property *prop;
|
|
+ struct script_string_entry *entry;
|
|
+
|
|
+ /*SCRIPT_VALUE_TYPE_STRING*/
|
|
+ entry = container_of(ep, struct script_string_entry, entry);
|
|
+ string = entry->string;
|
|
+ len = entry->l;
|
|
+
|
|
+ prop = get_property(node, ep->name);
|
|
+ if (prop) {
|
|
+ free(prop->val.val);
|
|
+ prop->val.val = malloc(len);
|
|
+ strcpy(prop->val.val, string);
|
|
+ prop->val.len = len;
|
|
+ } else {
|
|
+ d = data_copy_mem(string, len);
|
|
+ prop = build_property(ep->name, d);
|
|
+ add_property(node, prop);
|
|
+ }
|
|
+}
|
|
+
|
|
+void sunxi_dt_update_propval_empty(const char *section_name,
|
|
+ struct script_entry *ep,
|
|
+ struct node *node)
|
|
+{
|
|
+ struct data d = {0};
|
|
+ struct property *prop, *temp;
|
|
+ struct script_null_entry *entry;
|
|
+
|
|
+ /* SCRIPT_VALUE_TYPE_STRING */
|
|
+ entry = container_of(ep, struct script_null_entry, entry);
|
|
+
|
|
+ prop = get_property(node, entry->entry.name);
|
|
+ if (prop)
|
|
+ delete_property(prop);
|
|
+
|
|
+ temp = build_property(entry->entry.name, d);
|
|
+ add_property(node, temp);
|
|
+}
|
|
+
|
|
+void sunxi_dt_update_propval_gpio(const char *section_name,
|
|
+ struct script_entry *ep,
|
|
+ struct node *node,
|
|
+ struct dt_info *dti,
|
|
+ int sleep_state)
|
|
+{
|
|
+ struct script_gpio_entry *entry;
|
|
+ entry = container_of(ep, struct script_gpio_entry, entry);
|
|
+
|
|
+ switch (entry->data[0]) {
|
|
+ case 0:
|
|
+ case 1:
|
|
+ case 6:
|
|
+ sunxi_dt_update_gpio_group(dti, node, ep, entry);
|
|
+ break;
|
|
+ case 2:
|
|
+ case 3:
|
|
+ case 4:
|
|
+ case 5:
|
|
+ case 7:
|
|
+ if (sleep_state)
|
|
+ sunxi_dt_update_pin_group_sleep(section_name, dti, node, ep);
|
|
+ else
|
|
+ sunxi_dt_update_pin_group_default(section_name, dti, node, ep);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+}
|
|
+struct node *sunxi_get_node(struct node *tree, const char *string)
|
|
+{
|
|
+ struct node *nd;
|
|
+
|
|
+ nd = get_node_by_label(tree, string);
|
|
+ if (!nd)
|
|
+ nd = get_node_by_type(tree, string);
|
|
+
|
|
+ return nd;
|
|
+}
|
|
+
|
|
+int sunxi_build_new_node(struct dt_info *dti, char pnode_name[], char node_name[])
|
|
+{
|
|
+ char *label;
|
|
+ struct node *child, *parent;
|
|
+
|
|
+ parent = sunxi_get_node(dti->dt, pnode_name);
|
|
+ child = build_node(NULL, NULL);
|
|
+ if (!child)
|
|
+ printf("build node faile[%s]\n", node_name);
|
|
+
|
|
+ label = xstrdup(node_name);
|
|
+ add_label(&child->labels, label);
|
|
+ child->name = xstrdup(node_name);
|
|
+ child->fullpath = join_path(parent->fullpath, child->name);
|
|
+ add_child(parent, child);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int process_mainkey(char *mainkey, char parent_name[], char child_name[], int *state)
|
|
+{
|
|
+ char *delim1 = "/";
|
|
+ char *delim2 = "_suspend";
|
|
+ char *buf = strstr(mainkey, delim1);
|
|
+ char *temp_buf;
|
|
+
|
|
+ if (buf != NULL) {
|
|
+ sscanf(mainkey, "%31[^/]/%31[^@]", parent_name, child_name);
|
|
+ } else {
|
|
+ strcpy(parent_name, "soc");
|
|
+ strcpy(child_name, mainkey);
|
|
+ }
|
|
+
|
|
+ temp_buf = strstr(child_name, delim2);
|
|
+ if (temp_buf != NULL) {
|
|
+ memset(temp_buf, 0, strlen(temp_buf));
|
|
+ *state = 1;
|
|
+ } else {
|
|
+ *state = 0;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int dt_update_source(const char *fexname, FILE *f, struct dt_info *dti)
|
|
+{
|
|
+
|
|
+ int ret = 0;
|
|
+ int sleep_state = false;
|
|
+ char p_key[32] = {0};
|
|
+ char c_key[32] = {0};
|
|
+
|
|
+ struct node *sub_node, *parent_node;
|
|
+ struct list_entry *sec_list, *o;
|
|
+ struct script_section *section;
|
|
+ struct script_entry *ep;
|
|
+ struct property *device_type_prop;
|
|
+
|
|
+ /*for build new device type property.*/
|
|
+ struct data d;
|
|
+ struct property *new_prop;
|
|
+
|
|
+ ret = script_parse(fexname);
|
|
+ if (ret) {
|
|
+ printf("parser sys_config.fex file failed.\n");
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ for_each_section_in_list(script->sections, sec_list) {
|
|
+ section = container_of(sec_list,
|
|
+ struct script_section, sections);
|
|
+ /*
|
|
+ * here mainly deal with section name like parent_key/child_key
|
|
+ */
|
|
+ process_mainkey(section->name, p_key, c_key, &sleep_state);
|
|
+ printf("p=%s c=%s state=%d\n", p_key, c_key, sleep_state);
|
|
+
|
|
+ parent_node = sunxi_get_node(dti->dt, p_key);
|
|
+ if (!parent_node) {
|
|
+ printf("[SCRIPT_TO_DTS]Can not get parent node.\n");
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ sub_node = sunxi_get_node(dti->dt, c_key);
|
|
+ if (!sub_node) {
|
|
+ sunxi_build_new_node(dti, p_key, c_key);
|
|
+ sub_node = sunxi_get_node(dti->dt, c_key);
|
|
+ }
|
|
+
|
|
+ device_type_prop = get_property(sub_node, "device_type");
|
|
+ if (!device_type_prop) {
|
|
+ d = data_copy_mem(c_key, strlen(c_key)+1);
|
|
+ new_prop = build_property("device_type", d);
|
|
+ add_property(sub_node, new_prop);
|
|
+ }
|
|
+
|
|
+ sunxi_dt_init_pinconf_prop(section, dti, sub_node, sleep_state);
|
|
+ for_each_entry_in_section(section->entries, o) {
|
|
+ ep = container_of(o, struct script_entry, entries);
|
|
+ switch (ep->type) {
|
|
+ case 1:
|
|
+ case 2:
|
|
+ sunxi_dt_update_propval_cells(c_key, ep, sub_node);
|
|
+ break;
|
|
+ case 3:
|
|
+ sunxi_dt_update_propval_string(c_key, ep, sub_node);
|
|
+ break;
|
|
+ case 5:
|
|
+ sunxi_dt_update_propval_gpio(c_key, ep, sub_node, dti, sleep_state);
|
|
+ break;
|
|
+ case 6:
|
|
+ /*empty property */
|
|
+ sunxi_dt_update_propval_empty(c_key, ep, sub_node);
|
|
+ break;
|
|
+ default:
|
|
+ printf("input type error.\n");
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|