hw25: handle gpio variants

This commit is contained in:
Rene Straub 2020-12-02 08:11:59 +01:00 committed by Gitea
parent 24c0d5539e
commit 3b18df525d
1 changed files with 81 additions and 10 deletions

View File

@ -1205,6 +1205,63 @@ 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);
int gpios = -1;
const char* text;
int pos = 0;
int i;
char buffer[512];
if (node_ofs == -1) {
printf("Can't find node %s\n", gpio);
goto end;
}
/* get number of IOs in node */
gpios = fdt_getprop_u32_default_node(blob, node_ofs, 0, "ngpios", -1);
if (gpios == -1 || gpios > 64) {
printf("Illegal number of gpios %d\n", gpios);
goto end;
}
/* get string array with names */
const struct fdt_property* prop = fdt_get_property(blob, node_ofs, "gpio-line-names", NULL);
if (prop == NULL) {
goto end;
}
/* modify given name */
for (i=0; i<gpios; i++) {
if (i == pin) {
/* Take provided name if GPIO pin is matched */
text = name;
}
else {
/* Take existing name from string list */
(void)fdt_get_string_index(blob, node_ofs, "gpio-line-names", i, &text);
}
/* Add name to new string list */
if ((pos + strlen(text) + 1) < sizeof(buffer)) {
strncpy(buffer+pos, text, sizeof(buffer)-pos);
pos += strlen(text) + 1;
}
else {
printf("ft_set_gpio_name() Buffer too small\n");
goto end;
}
}
(void)fdt_setprop(blob, node_ofs, "gpio-line-names", buffer, pos);
end: ;
}
static void ft_bootloader_version(void *blob) static void ft_bootloader_version(void *blob)
{ {
int node_offset; int node_offset;
@ -1236,18 +1293,27 @@ static void ft_hw_info(void *blob)
static void ft_dio(void *blob) static void ft_dio(void *blob)
{ {
switch (hw_num_ios) { switch (hw_num_ios) {
case 6: case 6:
printf("configuring 4+2 IOs\n"); /* NRSW IO node 4+2 */
ft_enable_node(blob, "/netbox_dio_4in_2out"); ft_enable_node(blob, "/netbox_dio_4in_2out");
break; break;
case 3: case 3:
printf("configuring 2+1 IOs\n"); /* NRSW IO node 2+1 */
ft_enable_node(blob, "/netbox_dio_2in_1out"); ft_enable_node(blob, "/netbox_dio_2in_1out");
break;
default: /* OEM Linux gpios -> remove IOs not present */
break; ft_set_gpio_name(blob, "/ocp/gpio@44e07000", 27, ""); /* gpio0_27: IO_OUT1n */
ft_set_gpio_name(blob, "/ocp/gpio@4804c000", 14, ""); /* gpio1_14: IO_IN2 */
ft_set_gpio_name(blob, "/ocp/gpio@4804c000", 15, ""); /* gpio1_15: IO_IN3 */
/* pmic_gpios: 5: IO_IN2_WAKE3n, 6: IO_IN2_WAKE3n */
ft_set_gpio_name(blob, "/ocp/i2c@44e0b000/da9063@58/gpio", 5, "");
ft_set_gpio_name(blob, "/ocp/i2c@44e0b000/da9063@58/gpio", 6, "");
break;
default:
break;
} }
} }
@ -1257,6 +1323,11 @@ static void ft_tty(void *blob)
/* TODO: Should use alias uart5 */ /* TODO: Should use alias uart5 */
ft_enable_node(blob, "/ocp/serial@481aa000"); ft_enable_node(blob, "/ocp/serial@481aa000");
} }
else {
/* OEM Linux gpios -> remove IOs not present */
ft_set_gpio_name(blob, "/ocp/gpio@44e07000", 22, ""); /* gpio0_22: SEL_RS232_RS485n */
ft_set_gpio_name(blob, "/ocp/gpio@44e07000", 23, ""); /* gpio0_23: RS485_TERM_ENn */
}
} }
#if 0 #if 0