xref: /rk3399_rockchip-uboot/drivers/irq/irq-gpio-switch.c (revision bdeebcdf00ebe436321906d25106d1fecc2aa77d)
1 /*
2  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <dm.h>
8 #include <irq-generic.h>
9 #include "irq-gpio-switch.h"
10 
11 static struct gpio_bank gpio_banks[GPIO_BANK_NUM] = {
12 #if GPIO_BANK_NUM >= 1
13 	GPIO_BANK_REGISTER(0, GPIO_BANK_PINS),
14 #endif
15 #if GPIO_BANK_NUM >= 2
16 	GPIO_BANK_REGISTER(1, GPIO_BANK_PINS),
17 #endif
18 #if GPIO_BANK_NUM >= 3
19 	GPIO_BANK_REGISTER(2, GPIO_BANK_PINS),
20 #endif
21 #if GPIO_BANK_NUM >= 4
22 	GPIO_BANK_REGISTER(3, GPIO_BANK_PINS),
23 #endif
24 #if GPIO_BANK_NUM >= 5
25 	GPIO_BANK_REGISTER(4, GPIO_BANK_PINS),
26 #endif
27 #if GPIO_BANK_NUM >= 6
28 	GPIO_BANK_REGISTER(5, GPIO_BANK_PINS),
29 #endif
30 #if GPIO_BANK_NUM >= 7
31 	GPIO_BANK_REGISTER(6, GPIO_BANK_PINS),
32 #endif
33 #if GPIO_BANK_NUM >= 8
34 	GPIO_BANK_REGISTER(7, GPIO_BANK_PINS),
35 #endif
36 #if GPIO_BANK_NUM >= 9
37 	GPIO_BANK_REGISTER(8, GPIO_BANK_PINS),
38 #endif
39 #if GPIO_BANK_NUM >= 10
40 	GPIO_BANK_REGISTER(9, GPIO_BANK_PINS),
41 #endif
42 };
43 
44 static int gpio_is_valid(u32 gpio)
45 {
46 	if ((gpio == EINVAL_GPIO) || !GPIO_BANK_VALID(gpio) ||
47 	    !GPIO_PIN_VALID(gpio)) {
48 		printf("gpio = 0x%x is not valid!\n", gpio);
49 		return 0;
50 	}
51 
52 	return 1;
53 }
54 
55 static int _hard_gpio_to_irq(u32 gpio)
56 {
57 	int idx, bank = 0, pin = 0;
58 
59 	if (!gpio_is_valid(gpio))
60 		return -EINVAL;
61 
62 	bank = (gpio & GPIO_BANK_MASK) >> GPIO_BANK_OFFSET;
63 	pin = (gpio & GPIO_PIN_MASK) >> GPIO_PIN_OFFSET;
64 
65 	for (idx = 0; idx < ARRAY_SIZE(gpio_banks); idx++) {
66 		if (gpio_banks[idx].id == bank)
67 			return (gpio_banks[idx].irq_base + pin);
68 	}
69 
70 	return -EINVAL;
71 }
72 
73 static int _irq_to_gpio(int irq)
74 {
75 	int bank, pin, idx;
76 
77 	bank = (irq - PIN_BASE) / GPIO_BANK_PINS;
78 	pin = (irq - PIN_BASE) % GPIO_BANK_PINS;
79 
80 	for (idx = 0; idx < ARRAY_SIZE(gpio_banks); idx++) {
81 		if (gpio_banks[idx].id == bank) {
82 			return (bank << GPIO_BANK_OFFSET) |
83 				(pin << GPIO_PIN_OFFSET);
84 		}
85 	}
86 
87 	return -EINVAL;
88 }
89 
90 int gpio_to_irq(struct gpio_desc *gpio)
91 {
92 	int irq_gpio, bank;
93 	bool found;
94 	char *name;
95 
96 	if (!gpio->dev->name) {
97 		printf("can't find device name for the gpio bank\n");
98 		return EINVAL_GPIO;
99 	}
100 
101 	name = strtok((char *)gpio->dev->name, "@");
102 	if (!name) {
103 		printf("can't find correct device name for the gpio bank\n");
104 		return EINVAL_GPIO;
105 	}
106 
107 	for (bank = 0; bank < ARRAY_SIZE(gpio_banks); bank++) {
108 		if (!strcmp(gpio_banks[bank].name, name)) {
109 			found = true;
110 			break;
111 		}
112 	}
113 
114 	if (!found) {
115 		printf("irq gpio framework can't find %s\n", name);
116 		return EINVAL_GPIO;
117 	}
118 
119 	irq_gpio = RK_IRQ_GPIO(bank, gpio->offset);
120 	if (!gpio_is_valid(irq_gpio))
121 		return EINVAL_GPIO;
122 
123 	return _hard_gpio_to_irq(irq_gpio);
124 }
125 
126 int hard_gpio_to_irq(u32 gpio)
127 {
128 	if (!gpio_is_valid(gpio))
129 		return EINVAL_GPIO;
130 
131 	return _hard_gpio_to_irq(gpio);
132 }
133 
134 int irq_to_gpio(int irq)
135 {
136 	return _irq_to_gpio(irq);
137 }
138 
139 struct gpio_bank *gpio_id_to_bank(u32 id)
140 {
141 	int idx;
142 
143 	for (idx = 0; idx < ARRAY_SIZE(gpio_banks); idx++) {
144 		if (gpio_banks[idx].id == id)
145 			return &gpio_banks[idx];
146 	}
147 
148 	return NULL;
149 }
150 
151 struct gpio_bank *gpio_to_bank(u32 gpio)
152 {
153 	int id;
154 
155 	if (!gpio_is_valid(gpio))
156 		return NULL;
157 
158 	id = (gpio & GPIO_BANK_MASK) >> GPIO_BANK_OFFSET;
159 
160 	return gpio_id_to_bank(id);
161 }
162