xref: /rk3399_rockchip-uboot/drivers/pinctrl/rockchip/pinctrl-rv1126b.c (revision b653b9e8c171365ce437eb92a7c649c314d97973)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2025 Rockchip Electronics Co., Ltd
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <dm/pinctrl.h>
9 #include <regmap.h>
10 #include <syscon.h>
11 
12 #include "pinctrl-rockchip.h"
13 
rv1126b_set_mux(struct rockchip_pin_bank * bank,int pin,int mux)14 static int rv1126b_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
15 {
16 	struct rockchip_pinctrl_priv *priv = bank->priv;
17 	int iomux_num = (pin / 8);
18 	struct regmap *regmap;
19 	int reg, ret, mask;
20 	u8 bit;
21 	u32 data;
22 
23 	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
24 
25 	regmap = priv->regmap_base;
26 	reg = bank->iomux[iomux_num].offset;
27 	if ((pin % 8) >= 4)
28 		reg += 0x4;
29 	bit = (pin % 4) * 4;
30 	mask = 0xf;
31 
32 	if (bank->recalced_mask & BIT(pin))
33 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
34 	data = (mask << (bit + 16));
35 	data |= (mux & mask) << bit;
36 
37 	debug("iomux write reg = %x data = %x\n", reg, data);
38 
39 	ret = regmap_write(regmap, reg, data);
40 
41 	return ret;
42 }
43 
44 #define RV1126B_DRV_BITS_PER_PIN		8
45 #define RV1126B_DRV_PINS_PER_REG		2
46 #define RV1126B_DRV_GPIO0_A_OFFSET		0x100
47 #define RV1126B_DRV_GPIO0_C_OFFSET		0x8120
48 #define RV1126B_DRV_GPIO_OFFSET(GPION)		(0x8100 + GPION * 0x8040)
49 
rv1126b_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)50 static int rv1126b_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
51 				       int pin_num, struct regmap **regmap,
52 				       int *reg, u8 *bit)
53 {
54 	struct rockchip_pinctrl_priv *priv = bank->priv;
55 
56 	*regmap = priv->regmap_base;
57 	switch (bank->bank_num) {
58 	case 0:
59 		if (pin_num < 16)
60 			*reg = RV1126B_DRV_GPIO0_A_OFFSET;
61 		else
62 			*reg = RV1126B_DRV_GPIO0_C_OFFSET - 0x20;
63 		break;
64 
65 	case 1:
66 	case 2:
67 	case 3:
68 	case 4:
69 	case 5:
70 	case 6:
71 	case 7:
72 		*reg = RV1126B_DRV_GPIO_OFFSET(bank->bank_num);
73 		break;
74 
75 	default:
76 		dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num);
77 
78 		return -EINVAL;
79 	}
80 
81 	*reg += ((pin_num / RV1126B_DRV_PINS_PER_REG) * 4);
82 	*bit = pin_num % RV1126B_DRV_PINS_PER_REG;
83 	*bit *= RV1126B_DRV_BITS_PER_PIN;
84 
85 	return 0;
86 }
87 
rv1126b_set_drive(struct rockchip_pin_bank * bank,int pin_num,int strength)88 static int rv1126b_set_drive(struct rockchip_pin_bank *bank,
89 			    int pin_num, int strength)
90 {
91 	struct regmap *regmap;
92 	int reg, ret;
93 	u32 data;
94 	u8 bit;
95 	int rmask_bits = RV1126B_DRV_BITS_PER_PIN;
96 
97 	ret = rv1126b_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
98 	if (ret)
99 		return ret;
100 
101 	/* enable the write to the equivalent lower bits */
102 	data = ((1 << rmask_bits) - 1) << (bit + 16);
103 	ret = (1 << (strength + 1)) - 1;
104 	data |= (ret << bit);
105 	ret = regmap_write(regmap, reg, data);
106 
107 	return ret;
108 }
109 
110 #define RV1126B_PULL_BITS_PER_PIN		2
111 #define RV1126B_PULL_PINS_PER_REG		8
112 #define RV1126B_PULL_GPIO0_A_OFFSET		0x300
113 #define RV1126B_PULL_GPIO0_C_OFFSET		0x8308
114 #define RV1126B_PULL_GPIO_OFFSET(GPION)		(0x8300 + GPION * 0x8010)
115 
rv1126b_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)116 static int rv1126b_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
117 					int pin_num, struct regmap **regmap,
118 					int *reg, u8 *bit)
119 {
120 	struct rockchip_pinctrl_priv *priv = bank->priv;
121 
122 	*regmap = priv->regmap_base;
123 	switch (bank->bank_num) {
124 	case 0:
125 		if (pin_num < 16)
126 			*reg = RV1126B_PULL_GPIO0_A_OFFSET;
127 		else
128 			*reg = RV1126B_PULL_GPIO0_C_OFFSET - 0x8;
129 		break;
130 
131 	case 1:
132 	case 2:
133 	case 3:
134 	case 4:
135 	case 5:
136 	case 6:
137 	case 7:
138 		*reg = RV1126B_PULL_GPIO_OFFSET(bank->bank_num);
139 		break;
140 
141 	default:
142 		dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num);
143 
144 		return -EINVAL;
145 	}
146 
147 	*reg += ((pin_num / RV1126B_PULL_PINS_PER_REG) * 4);
148 	*bit = pin_num % RV1126B_PULL_PINS_PER_REG;
149 	*bit *= RV1126B_PULL_BITS_PER_PIN;
150 
151 	return 0;
152 }
153 
rv1126b_set_pull(struct rockchip_pin_bank * bank,int pin_num,int pull)154 static int rv1126b_set_pull(struct rockchip_pin_bank *bank,
155 			   int pin_num, int pull)
156 {
157 	struct regmap *regmap;
158 	int reg, ret;
159 	u8 bit, type;
160 	u32 data;
161 
162 	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
163 		return -ENOTSUPP;
164 
165 	ret = rv1126b_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
166 	if (ret)
167 		return ret;
168 	type = bank->pull_type[pin_num / 8];
169 
170 	ret = rockchip_translate_pull_value(type, pull);
171 	if (ret < 0) {
172 		debug("unsupported pull setting %d\n", pull);
173 
174 		return ret;
175 	}
176 
177 	/* enable the write to the equivalent lower bits */
178 	data = ((1 << RV1126B_PULL_BITS_PER_PIN) - 1) << (bit + 16);
179 	data |= (ret << bit);
180 	ret = regmap_write(regmap, reg, data);
181 
182 	return ret;
183 }
184 
185 #define RV1126B_SMT_BITS_PER_PIN		1
186 #define RV1126B_SMT_PINS_PER_REG		8
187 #define RV1126B_SMT_GPIO0_A_OFFSET		0x500
188 #define RV1126B_SMT_GPIO0_C_OFFSET		0x8508
189 #define RV1126B_SMT_GPIO_OFFSET(GPION)		(0x8500 + GPION * 0x8010)
190 
rv1126b_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)191 static int rv1126b_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
192 					   int pin_num,
193 					   struct regmap **regmap,
194 					   int *reg, u8 *bit)
195 {
196 	struct rockchip_pinctrl_priv *priv = bank->priv;
197 
198 	*regmap = priv->regmap_base;
199 	switch (bank->bank_num) {
200 	case 0:
201 		if (pin_num < 16)
202 			*reg = RV1126B_SMT_GPIO0_A_OFFSET;
203 		else
204 			*reg = RV1126B_SMT_GPIO0_C_OFFSET - 0x8;
205 		break;
206 
207 	case 1:
208 	case 2:
209 	case 3:
210 	case 4:
211 	case 5:
212 	case 6:
213 	case 7:
214 		*reg = RV1126B_SMT_GPIO_OFFSET(bank->bank_num);
215 		break;
216 
217 	default:
218 		dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num);
219 		return -EINVAL;
220 	}
221 
222 	*reg += ((pin_num / RV1126B_SMT_PINS_PER_REG) * 4);
223 	*bit = pin_num % RV1126B_SMT_PINS_PER_REG;
224 	*bit *= RV1126B_SMT_BITS_PER_PIN;
225 
226 	return 0;
227 }
228 
rv1126b_set_schmitt(struct rockchip_pin_bank * bank,int pin_num,int enable)229 static int rv1126b_set_schmitt(struct rockchip_pin_bank *bank,
230 			      int pin_num, int enable)
231 {
232 	struct regmap *regmap;
233 	int reg, ret;
234 	u32 data;
235 	u8 bit;
236 
237 	ret = rv1126b_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
238 	if (ret)
239 		return ret;
240 
241 	/* enable the write to the equivalent lower bits */
242 	data = ((1 << RV1126B_SMT_BITS_PER_PIN) - 1) << (bit + 16);
243 	data |= (enable << bit);
244 	ret = regmap_write(regmap, reg, data);
245 
246 	return ret;
247 }
248 
249 static struct rockchip_pin_bank rv1126b_pin_banks[] = {
250 	PIN_BANK_IOMUX_4_OFFSET(0, 32, "gpio0",
251 				      0x0, 0x8, 0x8010, 0x8018),
252 	PIN_BANK_IOMUX_4_OFFSET(1, 32, "gpio1",
253 				      0x10020, 0x10028, 0x10030, 0x10038),
254 	PIN_BANK_IOMUX_4_OFFSET(2, 32, "gpio2",
255 				      0x18040, 0x18048, 0x18050, 0x18058),
256 	PIN_BANK_IOMUX_4_OFFSET(3, 32, "gpio3",
257 				      0x20060, 0x20068, 0x20070, 0x20078),
258 	PIN_BANK_IOMUX_4_OFFSET(4, 32, "gpio4",
259 				      0x28080, 0x28088, 0x28090, 0x28098),
260 	PIN_BANK_IOMUX_4_OFFSET(5, 32, "gpio5",
261 				      0x300a0, 0x300a8, 0x300b0, 0x300b8),
262 	PIN_BANK_IOMUX_4_OFFSET(6, 32, "gpio6",
263 				      0x380c0, 0x380c8, 0x380d0, 0x380d8),
264 	PIN_BANK_IOMUX_4_OFFSET(7, 32, "gpio7",
265 				      0x400e0, 0x400e8, 0x400f0, 0x400f8),
266 };
267 static struct rockchip_pin_ctrl rv1126b_pin_ctrl __maybe_unused = {
268 	.pin_banks		= rv1126b_pin_banks,
269 	.nr_banks		= ARRAY_SIZE(rv1126b_pin_banks),
270 	.nr_pins		= 256,
271 	.set_mux		= rv1126b_set_mux,
272 	.set_pull		= rv1126b_set_pull,
273 	.set_drive		= rv1126b_set_drive,
274 	.set_schmitt		= rv1126b_set_schmitt,
275 };
276 
277 static const struct udevice_id rv1126b_pinctrl_ids[] = {
278 	{
279 		.compatible = "rockchip,rv1126b-pinctrl",
280 		.data = (ulong)&rv1126b_pin_ctrl
281 	},
282 	{ }
283 };
284 
285 U_BOOT_DRIVER(pinctrl_rv1126b) = {
286 	.name		= "rockchip_rv1126b_pinctrl",
287 	.id		= UCLASS_PINCTRL,
288 	.of_match	= rv1126b_pinctrl_ids,
289 	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
290 	.ops		= &rockchip_pinctrl_ops,
291 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
292 	.bind		= dm_scan_fdt_dev,
293 #endif
294 	.probe		= rockchip_pinctrl_probe,
295 };
296