summaryrefslogtreecommitdiffstats
path: root/bsps/arm/shared/include/bsp/imx-gpio.h
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/arm/shared/include/bsp/imx-gpio.h')
-rw-r--r--bsps/arm/shared/include/bsp/imx-gpio.h196
1 files changed, 196 insertions, 0 deletions
diff --git a/bsps/arm/shared/include/bsp/imx-gpio.h b/bsps/arm/shared/include/bsp/imx-gpio.h
new file mode 100644
index 0000000000..dca2d0cfad
--- /dev/null
+++ b/bsps/arm/shared/include/bsp/imx-gpio.h
@@ -0,0 +1,196 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BSP_IMX_GPIO_H
+#define BSP_IMX_GPIO_H
+
+#include <rtems.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** Hardware registers and locking mechanism for one hardware GPIO module. */
+struct imx_gpio;
+
+/** Mode of the pin. */
+enum imx_gpio_mode {
+ IMX_GPIO_MODE_OUTPUT,
+ IMX_GPIO_MODE_INPUT,
+ IMX_GPIO_MODE_INTERRUPT_LOW,
+ IMX_GPIO_MODE_INTERRUPT_HIGH,
+ IMX_GPIO_MODE_INTERRUPT_RISING,
+ IMX_GPIO_MODE_INTERRUPT_FALLING,
+ IMX_GPIO_MODE_INTERRUPT_ANY_EDGE,
+};
+
+/**
+ * A i.MX GPIO pin or set of pins.
+ *
+ * Use this structures to handle pins in the application. You can either get
+ * them from an FDT entry (with @ref imx_gpio_init_from_fde_property) or fill
+ * them by hand.
+ */
+struct imx_gpio_pin {
+ /** Management structure for the GPIO. Get with @ref imx_gpio_get_by_index. */
+ volatile struct imx_gpio* gpio;
+ /**
+ * Select the pins you want to handle with this mask. The mask is not
+ * influenced by the @a shift field.
+ */
+ uint32_t mask;
+ /** If set to something != 0: Shift the pins that many bits. */
+ unsigned int shift;
+ /** Whether the pin is an input, output, interrupt, ... */
+ enum imx_gpio_mode mode;
+};
+
+/**
+ * Initialize a GPIO pin. Only necessary for manually filled imx_gpio
+ * structures.
+ */
+void imx_gpio_init (struct imx_gpio_pin *pin);
+
+/**
+ * Initialize a GPIO pin from a FDT property.
+ *
+ * If you have for example the following property in an FDT node:
+ *
+ * some-node {
+ * gpios = <&gpio5 1 GPIO_ACTIVE_LOW>, <&gpio4 22 GPIO_ACTIVE_LOW>;
+ * };
+ *
+ * you can use the following to initialize the second GPIO:
+ *
+ * imx_gpio_init_from_fdt_property(&pin, node, "gpios",
+ * IMX_GPIO_INTERRUPT_LOW, 1);
+ *
+ * NOTE: The information from the third parameter in the FDT (GPIO_ACTIVE_LOW in
+ * the example) is currently ignored.
+ */
+rtems_status_code imx_gpio_init_from_fdt_property(
+ struct imx_gpio_pin *pin,
+ int node_offset,
+ const char *property,
+ enum imx_gpio_mode mode,
+ size_t index);
+
+/**
+ * Return the RTEMS interrupt vector belonging to the GPIO interrupt of a given
+ * node. The node should look like follows:
+ *
+ * some-node {
+ * interrupt-parent = <&gpio4>;
+ * interrupts = <15 IRQ_TYPE_EDGE_BOTH>, <22 IRQ_TYPE_EDGE_BOTH>;
+ * };
+ *
+ * To get the interrupt vector from the first GPIO in interrupts use
+ *
+ * imx_gpio_get_irq_of_node(fdt, node, 0);
+ *
+ * @returns the interrupt vector if successful.
+ * @returns BSP_INTERRUPT_VECTOR_INVALID on failure.
+ */
+rtems_vector_number imx_gpio_get_irq_of_node(
+ const void *fdt,
+ int node,
+ size_t index);
+
+/**
+ * Return the gpio management structure based on the GPIO index. The index is
+ * the one used in the FDT alias list. So index 0 is GPIO1 in the i.MX docs for
+ * most FDTs based on the Linux one.
+ */
+struct imx_gpio *imx_gpio_get_by_index(unsigned idx);
+
+/**
+ * Return the gpio management structure based on the GPIO registers.
+ */
+struct imx_gpio *imx_gpio_get_by_register(void *regs);
+
+/**
+ * Get the name of the gpio.
+ */
+const char *imx_gpio_get_name(struct imx_gpio *imx_gpio);
+
+/**
+ * Set the value of the output pin. @a set will be shifted and masked (in that
+ * order) based on the values of @a pin.
+ */
+void imx_gpio_set_output(struct imx_gpio_pin *pin, uint32_t set);
+
+/**
+ * Toggle the value of the output pin.
+ */
+void imx_gpio_toggle_output(struct imx_gpio_pin *pin);
+
+/**
+ * Get the value of the input pin. The input value will be masked and shifted
+ * (in that order) based on the values of @a pin.
+ */
+uint32_t imx_gpio_get_input(struct imx_gpio_pin *pin);
+
+/**
+ * Disable the interrupt of the given @a pin.
+ */
+void imx_gpio_int_disable(struct imx_gpio_pin *pin);
+
+/**
+ * Enable the interrupt of the given @a pin.
+ */
+void imx_gpio_int_enable(struct imx_gpio_pin *pin);
+
+/**
+ * Read the interrupt status register for the given @a pin.
+ */
+uint32_t imx_gpio_get_isr(struct imx_gpio_pin *pin);
+
+/**
+ * Clear the interrupt status register for the given @a pin.
+ */
+void imx_gpio_clear_isr(struct imx_gpio_pin *pin, uint32_t clr);
+
+/**
+ * Fast access macros for the GPIOs. Note that these assume a FDT based on the
+ * Linux FDTs.
+ */
+/** @{ */
+#define IMX_GPIO1 (imx_gpio_get_by_index(0))
+#define IMX_GPIO2 (imx_gpio_get_by_index(1))
+#define IMX_GPIO3 (imx_gpio_get_by_index(2))
+#define IMX_GPIO4 (imx_gpio_get_by_index(3))
+#define IMX_GPIO5 (imx_gpio_get_by_index(4))
+#define IMX_GPIO6 (imx_gpio_get_by_index(5))
+#define IMX_GPIO7 (imx_gpio_get_by_index(6))
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* BSP_IMX_GPIO_H */