package: add fitblk util to release /dev/fit* devices
[openwrt/staging/dangole.git] / target / linux / mediatek / patches-5.15 / 822-v5.16-pinctrl-mediatek-support-rsel-feature.patch
1 From fb34a9ae383ae26326d4889fd2513e49f1019b88 Mon Sep 17 00:00:00 2001
2 From: Zhiyong Tao <zhiyong.tao@mediatek.com>
3 Date: Fri, 24 Sep 2021 16:06:31 +0800
4 Subject: [PATCH] pinctrl: mediatek: support rsel feature
5
6 This patch supports rsel(resistance selection) feature for I2C pins.
7 It provides more resistance selection solution in different ICs.
8 It provides rsel define and si unit solution by identifying
9 "mediatek,rsel_resistance_in_si_unit" property in pio dtsi node.
10
11 Signed-off-by: Zhiyong Tao <zhiyong.tao@mediatek.com>
12 Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
13 Link: https://lore.kernel.org/r/20210924080632.28410-5-zhiyong.tao@mediatek.com
14 Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
15 ---
16 .../pinctrl/mediatek/pinctrl-mtk-common-v2.c | 231 +++++++++++++++---
17 .../pinctrl/mediatek/pinctrl-mtk-common-v2.h | 46 ++++
18 drivers/pinctrl/mediatek/pinctrl-paris.c | 60 +++--
19 3 files changed, 289 insertions(+), 48 deletions(-)
20
21 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
22 +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
23 @@ -665,6 +665,181 @@ out:
24 return err;
25 }
26
27 +static int mtk_hw_pin_rsel_lookup(struct mtk_pinctrl *hw,
28 + const struct mtk_pin_desc *desc,
29 + u32 pullup, u32 arg, u32 *rsel_val)
30 +{
31 + const struct mtk_pin_rsel *rsel;
32 + int check;
33 + bool found = false;
34 +
35 + rsel = hw->soc->pin_rsel;
36 +
37 + for (check = 0; check <= hw->soc->npin_rsel - 1; check++) {
38 + if (desc->number >= rsel[check].s_pin &&
39 + desc->number <= rsel[check].e_pin) {
40 + if (pullup) {
41 + if (rsel[check].up_rsel == arg) {
42 + found = true;
43 + *rsel_val = rsel[check].rsel_index;
44 + break;
45 + }
46 + } else {
47 + if (rsel[check].down_rsel == arg) {
48 + found = true;
49 + *rsel_val = rsel[check].rsel_index;
50 + break;
51 + }
52 + }
53 + }
54 + }
55 +
56 + if (!found) {
57 + dev_err(hw->dev, "Not support rsel value %d Ohm for pin = %d (%s)\n",
58 + arg, desc->number, desc->name);
59 + return -ENOTSUPP;
60 + }
61 +
62 + return 0;
63 +}
64 +
65 +static int mtk_pinconf_bias_set_rsel(struct mtk_pinctrl *hw,
66 + const struct mtk_pin_desc *desc,
67 + u32 pullup, u32 arg)
68 +{
69 + int err, rsel_val;
70 +
71 + if (hw->rsel_si_unit) {
72 + /* find pin rsel_index from pin_rsel array*/
73 + err = mtk_hw_pin_rsel_lookup(hw, desc, pullup, arg, &rsel_val);
74 + if (err)
75 + goto out;
76 + } else {
77 + if (arg < MTK_PULL_SET_RSEL_000 ||
78 + arg > MTK_PULL_SET_RSEL_111) {
79 + err = -EINVAL;
80 + goto out;
81 + }
82 +
83 + rsel_val = arg - MTK_PULL_SET_RSEL_000;
84 + }
85 +
86 + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_RSEL, rsel_val);
87 + if (err)
88 + goto out;
89 +
90 + err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, MTK_ENABLE);
91 +
92 +out:
93 + return err;
94 +}
95 +
96 +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
97 + const struct mtk_pin_desc *desc,
98 + u32 pullup, u32 arg)
99 +{
100 + int err = -ENOTSUPP;
101 + u32 try_all_type;
102 +
103 + if (hw->soc->pull_type)
104 + try_all_type = hw->soc->pull_type[desc->number];
105 + else
106 + try_all_type = MTK_PULL_TYPE_MASK;
107 +
108 + if (try_all_type & MTK_PULL_RSEL_TYPE) {
109 + err = mtk_pinconf_bias_set_rsel(hw, desc, pullup, arg);
110 + if (!err)
111 + return err;
112 + }
113 +
114 + if (try_all_type & MTK_PULL_PU_PD_TYPE) {
115 + err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
116 + if (!err)
117 + return err;
118 + }
119 +
120 + if (try_all_type & MTK_PULL_PULLSEL_TYPE) {
121 + err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc,
122 + pullup, arg);
123 + if (!err)
124 + return err;
125 + }
126 +
127 + if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE)
128 + err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
129 +
130 + if (err)
131 + dev_err(hw->dev, "Invalid pull argument\n");
132 +
133 + return err;
134 +}
135 +EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo);
136 +
137 +static int mtk_rsel_get_si_unit(struct mtk_pinctrl *hw,
138 + const struct mtk_pin_desc *desc,
139 + u32 pullup, u32 rsel_val, u32 *si_unit)
140 +{
141 + const struct mtk_pin_rsel *rsel;
142 + int check;
143 +
144 + rsel = hw->soc->pin_rsel;
145 +
146 + for (check = 0; check <= hw->soc->npin_rsel - 1; check++) {
147 + if (desc->number >= rsel[check].s_pin &&
148 + desc->number <= rsel[check].e_pin) {
149 + if (rsel_val == rsel[check].rsel_index) {
150 + if (pullup)
151 + *si_unit = rsel[check].up_rsel;
152 + else
153 + *si_unit = rsel[check].down_rsel;
154 + break;
155 + }
156 + }
157 + }
158 +
159 + return 0;
160 +}
161 +
162 +static int mtk_pinconf_bias_get_rsel(struct mtk_pinctrl *hw,
163 + const struct mtk_pin_desc *desc,
164 + u32 *pullup, u32 *enable)
165 +{
166 + int pu, pd, rsel, err;
167 +
168 + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_RSEL, &rsel);
169 + if (err)
170 + goto out;
171 +
172 + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
173 + if (err)
174 + goto out;
175 +
176 + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
177 +
178 + if (pu == 0 && pd == 0) {
179 + *pullup = 0;
180 + *enable = MTK_DISABLE;
181 + } else if (pu == 1 && pd == 0) {
182 + *pullup = 1;
183 + if (hw->rsel_si_unit)
184 + mtk_rsel_get_si_unit(hw, desc, *pullup, rsel, enable);
185 + else
186 + *enable = rsel + MTK_PULL_SET_RSEL_000;
187 + } else if (pu == 0 && pd == 1) {
188 + *pullup = 0;
189 + if (hw->rsel_si_unit)
190 + mtk_rsel_get_si_unit(hw, desc, *pullup, rsel, enable);
191 + else
192 + *enable = rsel + MTK_PULL_SET_RSEL_000;
193 + } else {
194 + err = -EINVAL;
195 + goto out;
196 + }
197 +
198 +out:
199 + return err;
200 +}
201 +
202 static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
203 const struct mtk_pin_desc *desc,
204 u32 *pullup, u32 *enable)
205 @@ -746,44 +921,40 @@ out:
206 return err;
207 }
208
209 -int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
210 - const struct mtk_pin_desc *desc,
211 - u32 pullup, u32 arg)
212 -{
213 - int err;
214 -
215 - err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
216 - if (!err)
217 - goto out;
218 -
219 - err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
220 - if (!err)
221 - goto out;
222 -
223 - err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
224 -
225 -out:
226 - return err;
227 -}
228 -EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo);
229 -
230 int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
231 const struct mtk_pin_desc *desc,
232 u32 *pullup, u32 *enable)
233 {
234 - int err;
235 + int err = -ENOTSUPP;
236 + u32 try_all_type;
237
238 - err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
239 - if (!err)
240 - goto out;
241 + if (hw->soc->pull_type)
242 + try_all_type = hw->soc->pull_type[desc->number];
243 + else
244 + try_all_type = MTK_PULL_TYPE_MASK;
245
246 - err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
247 - if (!err)
248 - goto out;
249 + if (try_all_type & MTK_PULL_RSEL_TYPE) {
250 + err = mtk_pinconf_bias_get_rsel(hw, desc, pullup, enable);
251 + if (!err)
252 + return err;
253 + }
254 +
255 + if (try_all_type & MTK_PULL_PU_PD_TYPE) {
256 + err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
257 + if (!err)
258 + return err;
259 + }
260 +
261 + if (try_all_type & MTK_PULL_PULLSEL_TYPE) {
262 + err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc,
263 + pullup, enable);
264 + if (!err)
265 + return err;
266 + }
267
268 - err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
269 + if (try_all_type & MTK_PULL_PUPD_R1R0_TYPE)
270 + err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
271
272 -out:
273 return err;
274 }
275 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_combo);
276 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
277 +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
278 @@ -17,6 +17,22 @@
279 #define MTK_ENABLE 1
280 #define MTK_PULLDOWN 0
281 #define MTK_PULLUP 1
282 +#define MTK_PULL_PU_PD_TYPE BIT(0)
283 +#define MTK_PULL_PULLSEL_TYPE BIT(1)
284 +#define MTK_PULL_PUPD_R1R0_TYPE BIT(2)
285 +/* MTK_PULL_RSEL_TYPE can select resistance and can be
286 + * turned on/off itself. But it can't be selected pull up/down
287 + */
288 +#define MTK_PULL_RSEL_TYPE BIT(3)
289 +/* MTK_PULL_PU_PD_RSEL_TYPE is a type which is controlled by
290 + * MTK_PULL_PU_PD_TYPE and MTK_PULL_RSEL_TYPE.
291 + */
292 +#define MTK_PULL_PU_PD_RSEL_TYPE (MTK_PULL_PU_PD_TYPE \
293 + | MTK_PULL_RSEL_TYPE)
294 +#define MTK_PULL_TYPE_MASK (MTK_PULL_PU_PD_TYPE |\
295 + MTK_PULL_PULLSEL_TYPE |\
296 + MTK_PULL_PUPD_R1R0_TYPE |\
297 + MTK_PULL_RSEL_TYPE)
298
299 #define EINT_NA U16_MAX
300 #define NO_EINT_SUPPORT EINT_NA
301 @@ -42,6 +58,14 @@
302 PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit, \
303 _x_bits, 32, 1)
304
305 +#define PIN_RSEL(_s_pin, _e_pin, _rsel_index, _up_resl, _down_rsel) { \
306 + .s_pin = _s_pin, \
307 + .e_pin = _e_pin, \
308 + .rsel_index = _rsel_index, \
309 + .up_rsel = _up_resl, \
310 + .down_rsel = _down_rsel, \
311 + }
312 +
313 /* List these attributes which could be modified for the pin */
314 enum {
315 PINCTRL_PIN_REG_MODE,
316 @@ -67,6 +91,7 @@ enum {
317 PINCTRL_PIN_REG_DRV_E0,
318 PINCTRL_PIN_REG_DRV_E1,
319 PINCTRL_PIN_REG_DRV_ADV,
320 + PINCTRL_PIN_REG_RSEL,
321 PINCTRL_PIN_REG_MAX,
322 };
323
324 @@ -129,6 +154,22 @@ struct mtk_pin_field_calc {
325 u8 fixed;
326 };
327
328 +/**
329 + * struct mtk_pin_rsel - the structure that provides bias resistance selection.
330 + * @s_pin: the start pin within the rsel range
331 + * @e_pin: the end pin within the rsel range
332 + * @rsel_index: the rsel bias resistance index
333 + * @up_rsel: the pullup rsel bias resistance value
334 + * @down_rsel: the pulldown rsel bias resistance value
335 + */
336 +struct mtk_pin_rsel {
337 + u16 s_pin;
338 + u16 e_pin;
339 + u16 rsel_index;
340 + u32 up_rsel;
341 + u32 down_rsel;
342 +};
343 +
344 /* struct mtk_pin_reg_calc - the structure that holds all ranges used to
345 * determine which register the pin would make use of
346 * for certain pin attribute.
347 @@ -206,6 +247,9 @@ struct mtk_pin_soc {
348 bool ies_present;
349 const char * const *base_names;
350 unsigned int nbase_names;
351 + const unsigned int *pull_type;
352 + const struct mtk_pin_rsel *pin_rsel;
353 + unsigned int npin_rsel;
354
355 /* Specific pinconfig operations */
356 int (*bias_disable_set)(struct mtk_pinctrl *hw,
357 @@ -254,6 +298,8 @@ struct mtk_pinctrl {
358 const char **grp_names;
359 /* lock pin's register resource to avoid multiple threads issue*/
360 spinlock_t lock;
361 + /* identify rsel setting by si unit or rsel define in dts node */
362 + bool rsel_si_unit;
363 };
364
365 void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set);
366 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
367 +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
368 @@ -574,8 +574,9 @@ static int mtk_hw_get_value_wrap(struct
369 ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
370 unsigned int gpio, char *buf, unsigned int buf_len)
371 {
372 - int pinmux, pullup = 0, pullen = 0, len = 0, r1 = -1, r0 = -1;
373 + int pinmux, pullup = 0, pullen = 0, len = 0, r1 = -1, r0 = -1, rsel = -1;
374 const struct mtk_pin_desc *desc;
375 + u32 try_all_type;
376
377 if (gpio >= hw->soc->npins)
378 return -EINVAL;
379 @@ -589,24 +590,39 @@ ssize_t mtk_pctrl_show_one_pin(struct mt
380 pinmux -= hw->soc->nfuncs;
381
382 mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
383 - if (pullen == MTK_PUPD_SET_R1R0_00) {
384 - pullen = 0;
385 - r1 = 0;
386 - r0 = 0;
387 - } else if (pullen == MTK_PUPD_SET_R1R0_01) {
388 - pullen = 1;
389 - r1 = 0;
390 - r0 = 1;
391 - } else if (pullen == MTK_PUPD_SET_R1R0_10) {
392 - pullen = 1;
393 - r1 = 1;
394 - r0 = 0;
395 - } else if (pullen == MTK_PUPD_SET_R1R0_11) {
396 +
397 + if (hw->soc->pull_type)
398 + try_all_type = hw->soc->pull_type[desc->number];
399 +
400 + if (hw->rsel_si_unit && (try_all_type & MTK_PULL_RSEL_TYPE)) {
401 + rsel = pullen;
402 pullen = 1;
403 - r1 = 1;
404 - r0 = 1;
405 - } else if (pullen != MTK_DISABLE && pullen != MTK_ENABLE) {
406 - pullen = 0;
407 + } else {
408 + /* Case for: R1R0 */
409 + if (pullen == MTK_PUPD_SET_R1R0_00) {
410 + pullen = 0;
411 + r1 = 0;
412 + r0 = 0;
413 + } else if (pullen == MTK_PUPD_SET_R1R0_01) {
414 + pullen = 1;
415 + r1 = 0;
416 + r0 = 1;
417 + } else if (pullen == MTK_PUPD_SET_R1R0_10) {
418 + pullen = 1;
419 + r1 = 1;
420 + r0 = 0;
421 + } else if (pullen == MTK_PUPD_SET_R1R0_11) {
422 + pullen = 1;
423 + r1 = 1;
424 + r0 = 1;
425 + }
426 +
427 + /* Case for: RSEL */
428 + if (pullen >= MTK_PULL_SET_RSEL_000 &&
429 + pullen <= MTK_PULL_SET_RSEL_111) {
430 + rsel = pullen - MTK_PULL_SET_RSEL_000;
431 + pullen = 1;
432 + }
433 }
434 len += scnprintf(buf + len, buf_len - len,
435 "%03d: %1d%1d%1d%1d%02d%1d%1d%1d%1d",
436 @@ -624,6 +640,8 @@ ssize_t mtk_pctrl_show_one_pin(struct mt
437 if (r1 != -1) {
438 len += scnprintf(buf + len, buf_len - len, " (%1d %1d)\n",
439 r1, r0);
440 + } else if (rsel != -1) {
441 + len += scnprintf(buf + len, buf_len - len, " (%1d)\n", rsel);
442 } else {
443 len += scnprintf(buf + len, buf_len - len, "\n");
444 }
445 @@ -966,6 +984,12 @@ int mtk_paris_pinctrl_probe(struct platf
446
447 hw->nbase = hw->soc->nbase_names;
448
449 + if (of_find_property(hw->dev->of_node,
450 + "mediatek,rsel_resistance_in_si_unit", NULL))
451 + hw->rsel_si_unit = true;
452 + else
453 + hw->rsel_si_unit = false;
454 +
455 spin_lock_init(&hw->lock);
456
457 err = mtk_pctrl_build_state(pdev);