xref: /OK3568_Linux_fs/kernel/drivers/misc/rk628/rk628_pinctrl.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2021 Rockchip Electronics Co. Ltd.
4  *
5  * Author: Wyon Bi <bivvy.bi@rock-chips.com>
6  */
7 
8 #include "rk628.h"
9 
rk628_calc_mux_offset(struct rk628 * rk628,int mux,int reg,int offset)10 static int rk628_calc_mux_offset(struct rk628 *rk628, int mux, int reg, int offset)
11 {
12 	int val = 0, orig;
13 
14 	switch (reg) {
15 	case GRF_SYSTEM_CON3:
16 		rk628_i2c_read(rk628, reg, &orig);
17 		if (mux)
18 			val = BIT(offset) | orig;
19 		else
20 			val = ~BIT(offset) & orig;
21 		break;
22 	case GRF_GPIO0AB_SEL_CON:
23 		if (offset >= 4 && offset < 8) {
24 			offset += offset - 4;
25 			val = 0x3 << (offset + 16) | (mux << offset);
26 		} else if (offset > 7) {
27 			offset += 4;
28 			val = BIT(offset + 16) | (mux << offset);
29 		} else {
30 			val = BIT(offset + 16) | (mux << offset);
31 		}
32 		break;
33 	case GRF_GPIO1AB_SEL_CON:
34 		if (offset == 13)
35 			offset++;
36 		if (offset > 11)
37 			val = 0x3 << (offset + 16) | (mux << offset);
38 		else
39 			val = BIT(offset + 16) | (mux << offset);
40 		break;
41 	case GRF_GPIO2AB_SEL_CON:
42 		val = BIT(offset + 16) | (mux << offset);
43 		break;
44 	case GRF_GPIO2C_SEL_CON:
45 		offset -= 16;
46 		val = 0x3 << ((offset*2) + 16) | (mux << (offset*2));
47 		break;
48 	case GRF_GPIO3AB_SEL_CON:
49 		if (offset > 11)
50 			val = 0x3 << (offset + 16) | (mux << offset);
51 		else
52 			val = BIT(offset + 16) | (mux << offset);
53 		break;
54 	default:
55 		break;
56 	}
57 
58 	return val;
59 }
60 
rk628_misc_pinctrl_set_mux(struct rk628 * rk628,int gpio,int mux)61 int rk628_misc_pinctrl_set_mux(struct rk628 *rk628, int gpio, int mux)
62 {
63 	int i, iomux_base, offset, val;
64 
65 	mux &= 0x3;
66 
67 	for (i = 0; i < ARRAY_SIZE(rk628_pin_iomux_groups); i++) {
68 		if (rk628_pin_iomux_groups[i].pins == gpio) {
69 			iomux_base = rk628_pin_iomux_groups[i].iomux_base;
70 			offset = rk628_pin_iomux_groups[i].pins % BANK_OFFSET;
71 			break;
72 		}
73 	}
74 
75 	if ((i == ARRAY_SIZE(rk628_pin_iomux_groups)) || (!iomux_base)) {
76 		pr_info("%s invalid gpio or iomux_base\n", __func__);
77 		return -1;
78 	}
79 
80 	val = rk628_calc_mux_offset(rk628, mux, iomux_base, offset);
81 
82 	rk628_i2c_write(rk628, iomux_base, val);
83 
84 	return 0;
85 
86 }
87 
88 
89 /* generic gpio chip */
rk628_misc_gpio_get_value(struct rk628 * rk628,int gpio)90 int rk628_misc_gpio_get_value(struct rk628 *rk628, int gpio)
91 {
92 	int i, data_reg, offset, val;
93 
94 	for (i = 0; i < ARRAY_SIZE(rk628_pin_iomux_groups); i++) {
95 		if (rk628_pin_iomux_groups[i].pins == gpio) {
96 			data_reg = rk628_pin_iomux_groups[i].gpio_base + GPIO_EXT_PORT;
97 			offset = rk628_pin_iomux_groups[i].pins % BANK_OFFSET;
98 			break;
99 		}
100 	}
101 
102 	if ((i == ARRAY_SIZE(rk628_pin_iomux_groups)) || (!data_reg)) {
103 		pr_info("%s invalid gpio or data_reg\n", __func__);
104 		return -1;
105 	}
106 
107 	rk628_i2c_read(rk628, data_reg, &val);
108 
109 	val >>= offset;
110 	val &= 1;
111 
112 	return val;
113 }
114 
rk628_misc_gpio_set_value(struct rk628 * rk628,int gpio,int value)115 int rk628_misc_gpio_set_value(struct rk628 *rk628, int gpio, int value)
116 {
117 	int i, data_reg, offset, val;
118 
119 	for (i = 0; i < ARRAY_SIZE(rk628_pin_iomux_groups); i++) {
120 		if (rk628_pin_iomux_groups[i].pins == gpio) {
121 			offset = rk628_pin_iomux_groups[i].pins % BANK_OFFSET;
122 			if (offset >= 16) {
123 				data_reg = rk628_pin_iomux_groups[i].gpio_base + GPIO_SWPORT_DR_H;
124 				offset -= 16;
125 			} else {
126 				data_reg = rk628_pin_iomux_groups[i].gpio_base + GPIO_SWPORT_DR_L;
127 			}
128 			break;
129 		}
130 	}
131 
132 	if ((i == ARRAY_SIZE(rk628_pin_iomux_groups)) || (!data_reg)) {
133 		pr_info("%s invalid gpio or data_reg\n", __func__);
134 		return -1;
135 	}
136 
137 	if (value)
138 		val = BIT(offset + 16) | BIT(offset);
139 	else
140 		val = BIT(offset + 16) | (0xffff & ~BIT(offset));
141 
142 	rk628_i2c_write(rk628, data_reg, val);
143 
144 	return 0;
145 }
146 
147 
148 
rk628_misc_gpio_set_direction(struct rk628 * rk628,int gpio,int direction)149 int rk628_misc_gpio_set_direction(struct rk628 *rk628, int gpio, int direction)
150 {
151 	int i, dir_reg, offset, val;
152 
153 	for (i = 0; i < ARRAY_SIZE(rk628_pin_iomux_groups); i++) {
154 		if (rk628_pin_iomux_groups[i].pins == gpio) {
155 			offset = rk628_pin_iomux_groups[i].pins % BANK_OFFSET;
156 			if (offset >= 16) {
157 				dir_reg = rk628_pin_iomux_groups[i].gpio_base + GPIO_SWPORT_DDR_H;
158 				offset -= 16;
159 			} else {
160 				dir_reg = rk628_pin_iomux_groups[i].gpio_base + GPIO_SWPORT_DDR_L;
161 			}
162 			break;
163 		}
164 	}
165 
166 	if ((i == ARRAY_SIZE(rk628_pin_iomux_groups)) || (!dir_reg)) {
167 		pr_info("%s invalid gpio or dir_reg\n", __func__);
168 		return -1;
169 	}
170 
171 	if (!direction)
172 		val = BIT(offset + 16) | (0xffff & ~BIT(offset));
173 	else
174 		val = BIT(offset + 16) | BIT(offset);
175 
176 	rk628_i2c_write(rk628, dir_reg, val);
177 
178 	return 0;
179 }
180 
181 
rk628_misc_iomux_init(struct rk628 * rk628)182 int rk628_misc_iomux_init(struct rk628 *rk628)
183 {
184 	int i, iomux_base, offset, val, mux;
185 
186 	for (i = 0; i < ARRAY_SIZE(rk628_pin_iomux_groups); i++) {
187 		mux = rk628_pin_iomux_groups[i].mux;
188 		iomux_base = rk628_pin_iomux_groups[i].iomux_base;
189 		offset = rk628_pin_iomux_groups[i].pins % BANK_OFFSET;
190 		if (iomux_base) {
191 			val = rk628_calc_mux_offset(rk628, mux, iomux_base, offset);
192 			rk628_i2c_write(rk628, iomux_base, val);
193 		}
194 	}
195 
196 	return 0;
197 }
198 
199 
rk628_misc_gpio_direction_input(struct rk628 * rk628,int gpio)200 int rk628_misc_gpio_direction_input(struct rk628 *rk628, int gpio)
201 {
202 	rk628_misc_pinctrl_set_mux(rk628, gpio, GPIO_FUNC);
203 
204 	rk628_misc_gpio_set_direction(rk628, gpio, GPIO_DIRECTION_IN);
205 
206 	return 0;
207 }
208 
209 
rk628_misc_gpio_direction_output(struct rk628 * rk628,int gpio,int value)210 int rk628_misc_gpio_direction_output(struct rk628 *rk628, int gpio, int value)
211 {
212 
213 	rk628_misc_pinctrl_set_mux(rk628, gpio, GPIO_FUNC);
214 	rk628_misc_gpio_set_value(rk628, gpio, value);
215 	rk628_misc_gpio_set_direction(rk628, gpio, GPIO_DIRECTION_OUT);
216 	return 0;
217 }
218 
219 
rk628_misc_gpio_set_pull_highz_up_down(struct rk628 * rk628,int gpio,int pull)220 int rk628_misc_gpio_set_pull_highz_up_down(struct rk628 *rk628, int gpio, int pull)
221 {
222 	int i, bank, pull_reg = 0, offset, val = 0;
223 	int valid_pinnum[] = { 8, 8, 24, 13 };
224 
225 	for (i = 0; i < ARRAY_SIZE(rk628_pin_iomux_groups); i++) {
226 		if (rk628_pin_iomux_groups[i].pins == gpio) {
227 			bank = rk628_pin_iomux_groups[i].bank;
228 			pull_reg = rk628_pin_iomux_groups[i].pull_reg;
229 			offset = rk628_pin_iomux_groups[i].pins % BANK_OFFSET;
230 			break;
231 		}
232 	}
233 
234 	if ((i == ARRAY_SIZE(rk628_pin_iomux_groups))  || (!pull_reg)) {
235 		pr_info("rk628_gpio_pull_highz_up_down invalid gpio or pull_reg\n");
236 		return -1;
237 	}
238 
239 	switch (bank) {
240 	case GPIO_BANK0:
241 		if (pull == GPIO_PULL_UP)
242 			return -1;
243 
244 		if (offset == 2)
245 			return -1;
246 
247 		if (offset < valid_pinnum[bank])
248 			val = 0x3 << (2 * offset + 16) | pull << (2 * offset);
249 		break;
250 	case GPIO_BANK1:
251 		if (pull == GPIO_PULL_UP)
252 			return -1;
253 
254 		if (offset == 2)
255 			return -1;
256 
257 		if (offset < valid_pinnum[bank])
258 			val = 0x3 << (2 * offset + 16) | pull << (2 * offset);
259 		break;
260 	case GPIO_BANK2:
261 		if (pull == GPIO_PULL_UP)
262 			pull = GPIO_PULL_DOWN;
263 		else if (pull == GPIO_PULL_DOWN)
264 			pull = GPIO_PULL_UP;
265 
266 		if (offset < valid_pinnum[bank]) {
267 			offset = offset % 8;
268 			val = 0x3 << (2 * offset + 16) | pull << (2 * offset);
269 		}
270 		break;
271 	case GPIO_BANK3:
272 		if (pull == GPIO_PULL_UP && (offset == 2 || offset == 11 || offset == 12))
273 			return -1;
274 		else if (pull == GPIO_PULL_DOWN && (offset == 9 || offset == 10))
275 			return -1;
276 
277 		if (offset == 0 || offset == 1 || offset == 3 || offset == 8) {
278 			if (pull == GPIO_PULL_UP)
279 				pull = GPIO_PULL_DOWN;
280 			else if (pull == GPIO_PULL_DOWN)
281 				pull = GPIO_PULL_UP;
282 		}
283 
284 		if ((offset > 7 && offset < valid_pinnum[bank]) || offset < 4) {
285 			offset = offset % 8;
286 			val = 0x3 << (2 * offset + 16) | pull << (2 * offset);
287 		}
288 		break;
289 	default:
290 		break;
291 	}
292 
293 	rk628_i2c_write(rk628, pull_reg, val);
294 
295 	return 0;
296 }
297 
298 
299 
rk628_misc_gpio_test_all(struct rk628 * rk628)300 int rk628_misc_gpio_test_all(struct rk628 *rk628)
301 {
302 	int i;
303 
304 	for (i = 0; i < ARRAY_SIZE(rk628_pin_iomux_groups); i++) {
305 		if (rk628_pin_iomux_groups[i].pins && (rk628_pin_iomux_groups[i].pins != GPIO1_A1)
306 		    && (rk628_pin_iomux_groups[i].pins != GPIO2_C0)
307 		    && (rk628_pin_iomux_groups[i].pins != GPIO2_C1)
308 		    && (rk628_pin_iomux_groups[i].pins != GPIO2_C2)
309 		    && (rk628_pin_iomux_groups[i].pins != GPIO2_C3)
310 		    && (rk628_pin_iomux_groups[i].pins != GPIO2_C4))
311 			rk628_misc_gpio_direction_output(rk628, rk628_pin_iomux_groups[i].pins, 1);
312 	}
313 
314 	for (i = 0; i < ARRAY_SIZE(rk628_pin_iomux_groups); i++) {
315 		if (rk628_pin_iomux_groups[i].pins && (rk628_pin_iomux_groups[i].pins != GPIO1_A1)
316 		    && (rk628_pin_iomux_groups[i].pins != GPIO2_C0)
317 		    && (rk628_pin_iomux_groups[i].pins != GPIO2_C1)
318 		    && (rk628_pin_iomux_groups[i].pins != GPIO2_C2)
319 		    && (rk628_pin_iomux_groups[i].pins != GPIO2_C3)
320 		    && (rk628_pin_iomux_groups[i].pins != GPIO2_C4))
321 			rk628_misc_gpio_direction_output(rk628, rk628_pin_iomux_groups[i].pins, 0);
322 	}
323 
324 	return 0;
325 }
326 
327