xref: /rk3399_rockchip-uboot/drivers/pinctrl/rockchip/pinctrl-rk3506.c (revision 3fd22dcdf025129433b12c22bcf0b8fc3c469b5a)
1*3fd22dcdSYe Zhang // SPDX-License-Identifier: GPL-2.0+
2*3fd22dcdSYe Zhang /*
3*3fd22dcdSYe Zhang  * (C) Copyright 2024 Rockchip Electronics Co., Ltd
4*3fd22dcdSYe Zhang  */
5*3fd22dcdSYe Zhang 
6*3fd22dcdSYe Zhang #include <common.h>
7*3fd22dcdSYe Zhang #include <dm.h>
8*3fd22dcdSYe Zhang #include <dm/pinctrl.h>
9*3fd22dcdSYe Zhang #include <regmap.h>
10*3fd22dcdSYe Zhang #include <syscon.h>
11*3fd22dcdSYe Zhang 
12*3fd22dcdSYe Zhang #include "pinctrl-rockchip.h"
13*3fd22dcdSYe Zhang 
rockchip_set_rmio(struct rockchip_pin_bank * bank,int pin,int * mux)14*3fd22dcdSYe Zhang static int rockchip_set_rmio(struct rockchip_pin_bank *bank, int pin, int *mux)
15*3fd22dcdSYe Zhang {
16*3fd22dcdSYe Zhang 	struct rockchip_pinctrl_priv *priv = bank->priv;
17*3fd22dcdSYe Zhang 	struct regmap *regmap;
18*3fd22dcdSYe Zhang 	int reg, function;
19*3fd22dcdSYe Zhang 	u32 data;
20*3fd22dcdSYe Zhang 	int ret = 0;
21*3fd22dcdSYe Zhang 	u32 iomux_max = (1 << 4) - 1;
22*3fd22dcdSYe Zhang 
23*3fd22dcdSYe Zhang 	if (*mux > iomux_max)
24*3fd22dcdSYe Zhang 		function = *mux - iomux_max;
25*3fd22dcdSYe Zhang 	else
26*3fd22dcdSYe Zhang 		return 0;
27*3fd22dcdSYe Zhang 
28*3fd22dcdSYe Zhang 	regmap = priv->regmap_rmio;
29*3fd22dcdSYe Zhang 	if (bank->bank_num == 0) {
30*3fd22dcdSYe Zhang 		if (pin < 24)
31*3fd22dcdSYe Zhang 			reg = 0x80 + 0x4 * pin;
32*3fd22dcdSYe Zhang 		else
33*3fd22dcdSYe Zhang 			ret = -EINVAL;
34*3fd22dcdSYe Zhang 	} else if (bank->bank_num == 1) {
35*3fd22dcdSYe Zhang 		if (pin >= 9 && pin <= 11)
36*3fd22dcdSYe Zhang 			reg = 0xbc + 0x4 * pin;
37*3fd22dcdSYe Zhang 		else if (pin >= 18 && pin <= 19)
38*3fd22dcdSYe Zhang 			reg = 0xa4 + 0x4 * pin;
39*3fd22dcdSYe Zhang 		else if (pin >= 25 && pin <= 27)
40*3fd22dcdSYe Zhang 			reg = 0x90 + 0x4 * pin;
41*3fd22dcdSYe Zhang 		else
42*3fd22dcdSYe Zhang 			ret = -EINVAL;
43*3fd22dcdSYe Zhang 	} else {
44*3fd22dcdSYe Zhang 		ret = -EINVAL;
45*3fd22dcdSYe Zhang 	}
46*3fd22dcdSYe Zhang 	if (ret) {
47*3fd22dcdSYe Zhang 		pr_err("rmio unsupported bank_num %d function %d\n",
48*3fd22dcdSYe Zhang 			bank->bank_num, function);
49*3fd22dcdSYe Zhang 
50*3fd22dcdSYe Zhang 		return -EINVAL;
51*3fd22dcdSYe Zhang 	}
52*3fd22dcdSYe Zhang 
53*3fd22dcdSYe Zhang 	data = 0x7f0000 | function;
54*3fd22dcdSYe Zhang 	*mux = 7;
55*3fd22dcdSYe Zhang 	ret = regmap_write(regmap, reg, data);
56*3fd22dcdSYe Zhang 	if (ret)
57*3fd22dcdSYe Zhang 		return ret;
58*3fd22dcdSYe Zhang 
59*3fd22dcdSYe Zhang 	return 0;
60*3fd22dcdSYe Zhang }
61*3fd22dcdSYe Zhang 
rk3506_set_mux(struct rockchip_pin_bank * bank,int pin,int mux)62*3fd22dcdSYe Zhang static int rk3506_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
63*3fd22dcdSYe Zhang {
64*3fd22dcdSYe Zhang 	struct rockchip_pinctrl_priv *priv = bank->priv;
65*3fd22dcdSYe Zhang 	int iomux_num = (pin / 8);
66*3fd22dcdSYe Zhang 	struct regmap *regmap;
67*3fd22dcdSYe Zhang 	int reg, ret, mask;
68*3fd22dcdSYe Zhang 	u8 bit;
69*3fd22dcdSYe Zhang 	u32 data;
70*3fd22dcdSYe Zhang 
71*3fd22dcdSYe Zhang 	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
72*3fd22dcdSYe Zhang 
73*3fd22dcdSYe Zhang 	ret = rockchip_set_rmio(bank, pin, &mux);
74*3fd22dcdSYe Zhang 	if (ret)
75*3fd22dcdSYe Zhang 		return ret;
76*3fd22dcdSYe Zhang 
77*3fd22dcdSYe Zhang 	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
78*3fd22dcdSYe Zhang 		regmap = priv->regmap_pmu;
79*3fd22dcdSYe Zhang 	else
80*3fd22dcdSYe Zhang 		regmap = priv->regmap_base;
81*3fd22dcdSYe Zhang 
82*3fd22dcdSYe Zhang 	if (bank->bank_num == 1)
83*3fd22dcdSYe Zhang 		regmap = priv->regmap_ioc1;
84*3fd22dcdSYe Zhang 	else if (bank->bank_num == 4)
85*3fd22dcdSYe Zhang 		return 0;
86*3fd22dcdSYe Zhang 
87*3fd22dcdSYe Zhang 	reg = bank->iomux[iomux_num].offset;
88*3fd22dcdSYe Zhang 	if ((pin % 8) >= 4)
89*3fd22dcdSYe Zhang 		reg += 0x4;
90*3fd22dcdSYe Zhang 	bit = (pin % 4) * 4;
91*3fd22dcdSYe Zhang 	mask = 0xf;
92*3fd22dcdSYe Zhang 
93*3fd22dcdSYe Zhang 	if (bank->recalced_mask & BIT(pin))
94*3fd22dcdSYe Zhang 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
95*3fd22dcdSYe Zhang 	data = (mask << (bit + 16));
96*3fd22dcdSYe Zhang 	data |= (mux & mask) << bit;
97*3fd22dcdSYe Zhang 
98*3fd22dcdSYe Zhang 	debug("iomux write reg = %x data = %x\n", reg, data);
99*3fd22dcdSYe Zhang 
100*3fd22dcdSYe Zhang 	ret = regmap_write(regmap, reg, data);
101*3fd22dcdSYe Zhang 
102*3fd22dcdSYe Zhang 	return ret;
103*3fd22dcdSYe Zhang }
104*3fd22dcdSYe Zhang 
105*3fd22dcdSYe Zhang #define RK3506_DRV_BITS_PER_PIN		8
106*3fd22dcdSYe Zhang #define RK3506_DRV_PINS_PER_REG		2
107*3fd22dcdSYe Zhang #define RK3506_DRV_GPIO0_A_OFFSET	0x100
108*3fd22dcdSYe Zhang #define RK3506_DRV_GPIO0_D_OFFSET	0x830
109*3fd22dcdSYe Zhang #define RK3506_DRV_GPIO1_OFFSET		0x140
110*3fd22dcdSYe Zhang #define RK3506_DRV_GPIO2_OFFSET		0x180
111*3fd22dcdSYe Zhang #define RK3506_DRV_GPIO3_OFFSET		0x1c0
112*3fd22dcdSYe Zhang #define RK3506_DRV_GPIO4_OFFSET		0x840
113*3fd22dcdSYe Zhang 
rk3506_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)114*3fd22dcdSYe Zhang static int rk3506_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
115*3fd22dcdSYe Zhang 					int pin_num, struct regmap **regmap,
116*3fd22dcdSYe Zhang 					int *reg, u8 *bit)
117*3fd22dcdSYe Zhang {
118*3fd22dcdSYe Zhang 	struct rockchip_pinctrl_priv *priv = bank->priv;
119*3fd22dcdSYe Zhang 	int ret = 0;
120*3fd22dcdSYe Zhang 
121*3fd22dcdSYe Zhang 	switch (bank->bank_num) {
122*3fd22dcdSYe Zhang 	case 0:
123*3fd22dcdSYe Zhang 		*regmap = priv->regmap_pmu;
124*3fd22dcdSYe Zhang 		if (pin_num > 24) {
125*3fd22dcdSYe Zhang 			ret = -EINVAL;
126*3fd22dcdSYe Zhang 		} else if (pin_num < 24) {
127*3fd22dcdSYe Zhang 			*reg = RK3506_DRV_GPIO0_A_OFFSET;
128*3fd22dcdSYe Zhang 		} else {
129*3fd22dcdSYe Zhang 			*reg = RK3506_DRV_GPIO0_D_OFFSET;
130*3fd22dcdSYe Zhang 			*bit = 3;
131*3fd22dcdSYe Zhang 
132*3fd22dcdSYe Zhang 			return 0;
133*3fd22dcdSYe Zhang 		}
134*3fd22dcdSYe Zhang 		break;
135*3fd22dcdSYe Zhang 
136*3fd22dcdSYe Zhang 	case 1:
137*3fd22dcdSYe Zhang 		*regmap = priv->regmap_ioc1;
138*3fd22dcdSYe Zhang 		if (pin_num < 28)
139*3fd22dcdSYe Zhang 			*reg = RK3506_DRV_GPIO1_OFFSET;
140*3fd22dcdSYe Zhang 		else
141*3fd22dcdSYe Zhang 			ret = -EINVAL;
142*3fd22dcdSYe Zhang 		break;
143*3fd22dcdSYe Zhang 
144*3fd22dcdSYe Zhang 	case 2:
145*3fd22dcdSYe Zhang 		*regmap = priv->regmap_base;
146*3fd22dcdSYe Zhang 		if (pin_num < 17)
147*3fd22dcdSYe Zhang 			*reg = RK3506_DRV_GPIO2_OFFSET;
148*3fd22dcdSYe Zhang 		else
149*3fd22dcdSYe Zhang 			ret = -EINVAL;
150*3fd22dcdSYe Zhang 		break;
151*3fd22dcdSYe Zhang 
152*3fd22dcdSYe Zhang 	case 3:
153*3fd22dcdSYe Zhang 		*regmap = priv->regmap_base;
154*3fd22dcdSYe Zhang 		if (pin_num < 15)
155*3fd22dcdSYe Zhang 			*reg = RK3506_DRV_GPIO3_OFFSET;
156*3fd22dcdSYe Zhang 		else
157*3fd22dcdSYe Zhang 			ret = -EINVAL;
158*3fd22dcdSYe Zhang 		break;
159*3fd22dcdSYe Zhang 
160*3fd22dcdSYe Zhang 	case 4:
161*3fd22dcdSYe Zhang 		*regmap = priv->regmap_base;
162*3fd22dcdSYe Zhang 		if (pin_num < 8 || pin_num > 11) {
163*3fd22dcdSYe Zhang 			ret = -EINVAL;
164*3fd22dcdSYe Zhang 		} else {
165*3fd22dcdSYe Zhang 			*reg = RK3506_DRV_GPIO4_OFFSET;
166*3fd22dcdSYe Zhang 			*bit = 10;
167*3fd22dcdSYe Zhang 
168*3fd22dcdSYe Zhang 			return 0;
169*3fd22dcdSYe Zhang 		}
170*3fd22dcdSYe Zhang 		break;
171*3fd22dcdSYe Zhang 
172*3fd22dcdSYe Zhang 	default:
173*3fd22dcdSYe Zhang 		ret = -EINVAL;
174*3fd22dcdSYe Zhang 		break;
175*3fd22dcdSYe Zhang 	}
176*3fd22dcdSYe Zhang 
177*3fd22dcdSYe Zhang 	if (ret) {
178*3fd22dcdSYe Zhang 		debug("unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
179*3fd22dcdSYe Zhang 
180*3fd22dcdSYe Zhang 		return ret;
181*3fd22dcdSYe Zhang 	}
182*3fd22dcdSYe Zhang 
183*3fd22dcdSYe Zhang 	*reg += ((pin_num / RK3506_DRV_PINS_PER_REG) * 4);
184*3fd22dcdSYe Zhang 	*bit = pin_num % RK3506_DRV_PINS_PER_REG;
185*3fd22dcdSYe Zhang 	*bit *= RK3506_DRV_BITS_PER_PIN;
186*3fd22dcdSYe Zhang 
187*3fd22dcdSYe Zhang 	return 0;
188*3fd22dcdSYe Zhang }
189*3fd22dcdSYe Zhang 
rk3506_set_drive(struct rockchip_pin_bank * bank,int pin_num,int strength)190*3fd22dcdSYe Zhang static int rk3506_set_drive(struct rockchip_pin_bank *bank,
191*3fd22dcdSYe Zhang 			    int pin_num, int strength)
192*3fd22dcdSYe Zhang {
193*3fd22dcdSYe Zhang 	struct regmap *regmap;
194*3fd22dcdSYe Zhang 	int reg, ret, i;
195*3fd22dcdSYe Zhang 	u32 data;
196*3fd22dcdSYe Zhang 	u8 bit;
197*3fd22dcdSYe Zhang 	int rmask_bits = RK3506_DRV_BITS_PER_PIN;
198*3fd22dcdSYe Zhang 
199*3fd22dcdSYe Zhang 	ret = rk3506_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
200*3fd22dcdSYe Zhang 	if (ret)
201*3fd22dcdSYe Zhang 		return ret;
202*3fd22dcdSYe Zhang 
203*3fd22dcdSYe Zhang 	for (i = 0, ret = 1; i < strength; i++)
204*3fd22dcdSYe Zhang 		ret = (ret << 1) | 1;
205*3fd22dcdSYe Zhang 
206*3fd22dcdSYe Zhang 	if ((bank->bank_num == 0 && pin_num == 24) || bank->bank_num == 4) {
207*3fd22dcdSYe Zhang 		rmask_bits = 2;
208*3fd22dcdSYe Zhang 		ret = strength;
209*3fd22dcdSYe Zhang 	}
210*3fd22dcdSYe Zhang 
211*3fd22dcdSYe Zhang 	/* enable the write to the equivalent lower bits */
212*3fd22dcdSYe Zhang 	data = ((1 << rmask_bits) - 1) << (bit + 16);
213*3fd22dcdSYe Zhang 	data |= (ret << bit);
214*3fd22dcdSYe Zhang 	ret = regmap_write(regmap, reg, data);
215*3fd22dcdSYe Zhang 
216*3fd22dcdSYe Zhang 	return ret;
217*3fd22dcdSYe Zhang }
218*3fd22dcdSYe Zhang 
219*3fd22dcdSYe Zhang #define RK3506_PULL_BITS_PER_PIN	2
220*3fd22dcdSYe Zhang #define RK3506_PULL_PINS_PER_REG	8
221*3fd22dcdSYe Zhang #define RK3506_PULL_GPIO0_A_OFFSET	0x200
222*3fd22dcdSYe Zhang #define RK3506_PULL_GPIO0_D_OFFSET	0x830
223*3fd22dcdSYe Zhang #define RK3506_PULL_GPIO1_OFFSET	0x210
224*3fd22dcdSYe Zhang #define RK3506_PULL_GPIO2_OFFSET	0x220
225*3fd22dcdSYe Zhang #define RK3506_PULL_GPIO3_OFFSET	0x230
226*3fd22dcdSYe Zhang #define RK3506_PULL_GPIO4_OFFSET	0x840
227*3fd22dcdSYe Zhang 
rk3506_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)228*3fd22dcdSYe Zhang static int rk3506_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
229*3fd22dcdSYe Zhang 					 int pin_num, struct regmap **regmap,
230*3fd22dcdSYe Zhang 					 int *reg, u8 *bit)
231*3fd22dcdSYe Zhang {
232*3fd22dcdSYe Zhang 	struct rockchip_pinctrl_priv *priv = bank->priv;
233*3fd22dcdSYe Zhang 	int ret = 0;
234*3fd22dcdSYe Zhang 
235*3fd22dcdSYe Zhang 	switch (bank->bank_num) {
236*3fd22dcdSYe Zhang 	case 0:
237*3fd22dcdSYe Zhang 		*regmap = priv->regmap_pmu;
238*3fd22dcdSYe Zhang 		if (pin_num > 24) {
239*3fd22dcdSYe Zhang 			ret = -EINVAL;
240*3fd22dcdSYe Zhang 		} else if (pin_num < 24) {
241*3fd22dcdSYe Zhang 			*reg = RK3506_PULL_GPIO0_A_OFFSET;
242*3fd22dcdSYe Zhang 		} else {
243*3fd22dcdSYe Zhang 			*reg = RK3506_PULL_GPIO0_D_OFFSET;
244*3fd22dcdSYe Zhang 			*bit = 5;
245*3fd22dcdSYe Zhang 
246*3fd22dcdSYe Zhang 			return 0;
247*3fd22dcdSYe Zhang 		}
248*3fd22dcdSYe Zhang 		break;
249*3fd22dcdSYe Zhang 
250*3fd22dcdSYe Zhang 	case 1:
251*3fd22dcdSYe Zhang 		*regmap = priv->regmap_ioc1;
252*3fd22dcdSYe Zhang 		if (pin_num < 28)
253*3fd22dcdSYe Zhang 			*reg = RK3506_PULL_GPIO1_OFFSET;
254*3fd22dcdSYe Zhang 		else
255*3fd22dcdSYe Zhang 			ret = -EINVAL;
256*3fd22dcdSYe Zhang 		break;
257*3fd22dcdSYe Zhang 
258*3fd22dcdSYe Zhang 	case 2:
259*3fd22dcdSYe Zhang 		*regmap = priv->regmap_base;
260*3fd22dcdSYe Zhang 		if (pin_num < 17)
261*3fd22dcdSYe Zhang 			*reg = RK3506_PULL_GPIO2_OFFSET;
262*3fd22dcdSYe Zhang 		else
263*3fd22dcdSYe Zhang 			ret = -EINVAL;
264*3fd22dcdSYe Zhang 		break;
265*3fd22dcdSYe Zhang 
266*3fd22dcdSYe Zhang 	case 3:
267*3fd22dcdSYe Zhang 		*regmap = priv->regmap_base;
268*3fd22dcdSYe Zhang 		if (pin_num < 15)
269*3fd22dcdSYe Zhang 			*reg = RK3506_PULL_GPIO3_OFFSET;
270*3fd22dcdSYe Zhang 		else
271*3fd22dcdSYe Zhang 			ret = -EINVAL;
272*3fd22dcdSYe Zhang 		break;
273*3fd22dcdSYe Zhang 
274*3fd22dcdSYe Zhang 	case 4:
275*3fd22dcdSYe Zhang 		*regmap = priv->regmap_base;
276*3fd22dcdSYe Zhang 		if (pin_num < 8 || pin_num > 11) {
277*3fd22dcdSYe Zhang 			ret = -EINVAL;
278*3fd22dcdSYe Zhang 		} else {
279*3fd22dcdSYe Zhang 			*reg = RK3506_PULL_GPIO4_OFFSET;
280*3fd22dcdSYe Zhang 			*bit = 13;
281*3fd22dcdSYe Zhang 
282*3fd22dcdSYe Zhang 			return 0;
283*3fd22dcdSYe Zhang 		}
284*3fd22dcdSYe Zhang 		break;
285*3fd22dcdSYe Zhang 
286*3fd22dcdSYe Zhang 	default:
287*3fd22dcdSYe Zhang 		ret = -EINVAL;
288*3fd22dcdSYe Zhang 		break;
289*3fd22dcdSYe Zhang 	}
290*3fd22dcdSYe Zhang 
291*3fd22dcdSYe Zhang 	if (ret) {
292*3fd22dcdSYe Zhang 		debug("unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
293*3fd22dcdSYe Zhang 
294*3fd22dcdSYe Zhang 		return ret;
295*3fd22dcdSYe Zhang 	}
296*3fd22dcdSYe Zhang 
297*3fd22dcdSYe Zhang 	*reg += ((pin_num / RK3506_PULL_PINS_PER_REG) * 4);
298*3fd22dcdSYe Zhang 	*bit = pin_num % RK3506_PULL_PINS_PER_REG;
299*3fd22dcdSYe Zhang 	*bit *= RK3506_PULL_BITS_PER_PIN;
300*3fd22dcdSYe Zhang 
301*3fd22dcdSYe Zhang 	return 0;
302*3fd22dcdSYe Zhang }
303*3fd22dcdSYe Zhang 
rk3506_set_pull(struct rockchip_pin_bank * bank,int pin_num,int pull)304*3fd22dcdSYe Zhang static int rk3506_set_pull(struct rockchip_pin_bank *bank,
305*3fd22dcdSYe Zhang 			   int pin_num, int pull)
306*3fd22dcdSYe Zhang {
307*3fd22dcdSYe Zhang 	struct regmap *regmap;
308*3fd22dcdSYe Zhang 	int reg, ret;
309*3fd22dcdSYe Zhang 	u8 bit, type;
310*3fd22dcdSYe Zhang 	u32 data;
311*3fd22dcdSYe Zhang 
312*3fd22dcdSYe Zhang 	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
313*3fd22dcdSYe Zhang 		return -ENOTSUPP;
314*3fd22dcdSYe Zhang 
315*3fd22dcdSYe Zhang 	ret = rk3506_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
316*3fd22dcdSYe Zhang 	if (ret)
317*3fd22dcdSYe Zhang 		return ret;
318*3fd22dcdSYe Zhang 	type = bank->pull_type[pin_num / 8];
319*3fd22dcdSYe Zhang 
320*3fd22dcdSYe Zhang 	if ((bank->bank_num == 0 && pin_num == 24) || bank->bank_num == 4)
321*3fd22dcdSYe Zhang 		type = 1;
322*3fd22dcdSYe Zhang 
323*3fd22dcdSYe Zhang 	ret = rockchip_translate_pull_value(type, pull);
324*3fd22dcdSYe Zhang 	if (ret < 0) {
325*3fd22dcdSYe Zhang 		debug("unsupported pull setting %d\n", pull);
326*3fd22dcdSYe Zhang 
327*3fd22dcdSYe Zhang 		return ret;
328*3fd22dcdSYe Zhang 	}
329*3fd22dcdSYe Zhang 
330*3fd22dcdSYe Zhang 	/* enable the write to the equivalent lower bits */
331*3fd22dcdSYe Zhang 	data = ((1 << RK3506_PULL_BITS_PER_PIN) - 1) << (bit + 16);
332*3fd22dcdSYe Zhang 
333*3fd22dcdSYe Zhang 	data |= (ret << bit);
334*3fd22dcdSYe Zhang 	ret = regmap_write(regmap, reg, data);
335*3fd22dcdSYe Zhang 
336*3fd22dcdSYe Zhang 	return ret;
337*3fd22dcdSYe Zhang }
338*3fd22dcdSYe Zhang 
339*3fd22dcdSYe Zhang #define RK3506_SMT_BITS_PER_PIN		1
340*3fd22dcdSYe Zhang #define RK3506_SMT_PINS_PER_REG		8
341*3fd22dcdSYe Zhang #define RK3506_SMT_GPIO0_A_OFFSET	0x400
342*3fd22dcdSYe Zhang #define RK3506_SMT_GPIO0_D_OFFSET	0x830
343*3fd22dcdSYe Zhang #define RK3506_SMT_GPIO1_OFFSET		0x410
344*3fd22dcdSYe Zhang #define RK3506_SMT_GPIO2_OFFSET		0x420
345*3fd22dcdSYe Zhang #define RK3506_SMT_GPIO3_OFFSET		0x430
346*3fd22dcdSYe Zhang #define RK3506_SMT_GPIO4_OFFSET		0x840
347*3fd22dcdSYe Zhang 
rk3506_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)348*3fd22dcdSYe Zhang static int rk3506_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
349*3fd22dcdSYe Zhang 					   int pin_num,
350*3fd22dcdSYe Zhang 					   struct regmap **regmap,
351*3fd22dcdSYe Zhang 					   int *reg, u8 *bit)
352*3fd22dcdSYe Zhang {
353*3fd22dcdSYe Zhang 	struct rockchip_pinctrl_priv *priv = bank->priv;
354*3fd22dcdSYe Zhang 	int ret = 0;
355*3fd22dcdSYe Zhang 
356*3fd22dcdSYe Zhang 	switch (bank->bank_num) {
357*3fd22dcdSYe Zhang 	case 0:
358*3fd22dcdSYe Zhang 		*regmap = priv->regmap_pmu;
359*3fd22dcdSYe Zhang 		if (pin_num > 24) {
360*3fd22dcdSYe Zhang 			ret = -EINVAL;
361*3fd22dcdSYe Zhang 		} else if (pin_num < 24) {
362*3fd22dcdSYe Zhang 			*reg = RK3506_SMT_GPIO0_A_OFFSET;
363*3fd22dcdSYe Zhang 		} else {
364*3fd22dcdSYe Zhang 			*reg = RK3506_SMT_GPIO0_D_OFFSET;
365*3fd22dcdSYe Zhang 			*bit = 9;
366*3fd22dcdSYe Zhang 
367*3fd22dcdSYe Zhang 			return 0;
368*3fd22dcdSYe Zhang 		}
369*3fd22dcdSYe Zhang 		break;
370*3fd22dcdSYe Zhang 
371*3fd22dcdSYe Zhang 	case 1:
372*3fd22dcdSYe Zhang 		*regmap = priv->regmap_ioc1;
373*3fd22dcdSYe Zhang 		if (pin_num < 28)
374*3fd22dcdSYe Zhang 			*reg = RK3506_SMT_GPIO1_OFFSET;
375*3fd22dcdSYe Zhang 		else
376*3fd22dcdSYe Zhang 			ret = -EINVAL;
377*3fd22dcdSYe Zhang 		break;
378*3fd22dcdSYe Zhang 
379*3fd22dcdSYe Zhang 	case 2:
380*3fd22dcdSYe Zhang 		*regmap = priv->regmap_base;
381*3fd22dcdSYe Zhang 		if (pin_num < 17)
382*3fd22dcdSYe Zhang 			*reg = RK3506_SMT_GPIO2_OFFSET;
383*3fd22dcdSYe Zhang 		else
384*3fd22dcdSYe Zhang 			ret = -EINVAL;
385*3fd22dcdSYe Zhang 		break;
386*3fd22dcdSYe Zhang 
387*3fd22dcdSYe Zhang 	case 3:
388*3fd22dcdSYe Zhang 		*regmap = priv->regmap_base;
389*3fd22dcdSYe Zhang 		if (pin_num < 15)
390*3fd22dcdSYe Zhang 			*reg = RK3506_SMT_GPIO3_OFFSET;
391*3fd22dcdSYe Zhang 		else
392*3fd22dcdSYe Zhang 			ret = -EINVAL;
393*3fd22dcdSYe Zhang 		break;
394*3fd22dcdSYe Zhang 
395*3fd22dcdSYe Zhang 	case 4:
396*3fd22dcdSYe Zhang 		*regmap = priv->regmap_base;
397*3fd22dcdSYe Zhang 		if (pin_num < 8 || pin_num > 11) {
398*3fd22dcdSYe Zhang 			ret = -EINVAL;
399*3fd22dcdSYe Zhang 		} else {
400*3fd22dcdSYe Zhang 			*reg = RK3506_SMT_GPIO4_OFFSET;
401*3fd22dcdSYe Zhang 			*bit = 8;
402*3fd22dcdSYe Zhang 
403*3fd22dcdSYe Zhang 			return 0;
404*3fd22dcdSYe Zhang 		}
405*3fd22dcdSYe Zhang 		break;
406*3fd22dcdSYe Zhang 
407*3fd22dcdSYe Zhang 	default:
408*3fd22dcdSYe Zhang 		ret = -EINVAL;
409*3fd22dcdSYe Zhang 		break;
410*3fd22dcdSYe Zhang 	}
411*3fd22dcdSYe Zhang 
412*3fd22dcdSYe Zhang 	if (ret) {
413*3fd22dcdSYe Zhang 		dev_err(priv->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
414*3fd22dcdSYe Zhang 
415*3fd22dcdSYe Zhang 		return ret;
416*3fd22dcdSYe Zhang 	}
417*3fd22dcdSYe Zhang 
418*3fd22dcdSYe Zhang 	*reg += ((pin_num / RK3506_SMT_PINS_PER_REG) * 4);
419*3fd22dcdSYe Zhang 	*bit = pin_num % RK3506_SMT_PINS_PER_REG;
420*3fd22dcdSYe Zhang 	*bit *= RK3506_SMT_BITS_PER_PIN;
421*3fd22dcdSYe Zhang 
422*3fd22dcdSYe Zhang 	return 0;
423*3fd22dcdSYe Zhang }
424*3fd22dcdSYe Zhang 
rk3506_set_schmitt(struct rockchip_pin_bank * bank,int pin_num,int enable)425*3fd22dcdSYe Zhang static int rk3506_set_schmitt(struct rockchip_pin_bank *bank,
426*3fd22dcdSYe Zhang 			      int pin_num, int enable)
427*3fd22dcdSYe Zhang {
428*3fd22dcdSYe Zhang 	struct regmap *regmap;
429*3fd22dcdSYe Zhang 	int reg, ret;
430*3fd22dcdSYe Zhang 	u32 data;
431*3fd22dcdSYe Zhang 	u8 bit;
432*3fd22dcdSYe Zhang 
433*3fd22dcdSYe Zhang 	ret = rk3506_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
434*3fd22dcdSYe Zhang 	if (ret)
435*3fd22dcdSYe Zhang 		return ret;
436*3fd22dcdSYe Zhang 
437*3fd22dcdSYe Zhang 	/* enable the write to the equivalent lower bits */
438*3fd22dcdSYe Zhang 	data = ((1 << RK3506_SMT_BITS_PER_PIN) - 1) << (bit + 16);
439*3fd22dcdSYe Zhang 	data |= (enable << bit);
440*3fd22dcdSYe Zhang 
441*3fd22dcdSYe Zhang 	if ((bank->bank_num == 0 && pin_num == 24) || bank->bank_num == 4) {
442*3fd22dcdSYe Zhang 		data = 0x3 << (bit + 16);
443*3fd22dcdSYe Zhang 		data |= ((enable ? 0x3 : 0) << bit);
444*3fd22dcdSYe Zhang 	}
445*3fd22dcdSYe Zhang 	ret = regmap_write(regmap, reg, data);
446*3fd22dcdSYe Zhang 
447*3fd22dcdSYe Zhang 	return ret;
448*3fd22dcdSYe Zhang }
449*3fd22dcdSYe Zhang 
450*3fd22dcdSYe Zhang static struct rockchip_mux_recalced_data rk3506_mux_recalced_data[] = {
451*3fd22dcdSYe Zhang 	{
452*3fd22dcdSYe Zhang 		.num = 0,
453*3fd22dcdSYe Zhang 		.pin = 24,
454*3fd22dcdSYe Zhang 		.reg = 0x830,
455*3fd22dcdSYe Zhang 		.bit = 0,
456*3fd22dcdSYe Zhang 		.mask = 0x3
457*3fd22dcdSYe Zhang 	},
458*3fd22dcdSYe Zhang };
459*3fd22dcdSYe Zhang 
460*3fd22dcdSYe Zhang static struct rockchip_pin_bank rk3506_pin_banks[] = {
461*3fd22dcdSYe Zhang 	PIN_BANK_IOMUX_FLAGS_OFFSET(0, 32, "gpio0",
462*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
463*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
464*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
465*3fd22dcdSYe Zhang 				    IOMUX_8WIDTH_2BIT | IOMUX_SOURCE_PMU,
466*3fd22dcdSYe Zhang 				    0x0, 0x8, 0x10, 0x830),
467*3fd22dcdSYe Zhang 	PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1",
468*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
469*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
470*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
471*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
472*3fd22dcdSYe Zhang 				    0x20, 0x28, 0x30, 0x38),
473*3fd22dcdSYe Zhang 	PIN_BANK_IOMUX_FLAGS_OFFSET(2, 32, "gpio2",
474*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
475*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
476*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
477*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
478*3fd22dcdSYe Zhang 				    0x40, 0x48, 0x50, 0x58),
479*3fd22dcdSYe Zhang 	PIN_BANK_IOMUX_FLAGS_OFFSET(3, 32, "gpio3",
480*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
481*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
482*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
483*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
484*3fd22dcdSYe Zhang 				    0x60, 0x68, 0x70, 0x78),
485*3fd22dcdSYe Zhang 	PIN_BANK_IOMUX_FLAGS_OFFSET(4, 32, "gpio4",
486*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
487*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
488*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
489*3fd22dcdSYe Zhang 				    IOMUX_WIDTH_4BIT,
490*3fd22dcdSYe Zhang 				    0x80, 0x88, 0x90, 0x98),
491*3fd22dcdSYe Zhang };
492*3fd22dcdSYe Zhang 
493*3fd22dcdSYe Zhang static const struct rockchip_pin_ctrl rk3506_pin_ctrl = {
494*3fd22dcdSYe Zhang 	.pin_banks		= rk3506_pin_banks,
495*3fd22dcdSYe Zhang 	.nr_banks		= ARRAY_SIZE(rk3506_pin_banks),
496*3fd22dcdSYe Zhang 	.nr_pins		= 160,
497*3fd22dcdSYe Zhang 	.iomux_recalced		= rk3506_mux_recalced_data,
498*3fd22dcdSYe Zhang 	.niomux_recalced	= ARRAY_SIZE(rk3506_mux_recalced_data),
499*3fd22dcdSYe Zhang 	.set_mux		= rk3506_set_mux,
500*3fd22dcdSYe Zhang 	.set_pull		= rk3506_set_pull,
501*3fd22dcdSYe Zhang 	.set_drive		= rk3506_set_drive,
502*3fd22dcdSYe Zhang 	.set_schmitt		= rk3506_set_schmitt,
503*3fd22dcdSYe Zhang };
504*3fd22dcdSYe Zhang 
505*3fd22dcdSYe Zhang static const struct udevice_id rk3506_pinctrl_ids[] = {
506*3fd22dcdSYe Zhang 	{
507*3fd22dcdSYe Zhang 		.compatible = "rockchip,rk3506-pinctrl",
508*3fd22dcdSYe Zhang 		.data = (ulong)&rk3506_pin_ctrl
509*3fd22dcdSYe Zhang 	},
510*3fd22dcdSYe Zhang 	{ }
511*3fd22dcdSYe Zhang };
512*3fd22dcdSYe Zhang 
513*3fd22dcdSYe Zhang U_BOOT_DRIVER(pinctrl_rk3506) = {
514*3fd22dcdSYe Zhang 	.name		= "rockchip_rk3506_pinctrl",
515*3fd22dcdSYe Zhang 	.id		= UCLASS_PINCTRL,
516*3fd22dcdSYe Zhang 	.of_match	= rk3506_pinctrl_ids,
517*3fd22dcdSYe Zhang 	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
518*3fd22dcdSYe Zhang 	.ops		= &rockchip_pinctrl_ops,
519*3fd22dcdSYe Zhang #if !CONFIG_IS_ENABLED(OF_PLATDATA)
520*3fd22dcdSYe Zhang 	.bind		= dm_scan_fdt_dev,
521*3fd22dcdSYe Zhang #endif
522*3fd22dcdSYe Zhang 	.probe		= rockchip_pinctrl_probe,
523*3fd22dcdSYe Zhang };
524