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, ®, &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, ®map, ®, &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, ®map, ®, &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, ®map, ®, &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