xref: /rk3399_rockchip-uboot/drivers/irq/irq-gpio.c (revision 5e8564cf419797f9095431e6eb6f0c00dfa423d2)
1 /*
2  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <asm/io.h>
8 #include <irq-generic.h>
9 #include "irq-gpio.h"
10 #include "irq-gpio-switch.h"
11 
12 typedef enum GPIOIntType {
13 	GPIOLevelLow = 0,
14 	GPIOLevelHigh,
15 	GPIOEdgelFalling,
16 	GPIOEdgelRising
17 } eGPIOIntType_t;
18 
19 typedef enum eGPIOPinLevel {
20 	GPIO_LOW = 0,
21 	GPIO_HIGH
22 } eGPIOPinLevel_t;
23 
24 typedef enum eGPIOPinDirection {
25 	GPIO_IN = 0,
26 	GPIO_OUT
27 } eGPIOPinDirection_t;
28 
29 #define GPIO_SWPORT_DR		0x00
30 #define GPIO_SWPORT_DDR		0x04
31 #define GPIO_INTEN		0x30
32 #define GPIO_INTMASK		0x34
33 #define GPIO_INTTYPE_LEVEL	0x38
34 #define GPIO_INT_POLARITY	0x3c
35 #define GPIO_INT_STATUS		0x40
36 #define GPIO_INT_RAWSTATUS	0x44
37 #define GPIO_DEBOUNCE		0x48
38 #define GPIO_PORTS_EOI		0x4c
39 #define GPIO_EXT_PORT		0x50
40 #define GPIO_LS_SYNC		0x60
41 
42 static inline unsigned pin_to_bit(unsigned pin)
43 {
44 	return (1 << pin);
45 }
46 
47 static inline unsigned offset_to_bit(unsigned offset)
48 {
49 	return (1 << offset);
50 }
51 
52 static void gpio_bit_op(void __iomem *regbase, unsigned int offset,
53 			u32 bit, unsigned char flag)
54 {
55 	u32 val = readl(regbase + offset);
56 
57 	if (flag)
58 		val |= bit;
59 	else
60 		val &= ~bit;
61 
62 	writel(val, regbase + offset);
63 }
64 
65 static int gpio_bit_rd(void __iomem *regbase, unsigned int offset, u32 bit)
66 {
67 	return readl(regbase + offset) & bit ? 1 : 0;
68 }
69 
70 static void gpio_irq_unmask(void __iomem *regbase, unsigned int bit)
71 {
72 	gpio_bit_op(regbase, GPIO_INTEN, bit, 1);
73 }
74 
75 static void gpio_irq_mask(void __iomem *regbase, unsigned int bit)
76 {
77 	gpio_bit_op(regbase, GPIO_INTEN, bit, 0);
78 }
79 
80 static void gpio_irq_ack(void __iomem *regbase, unsigned int bit)
81 {
82 	gpio_bit_op(regbase, GPIO_PORTS_EOI, bit, 1);
83 }
84 
85 static void generic_gpio_handle_irq(int irq, void *data __always_unused)
86 {
87 	struct gpio_bank *bank = gpio_id_to_bank(irq - IRQ_GPIO0);
88 	unsigned gpio_irq, pin, unmasked = 0;
89 	u32 isr, ilr;
90 
91 	isr = readl(bank->regbase + GPIO_INT_STATUS);
92 	ilr = readl(bank->regbase + GPIO_INTTYPE_LEVEL);
93 
94 	gpio_irq = bank->irq_base;
95 
96 	while (isr) {
97 		pin = fls(isr) - 1;
98 
99 		/* first mask and ack irq */
100 		gpio_irq_mask(bank->regbase, offset_to_bit(pin));
101 		gpio_irq_ack(bank->regbase, offset_to_bit(pin));
102 
103 		/*
104 		 * If gpio is edge triggered, clear condition before executing
105 		 * the handler, so that we don't miss next edges trigger.
106 		 */
107 		if (ilr & (1 << pin)) {
108 			unmasked = 1;
109 			gpio_irq_unmask(bank->regbase, offset_to_bit(pin));
110 		}
111 
112 		__generic_gpio_handle_irq(gpio_irq + pin);
113 
114 		isr &= ~(1 << pin);
115 
116 		if (!unmasked)
117 			gpio_irq_unmask(bank->regbase, offset_to_bit(pin));
118 	}
119 }
120 
121 static void gpio_set_intr_type(void __iomem *regbase,
122 			       unsigned int bit,
123 			       eGPIOIntType_t type)
124 {
125 	switch (type) {
126 	case GPIOLevelLow:
127 		gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 0);
128 		gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 0);
129 		break;
130 	case GPIOLevelHigh:
131 		gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 0);
132 		gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 1);
133 		break;
134 	case GPIOEdgelFalling:
135 		gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 1);
136 		gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 0);
137 		break;
138 	case GPIOEdgelRising:
139 		gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 1);
140 		gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 1);
141 		break;
142 	}
143 }
144 
145 static int gpio_get_intr_type(void __iomem *regbase,
146 			      unsigned int bit)
147 {
148 	u32 polarity, level, magic = 0;
149 	int type;
150 
151 	polarity = gpio_bit_rd(regbase, GPIO_INT_POLARITY, bit);
152 	level = gpio_bit_rd(regbase, GPIO_INTTYPE_LEVEL, bit);
153 	magic = (polarity << 1) | (level << 0);
154 
155 	switch (magic) {
156 	case 0x00:
157 		type = GPIOLevelLow;
158 		break;
159 	case 0x02:
160 		type = GPIOLevelHigh;
161 		break;
162 	case 0x01:
163 		type = GPIOEdgelFalling;
164 		break;
165 	case 0x03:
166 		type = GPIOEdgelRising;
167 		break;
168 	default:
169 		type = -EINVAL;
170 	}
171 
172 	return type;
173 }
174 
175 static int gpio_irq_set_type(int gpio_irq, unsigned int type)
176 {
177 	int gpio = irq_to_gpio(gpio_irq);
178 	struct gpio_bank *bank = gpio_to_bank(gpio);
179 	eGPIOIntType_t int_type = 0;
180 
181 	if (!bank)
182 		return -EINVAL;
183 
184 	gpio &= GPIO_PIN_MASK;
185 	if (gpio >= bank->ngpio)
186 		return -EINVAL;
187 
188 	switch (type) {
189 	case IRQ_TYPE_EDGE_RISING:
190 		int_type = GPIOEdgelRising;
191 		break;
192 	case IRQ_TYPE_EDGE_FALLING:
193 		int_type = GPIOEdgelFalling;
194 		break;
195 	case IRQ_TYPE_LEVEL_HIGH:
196 		int_type = GPIOLevelHigh;
197 		break;
198 	case IRQ_TYPE_LEVEL_LOW:
199 		int_type = GPIOLevelLow;
200 		break;
201 	default:
202 		return -EINVAL;
203 	}
204 
205 	/* Before set interrupt type, gpio must set input */
206 	gpio_bit_op(bank->regbase, GPIO_SWPORT_DDR,
207 		    offset_to_bit(gpio), GPIO_IN);
208 	gpio_set_intr_type(bank->regbase, offset_to_bit(gpio), int_type);
209 
210 	return 0;
211 }
212 
213 static int gpio_irq_revert_type(int gpio_irq)
214 {
215 	int gpio = irq_to_gpio(gpio_irq);
216 	struct gpio_bank *bank = gpio_to_bank(gpio);
217 	eGPIOIntType_t int_type = 0;
218 	int type;
219 
220 	if (!bank)
221 		return -EINVAL;
222 
223 	gpio &= GPIO_PIN_MASK;
224 	if (gpio >= bank->ngpio)
225 		return -EINVAL;
226 
227 	type = gpio_get_intr_type(bank->regbase, offset_to_bit(gpio));
228 	switch (type) {
229 	case GPIOEdgelFalling:
230 		int_type = GPIOEdgelRising;
231 		break;
232 	case GPIOEdgelRising:
233 		int_type = GPIOEdgelFalling;
234 		break;
235 	case GPIOLevelHigh:
236 		int_type = GPIOLevelLow;
237 		break;
238 	case GPIOLevelLow:
239 		int_type = GPIOLevelHigh;
240 		break;
241 	default:
242 		return -EINVAL;
243 	}
244 
245 	gpio_set_intr_type(bank->regbase, offset_to_bit(gpio), int_type);
246 
247 	return 0;
248 }
249 
250 static int gpio_irq_get_gpio_level(int gpio_irq)
251 {
252 	int gpio = irq_to_gpio(gpio_irq);
253 	struct gpio_bank *bank = gpio_to_bank(gpio);
254 
255 	if (!bank)
256 		return -EINVAL;
257 
258 	gpio &= GPIO_PIN_MASK;
259 	if (gpio >= bank->ngpio)
260 		return -EINVAL;
261 
262 	return gpio_bit_rd(bank->regbase, GPIO_EXT_PORT, offset_to_bit(gpio));
263 }
264 
265 static int gpio_irq_enable(int gpio_irq)
266 {
267 	int gpio = irq_to_gpio(gpio_irq);
268 	struct gpio_bank *bank = gpio_to_bank(gpio);
269 
270 	if (!bank)
271 		return -EINVAL;
272 
273 	gpio &= GPIO_PIN_MASK;
274 	if (gpio >= bank->ngpio)
275 		return -EINVAL;
276 
277 	gpio_irq_unmask(bank->regbase, offset_to_bit(gpio));
278 
279 	if (bank->use_count == 0)
280 		irq_handler_enable(IRQ_GPIO0 + bank->id);
281 	bank->use_count++;
282 
283 	return 0;
284 }
285 
286 static int gpio_irq_disable(int irq)
287 {
288 	int gpio = irq_to_gpio(irq);
289 	struct gpio_bank *bank = gpio_to_bank(gpio);
290 
291 	if (!bank)
292 		return -EINVAL;
293 
294 	gpio &= GPIO_PIN_MASK;
295 	if (gpio >= bank->ngpio)
296 		return -EINVAL;
297 
298 	gpio_irq_mask(bank->regbase, offset_to_bit(gpio));
299 
300 	if (bank->use_count == 1)
301 		irq_handler_disable(IRQ_GPIO0 + bank->id);
302 	bank->use_count--;
303 
304 	return 0;
305 }
306 
307 static int gpio_irq_init(void)
308 {
309 	struct gpio_bank *bank = NULL;
310 	int i = 0;
311 
312 	for (i = 0; i < GPIO_BANK_NUM; i++) {
313 		bank = gpio_id_to_bank(i);
314 		if (bank) {
315 			/* disable gpio pin interrupt */
316 			writel(0, bank->regbase + GPIO_INTEN);
317 
318 			/* register gpio group irq handler */
319 			irq_install_handler(IRQ_GPIO0 + bank->id,
320 			(interrupt_handler_t *)generic_gpio_handle_irq, NULL);
321 
322 			/* default disable all gpio group interrupt */
323 			irq_handler_disable(IRQ_GPIO0 + bank->id);
324 		}
325 	}
326 
327 	return 0;
328 }
329 
330 static struct irq_chip gpio_irq_chip = {
331 	.name		= "gpio-irq-chip",
332 	.irq_init	= gpio_irq_init,
333 	.irq_enable	= gpio_irq_enable,
334 	.irq_disable	= gpio_irq_disable,
335 	.irq_set_type	= gpio_irq_set_type,
336 	.irq_revert_type = gpio_irq_revert_type,
337 	.irq_get_gpio_level = gpio_irq_get_gpio_level,
338 };
339 
340 struct irq_chip *arch_gpio_irq_init(void)
341 {
342 	return &gpio_irq_chip;
343 }
344