![]() |
|
|||
File indexing completed on 2025-05-11 08:23:02
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /* 0004 * Copyright (C) 2020 embedded brains GmbH & Co. KG 0005 * 0006 * Redistribution and use in source and binary forms, with or without 0007 * modification, are permitted provided that the following conditions 0008 * are met: 0009 * 1. Redistributions of source code must retain the above copyright 0010 * notice, this list of conditions and the following disclaimer. 0011 * 2. Redistributions in binary form must reproduce the above copyright 0012 * notice, this list of conditions and the following disclaimer in the 0013 * documentation and/or other materials provided with the distribution. 0014 * 0015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0016 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0017 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0018 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0019 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0020 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0021 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0023 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0024 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0025 * POSSIBILITY OF SUCH DAMAGE. 0026 */ 0027 0028 #ifndef BSP_IMX_GPIO_H 0029 #define BSP_IMX_GPIO_H 0030 0031 #include <rtems.h> 0032 #include <stdint.h> 0033 0034 #ifdef __cplusplus 0035 extern "C" { 0036 #endif /* __cplusplus */ 0037 0038 /** Hardware registers and locking mechanism for one hardware GPIO module. */ 0039 struct imx_gpio; 0040 0041 /** Mode of the pin. */ 0042 enum imx_gpio_mode { 0043 IMX_GPIO_MODE_OUTPUT, 0044 IMX_GPIO_MODE_INPUT, 0045 IMX_GPIO_MODE_INTERRUPT_LOW, 0046 IMX_GPIO_MODE_INTERRUPT_HIGH, 0047 IMX_GPIO_MODE_INTERRUPT_RISING, 0048 IMX_GPIO_MODE_INTERRUPT_FALLING, 0049 IMX_GPIO_MODE_INTERRUPT_ANY_EDGE, 0050 }; 0051 0052 /** 0053 * A i.MX GPIO pin or set of pins. 0054 * 0055 * Use this structures to handle pins in the application. You can either get 0056 * them from an FDT entry (with @ref imx_gpio_init_from_fde_property) or fill 0057 * them by hand. 0058 */ 0059 struct imx_gpio_pin { 0060 /** Management structure for the GPIO. Get with @ref imx_gpio_get_by_index. */ 0061 volatile struct imx_gpio* gpio; 0062 /** 0063 * Select the pins you want to handle with this mask. The mask is not 0064 * influenced by the @a shift field. 0065 */ 0066 uint32_t mask; 0067 /** If set to something != 0: Shift the pins that many bits. */ 0068 unsigned int shift; 0069 /** Whether the pin is an input, output, interrupt, ... */ 0070 enum imx_gpio_mode mode; 0071 /** 0072 * Whether the pin is active low. Only used to store the last field of the FDT 0073 * entries. Can be queried via the @ref imx_gpio_get_active_level. 0074 */ 0075 bool is_active_low; 0076 }; 0077 0078 /** 0079 * Initialize a GPIO pin. Only necessary for manually filled imx_gpio 0080 * structures. 0081 */ 0082 void imx_gpio_init (struct imx_gpio_pin *pin); 0083 0084 /** 0085 * Initialize a GPIO pin from the fields in an FDT property. 0086 * 0087 * If you have for example the following property in an FDT node: 0088 * 0089 * some-node { 0090 * mixed-stuff = <0>, <&some_node 1>, <&gpio4 22 GPIO_ACTIVE_LOW>, <17>; 0091 * }; 0092 * 0093 * You can get the property using fdt_getprop(...) in your code, somehow find 0094 * the right start position (the phandle &gpio4) and then pass it to this 0095 * function. 0096 * 0097 * If you pass something != NULL to @a next_prop_pointer, you will get a pointer 0098 * to the next part in the attribute. In the example above, that will be a 0099 * pointer to the <17>. 0100 * 0101 * NOTE: The information from the third parameter in the FDT (GPIO_ACTIVE_LOW in 0102 * the example) is currently ignored. 0103 */ 0104 rtems_status_code imx_gpio_init_from_fdt_property_pointer( 0105 struct imx_gpio_pin *pin, 0106 const uint32_t *prop_pointer, 0107 enum imx_gpio_mode mode, 0108 const uint32_t **next_prop_pointer); 0109 0110 /** 0111 * Initialize a GPIO pin from a FDT property. 0112 * 0113 * If you have for example the following property in an FDT node: 0114 * 0115 * some-node { 0116 * gpios = <&gpio5 1 GPIO_ACTIVE_LOW>, <&gpio4 22 GPIO_ACTIVE_LOW>; 0117 * }; 0118 * 0119 * you can use the following to initialize the second GPIO: 0120 * 0121 * imx_gpio_init_from_fdt_property(&pin, node, "gpios", 0122 * IMX_GPIO_INTERRUPT_LOW, 1); 0123 * 0124 * NOTE: The information from the third parameter in the FDT (GPIO_ACTIVE_LOW in 0125 * the example) is only stored in the imx_gpio_pin structure. It can be queried 0126 * but will not be applied automatically! 0127 */ 0128 rtems_status_code imx_gpio_init_from_fdt_property( 0129 struct imx_gpio_pin *pin, 0130 int node_offset, 0131 const char *property, 0132 enum imx_gpio_mode mode, 0133 size_t index); 0134 0135 /** 0136 * Return the RTEMS interrupt vector belonging to the GPIO interrupt of a given 0137 * node. The node should look like follows: 0138 * 0139 * some-node { 0140 * interrupt-parent = <&gpio4>; 0141 * interrupts = <15 IRQ_TYPE_EDGE_BOTH>, <22 IRQ_TYPE_EDGE_BOTH>; 0142 * }; 0143 * 0144 * To get the interrupt vector from the first GPIO in interrupts use 0145 * 0146 * imx_gpio_get_irq_of_node(fdt, node, 0); 0147 * 0148 * @returns the interrupt vector if successful. 0149 * @returns BSP_INTERRUPT_VECTOR_INVALID on failure. 0150 */ 0151 rtems_vector_number imx_gpio_get_irq_of_node( 0152 const void *fdt, 0153 int node, 0154 size_t index); 0155 0156 /** 0157 * Return the gpio management structure based on the GPIO index. The index is 0158 * the one used in the FDT alias list. So index 0 is GPIO1 in the i.MX docs for 0159 * most FDTs based on the Linux one. 0160 */ 0161 struct imx_gpio *imx_gpio_get_by_index(unsigned idx); 0162 0163 /** 0164 * Return the gpio management structure based on the GPIO registers. 0165 */ 0166 struct imx_gpio *imx_gpio_get_by_register(void *regs); 0167 0168 /** 0169 * Get the name of the gpio. 0170 */ 0171 const char *imx_gpio_get_name(struct imx_gpio *imx_gpio); 0172 0173 /** 0174 * Set the value of the output pin. @a set will be shifted and masked (in that 0175 * order) based on the values of @a pin. 0176 */ 0177 void imx_gpio_set_output(struct imx_gpio_pin *pin, uint32_t set); 0178 0179 /** 0180 * Toggle the value of the output pin. 0181 */ 0182 void imx_gpio_toggle_output(struct imx_gpio_pin *pin); 0183 0184 /** 0185 * Get the value of the input pin. The input value will be masked and shifted 0186 * (in that order) based on the values of @a pin. 0187 */ 0188 uint32_t imx_gpio_get_input(struct imx_gpio_pin *pin); 0189 0190 /** 0191 * Disable the interrupt of the given @a pin. 0192 */ 0193 void imx_gpio_int_disable(struct imx_gpio_pin *pin); 0194 0195 /** 0196 * Enable the interrupt of the given @a pin. 0197 */ 0198 void imx_gpio_int_enable(struct imx_gpio_pin *pin); 0199 0200 /** 0201 * Read the interrupt status register for the given @a pin. 0202 */ 0203 uint32_t imx_gpio_get_isr(struct imx_gpio_pin *pin); 0204 0205 /** 0206 * Clear the interrupt status register for the given @a pin. 0207 */ 0208 void imx_gpio_clear_isr(struct imx_gpio_pin *pin, uint32_t clr); 0209 0210 /** 0211 * Get the active level of the pin. Returns either 0x0 or 0xFFFFFFFF so that you 0212 * can directly use it with the @ref imx_gpio_set_output function. 0213 */ 0214 static inline uint32_t imx_gpio_get_active_level(struct imx_gpio_pin *pin) 0215 { 0216 return (pin->is_active_low) ? 0 : 0xFFFFFFFFU; 0217 } 0218 0219 /** 0220 * Get the inactive level of the pin. Returns either 0x0 or 0xFFFFFFFF so that 0221 * you can directly use it with the @ref imx_gpio_set_output function. 0222 */ 0223 static inline uint32_t imx_gpio_get_inactive_level(struct imx_gpio_pin *pin) 0224 { 0225 return ~imx_gpio_get_active_level(pin); 0226 } 0227 0228 /** 0229 * Fast access macros for the GPIOs. Note that these assume a FDT based on the 0230 * Linux FDTs. 0231 */ 0232 /** @{ */ 0233 #define IMX_GPIO1 (imx_gpio_get_by_index(0)) 0234 #define IMX_GPIO2 (imx_gpio_get_by_index(1)) 0235 #define IMX_GPIO3 (imx_gpio_get_by_index(2)) 0236 #define IMX_GPIO4 (imx_gpio_get_by_index(3)) 0237 #define IMX_GPIO5 (imx_gpio_get_by_index(4)) 0238 #define IMX_GPIO6 (imx_gpio_get_by_index(5)) 0239 #define IMX_GPIO7 (imx_gpio_get_by_index(6)) 0240 /** @} */ 0241 0242 #ifdef __cplusplus 0243 } 0244 #endif /* __cplusplus */ 0245 0246 #endif /* BSP_IMX_GPIO_H */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |