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