summaryrefslogtreecommitdiffstats
path: root/bsps
diff options
context:
space:
mode:
authorAlex White <alex.white@oarcorp.com>2023-05-18 13:47:30 -0500
committerJoel Sherrill <joel@rtems.org>2023-05-19 12:32:18 -0500
commit9b7a1da8047ba630ea05f6969728af2fd14ce9b4 (patch)
treee440792ee93a57be87d5b9a78a3efd694db26099 /bsps
parentbsps/microblaze: Remove GPIO build system options (diff)
downloadrtems-9b7a1da8047ba630ea05f6969728af2fd14ce9b4.tar.bz2
bsps/microblaze: Add device tree support to GPIO
Diffstat (limited to 'bsps')
-rw-r--r--bsps/microblaze/microblaze_fpga/gpio/microblaze-gpio.c63
-rw-r--r--bsps/microblaze/microblaze_fpga/include/bsp/microblaze-gpio.h18
2 files changed, 81 insertions, 0 deletions
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 <assert.h>
#include <bsp/fatal.h>
+#include <bsp/fdt.h>
#include <bsp/microblaze-gpio.h>
+#include <libfdt.h>
+
#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.
*