From 9b7a1da8047ba630ea05f6969728af2fd14ce9b4 Mon Sep 17 00:00:00 2001 From: Alex White Date: Thu, 18 May 2023 13:47:30 -0500 Subject: bsps/microblaze: Add device tree support to GPIO --- .../microblaze_fpga/gpio/microblaze-gpio.c | 63 ++++++++++++++++++++++ .../microblaze_fpga/include/bsp/microblaze-gpio.h | 18 +++++++ 2 files changed, 81 insertions(+) (limited to 'bsps') diff --git a/bsps/microblaze/microblaze_fpga/gpio/microblaze-gpio.c b/bsps/microblaze/microblaze_fpga/gpio/microblaze-gpio.c index a12158f1b7..5444052b9e 100644 --- a/bsps/microblaze/microblaze_fpga/gpio/microblaze-gpio.c +++ b/bsps/microblaze/microblaze_fpga/gpio/microblaze-gpio.c @@ -36,12 +36,75 @@ #include #include +#include #include +#include + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +#ifdef BSP_MICROBLAZE_FPGA_USE_FDT +rtems_status_code microblaze_gpio_init_context_from_fdt( + Microblaze_GPIO_context *context, + int index +) +{ + if ( context == NULL ) { + return RTEMS_INVALID_ADDRESS; + } + + const char* compatible = "xlnx,xps-gpio-1.00.a"; + const void *fdt = bsp_fdt_get(); + int node = fdt_node_offset_by_compatible( fdt, -1, compatible ); + if ( node < 0 ) { + return RTEMS_INVALID_NUMBER; + } + + /* Get the desired GPIO node if index is greater than zero. */ + for(int i = 0; i < index; i++) { + node = fdt_node_offset_by_compatible( fdt, node, compatible ); + if ( node < 0 ) { + return RTEMS_INVALID_NUMBER; + } + } + + const uint32_t *prop; + prop = fdt_getprop( fdt, node, "reg", NULL ); + if ( prop != NULL ) { + context->regs = (Microblaze_GPIO_registers *) fdt32_to_cpu( prop[0] ); + } else { + return RTEMS_INVALID_NUMBER; + } + + prop = fdt_getprop( fdt, node, "xlnx,is-dual", NULL ); + if ( prop != NULL ) { + context->is_dual = fdt32_to_cpu( prop[0] ) != 0 ? true : false; + } else { + return RTEMS_INVALID_NUMBER; + } + + prop = fdt_getprop( fdt, node, "xlnx,interrupt-present", NULL ); + if ( prop != NULL ) { + context->has_interrupts = fdt32_to_cpu( prop[0] ) != 0 ? true : false; + } else { + return RTEMS_INVALID_NUMBER; + } + + if ( context->has_interrupts ) { + prop = fdt_getprop( fdt, node, "interrupts", NULL ); + if ( prop != NULL ) { + context->irq = fdt32_to_cpu( prop[0] ); + } else { + return RTEMS_INVALID_NUMBER; + } + } + + return RTEMS_SUCCESSFUL; +} +#endif /* BSP_MICROBLAZE_FPGA_USE_FDT */ + void microblaze_gpio_set_data_direction( Microblaze_GPIO_context *ctx, uint32_t channel, diff --git a/bsps/microblaze/microblaze_fpga/include/bsp/microblaze-gpio.h b/bsps/microblaze/microblaze_fpga/include/bsp/microblaze-gpio.h index a3d79ff70f..e8f569c8fd 100644 --- a/bsps/microblaze/microblaze_fpga/include/bsp/microblaze-gpio.h +++ b/bsps/microblaze/microblaze_fpga/include/bsp/microblaze-gpio.h @@ -129,6 +129,24 @@ typedef struct { bool has_interrupts; } Microblaze_GPIO_context; +#ifdef BSP_MICROBLAZE_FPGA_USE_FDT +/** + * @brief Initialize GPIO context from FDT. + * + * @param[in] context the GPIO context to initialize + * @param[in] index the zero-based GPIO index in the FDT + * + * @retval RTEMS_SUCCESSFUL on success + * @retval RTEMS_INVALID_NUMBER if the index is invalid or the node is missing a + * required property + * @retval RTEMS_INVALID_ADDRESS if the context is NULL + */ +rtems_status_code microblaze_gpio_init_context_from_fdt( + Microblaze_GPIO_context *context, + int index +); +#endif /* BSP_MICROBLAZE_FPGA_USE_FDT */ + /** * @brief Set pin configuration for the specified GPIO channel. * -- cgit v1.2.3