From 0cde66a78040959904d5511b7d0ba0d1f6edf064 Mon Sep 17 00:00:00 2001 From: Rene Straub Date: Sat, 16 Nov 2019 13:17:11 +0100 Subject: [PATCH] nmhw24: configure com/io shield gpios in dtb when a COM/IO shield is detected, its two IOs are given names in the gpio section so that they are accessible from Linux gpio chardev. BugzId: 60150 --- board/nm/nrhw24/board.c | 51 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/board/nm/nrhw24/board.c b/board/nm/nrhw24/board.c index bb34ff3035..6736a3dfc9 100644 --- a/board/nm/nrhw24/board.c +++ b/board/nm/nrhw24/board.c @@ -889,7 +889,7 @@ static void blink_led(int pulses) { const int pulse_width = 400*1000; /* 400ms */ - /* Assumed status led on, indicator off */ + /* Assumes status led on, indicator off */ set_status_led(0, 0); while (pulses) { @@ -1142,6 +1142,54 @@ static void ft_enable_node(void* blob, const char* name) } } +/* + * Modify the name of a gpio in a gpio-line-names string list. + */ +static void ft_set_gpio_name(void *blob, const char* gpio, int pin, const char* name) +{ + int node_ofs = fdt_path_offset(blob, gpio); + if (node_ofs != -1) { + const struct fdt_property* prop = fdt_get_property(blob, node_ofs, "gpio-line-names", NULL); + if (prop != NULL) { + const char* text; + int pos = 0; + int i; + char buffer[512]; + + /* TODO: Determine number of entries from ngpios field */ + + for (i=0; i<32; i++) { + if (i == pin) { + /* Take provided name if GPIO pin is matched */ + text = name; + } + else { + /* Take existing name from strin list */ + (void)fdt_get_string_index(blob, node_ofs, "gpio-line-names", i, &text); + } + /* Add name to new string list */ + strncpy(buffer+pos, text, sizeof(buffer)-pos); + pos += strlen(text) + 1; + printf(" %d %d %s\n", i, pos, text); + } + + (void)fdt_setprop(blob, node_ofs, "gpio-line-names", buffer, pos); + } + } +} + +/* + * Enable digital IOs provided by COM/IO shield in gpio nodes + */ +static void ft_comio_gpios(void *blob) +{ + /* gpio0_7: COM/IO relay output */ + ft_set_gpio_name(blob, "/ocp/gpio@44e07000", 7, "COMIO_OUT0"); + + /* gpio1_8: COM/IO digital input */ + ft_set_gpio_name(blob, "/ocp/gpio@4804c000", 8, "COMIO_IN0"); +} + static void ft_shields(void* blob) { int shield_type = -1; @@ -1149,6 +1197,7 @@ static void ft_shields(void* blob) shield_type = bd_get_shield(0); switch (shield_type) { case SHIELD_COM_IO: + ft_comio_gpios(blob); ft_enable_node(blob, "/netbox_dio_comio"); /* TODO: Should use alias serial0 */ ft_enable_node(blob, "/ocp/serial@44e09000");