1 /*
2 * Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
3 *
4 * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
5 * the the People's Republic of China and other countries.
6 * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
7 *
8 * DISCLAIMER
9 * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
10 * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
11 * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
12 * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
13 * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
14 * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
15 * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
19 * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
20 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
21 * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
22 * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 
33 #ifndef __GPIO_I_H__
34 #define __GPIO_I_H__
35 
36 #include "hal_interrupt.h"
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 #define PA_BASE 0
42 #define PB_BASE 32
43 #define PC_BASE 64
44 #define PD_BASE 96
45 #define PE_BASE 128
46 #define PF_BASE 160
47 #define PG_BASE 192
48 #define PH_BASE 224
49 #define PI_BASE 256
50 #define PJ_BASE 288
51 #define PK_BASE 320
52 #define PL_BASE 352
53 #define PM_BASE 384
54 #define PN_BASE 416
55 #define PO_BASE 448
56 
57 /* sunxi gpio name space */
58 #define GPIOA(n)    (PA_BASE + (n))
59 #define GPIOB(n)    (PB_BASE + (n))
60 #define GPIOC(n)    (PC_BASE + (n))
61 #define GPIOD(n)    (PD_BASE + (n))
62 #define GPIOE(n)    (PE_BASE + (n))
63 #define GPIOF(n)    (PF_BASE + (n))
64 #define GPIOG(n)    (PG_BASE + (n))
65 #define GPIOH(n)    (PH_BASE + (n))
66 #define GPIOI(n)    (PI_BASE + (n))
67 #define GPIOJ(n)    (PJ_BASE + (n))
68 #define GPIOK(n)    (PK_BASE + (n))
69 #define GPIOL(n)    (PL_BASE + (n))
70 #define GPIOM(n)    (PM_BASE + (n))
71 #define GPION(n)    (PN_BASE + (n))
72 #define GPIOO(n)    (PO_BASE + (n))
73 
74 
75 #define IRQ_MEM_SIZE        0x20
76 #define GIC_IRQ_NUM         140
77 #define GPIO_IRQ_START      (GIC_IRQ_NUM + 1)
78 
79 #if defined(CONFIG_ARCH_SUN8IW20) || defined(CONFIG_SOC_SUN20IW1)
80 #define BANK_MEM_SIZE       0x30
81 #define PULL_REGS_OFFSET    0x24
82 #define DLEVEL_PINS_PER_REG 8
83 #define DLEVEL_PINS_BITS    4
84 #define DLEVEL_PINS_MASK    0x0f
85 #else
86 #define BANK_MEM_SIZE       0x24
87 #define PULL_REGS_OFFSET    0x1c
88 #define DLEVEL_PINS_PER_REG 16
89 #define DLEVEL_PINS_BITS    2
90 #define DLEVEL_PINS_MASK    0x03
91 #endif
92 
93 #define MUX_REGS_OFFSET     0x0
94 #define DATA_REGS_OFFSET    0x10
95 #define DLEVEL_REGS_OFFSET  0x14
96 
97 #define PINS_PER_BANK       32
98 #define MUX_PINS_PER_REG    8
99 #define MUX_PINS_BITS       4
100 #define MUX_PINS_MASK       0x0f
101 #define DATA_PINS_PER_REG   32
102 #define DATA_PINS_BITS      1
103 #define DATA_PINS_MASK      0x01
104 #define PULL_PINS_PER_REG   16
105 #define PULL_PINS_BITS      2
106 #define PULL_PINS_MASK      0x03
107 
108 #define IRQ_PER_BANK        32
109 
110 #define IRQ_CFG_REG     0x200
111 #define IRQ_CFG_IRQ_PER_REG     8
112 #define IRQ_CFG_IRQ_BITS        4
113 #define IRQ_CFG_IRQ_MASK        ((1 << IRQ_CFG_IRQ_BITS) - 1)
114 #define IRQ_CTRL_REG        0x210
115 #define IRQ_CTRL_IRQ_PER_REG        32
116 #define IRQ_CTRL_IRQ_BITS       1
117 #define IRQ_CTRL_IRQ_MASK       ((1 << IRQ_CTRL_IRQ_BITS) - 1)
118 #define IRQ_STATUS_REG      0x214
119 #define IRQ_STATUS_IRQ_PER_REG      32
120 #define IRQ_STATUS_IRQ_BITS     1
121 #define IRQ_STATUS_IRQ_MASK     ((1 << IRQ_STATUS_IRQ_BITS) - 1)
122 #define IRQ_DEBOUNCE_REG        0x218
123 #define POWER_MODE_SEL 0x0340
124 #define POWER_MODE_VAL 0x0348
125 #define POWER_VOL_SEL 0x0350
126 
127 #define IRQ_MEM_SIZE        0x20
128 #define GIC_IRQ_NUM     140
129 #define GPIO_IRQ_START      (GIC_IRQ_NUM + 1)
130 
131 #define IRQ_EDGE_RISING     0x00
132 #define IRQ_EDGE_FALLING    0x01
133 #define IRQ_LEVEL_HIGH      0x02
134 #define IRQ_LEVEL_LOW       0x03
135 #define IRQ_EDGE_BOTH       0x04
136 
137 #define SUNXI_PIO_BANK_BASE(pin, irq_bank) \
138     ((pin-PA_BASE)/PINS_PER_BANK - irq_bank)
139 
140 #define SUNXI_R_PIO_BANK_BASE(pin, irq_bank) \
141     ((pin-PL_BASE)/PINS_PER_BANK - irq_bank)
142 
143 /*
144  * This looks more complex than it should be. But we need to
145  * get the type for the ~ right in round_down (it needs to be
146  * as wide as the result!), and we want to evaluate the macro
147  * arguments just once each.
148  */
149 #define __round_mask(x, y) ((__typeof__(x))((y)-1))
150 #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
151 #define round_down(x, y) ((x) & ~__round_mask(x, y))
152 
153 #ifndef ARRAY_SIZE
154 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
155 #endif
156 
157 /*
158  * gpio configuration (pull up/down and drive strength) type and its value are
159  * packed together into a 32-bits. The lower 8-bits represent the configuration
160  * type and the upper 24-bits hold the value of the configuration type.
161  */
162 #define GPIO_CFG_PACK(type, value)  (((value) << 8) | ((unsigned long) type & 0xFFUL))
163 #define GPIO_CFG_UNPACK_TYPE(cfg)   ((cfg) & 0xFFUL)
164 #define GPIO_CFG_UNPACK_VALUE(cfg)  (((cfg) & 0xFFFFFF00UL) >> 8)
165 
166 typedef enum
167 {
168     GPIO_TYPE_FUNC,
169     GPIO_TYPE_DAT,
170     GPIO_TYPE_PUD,
171     GPIO_TYPE_DRV,
172     GPIO_TYPE_VOL,
173     GPIO_CONFIG_END = 0x7F,
174     GPIO_CONFIG_MAX = 0xFF,
175 } pin_config_param_t;
176 
177 typedef enum
178 {
179     IRQ_TYPE_NONE       = 0x00000000,
180     IRQ_TYPE_EDGE_RISING    = 0x00000001,
181     IRQ_TYPE_EDGE_FALLING   = 0x00000002,
182     IRQ_TYPE_EDGE_BOTH  = (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING),
183     IRQ_TYPE_LEVEL_HIGH = 0x00000004,
184     IRQ_TYPE_LEVEL_LOW  = 0x00000008,
185 } gpio_interrupt_mode_t;
186 
187 struct gpio_irq_desc
188 {
189     uint32_t virq;
190     uint32_t pin;
191     unsigned long flags;
192     irq_handler_t handle_irq;
193     void (*irq_attach)(void*);
194     void *data;
195 };
196 
197 struct gpio_desc
198 {
199     const unsigned long membase;
200     const uint32_t resource_size; /* reg resource size */
201     const uint32_t irq_arry_size;
202     const uint32_t *irq;
203     const uint32_t pin_base;
204     const uint32_t banks;
205     const uint32_t *bank_base;
206     const uint32_t irq_banks;
207     const uint32_t *irq_bank_base;
208     const uint32_t virq_offset;
209     uint32_t irq_desc_size;
210     struct gpio_irq_desc *irq_desc;
211 };
212 
213 struct gpio_pm_reg_cache
214 {
215     void *reg_dump[2];
216     int reg_dump_size[2];
217 };
218 
219 /*
220  * include the platform gpio header file,
221  * should be after the name space macro.
222  */
223 #if defined(CONFIG_ARCH_SUN8IW19)
224 #include "sun8iw19/platform-gpio.h"
225 #endif
226 #if defined(CONFIG_ARCH_SUN8IW18P1)
227 #include "sun8iw18/platform-gpio.h"
228 #endif
229 #if defined(CONFIG_ARCH_SUN8IW20) || defined(CONFIG_SOC_SUN20IW1)
230 #include "sun8iw20/platform-gpio.h"
231 #endif
232 #if defined(CONFIG_ARCH_SUN50IW11)
233 #include "sun50iw11/platform-gpio.h"
234 #endif
235 
236 const struct gpio_desc **gpio_get_platform_desc(void);
237 int hal_gpio_suspend(void);
238 int hal_gpio_resume(void);
239 
240 #ifdef __cplusplus
241 }
242 #endif
243 #endif /* __GPIO_I_H__ */
244