blob: 4ae328699e2ef60df042fd6649b5bdfd6a9213c9 [file] [log] [blame]
developer84c7a632018-11-15 10:07:58 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2018 MediaTek Inc.
4 * Author: Ryder Lee <ryder.lee@mediatek.com>
5 */
6
7#include <common.h>
8#include <dm.h>
9#include <dm/device-internal.h>
10#include <dm/lists.h>
11#include <dm/pinctrl.h>
12#include <asm/io.h>
13#include <asm-generic/gpio.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060014#include <linux/bitops.h>
developer84c7a632018-11-15 10:07:58 +080015
16#include "pinctrl-mtk-common.h"
17
Fabien Parent105f6c82019-07-18 19:08:08 +020018#if CONFIG_IS_ENABLED(PINCONF)
developer84c7a632018-11-15 10:07:58 +080019/**
20 * struct mtk_drive_desc - the structure that holds the information
21 * of the driving current
22 * @min: the minimum current of this group
23 * @max: the maximum current of this group
24 * @step: the step current of this group
25 * @scal: the weight factor
26 *
27 * formula: output = ((input) / step - 1) * scal
28 */
29struct mtk_drive_desc {
30 u8 min;
31 u8 max;
32 u8 step;
33 u8 scal;
34};
35
36/* The groups of drive strength */
37static const struct mtk_drive_desc mtk_drive[] = {
38 [DRV_GRP0] = { 4, 16, 4, 1 },
39 [DRV_GRP1] = { 4, 16, 4, 2 },
40 [DRV_GRP2] = { 2, 8, 2, 1 },
41 [DRV_GRP3] = { 2, 8, 2, 2 },
42 [DRV_GRP4] = { 2, 16, 2, 1 },
43};
Fabien Parent105f6c82019-07-18 19:08:08 +020044#endif
developer84c7a632018-11-15 10:07:58 +080045
46static const char *mtk_pinctrl_dummy_name = "_dummy";
47
48static void mtk_w32(struct udevice *dev, u32 reg, u32 val)
49{
50 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
51
52 __raw_writel(val, priv->base + reg);
53}
54
55static u32 mtk_r32(struct udevice *dev, u32 reg)
56{
57 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
58
59 return __raw_readl(priv->base + reg);
60}
61
62static inline int get_count_order(unsigned int count)
63{
64 int order;
65
66 order = fls(count) - 1;
67 if (count & (count - 1))
68 order++;
69 return order;
70}
71
72void mtk_rmw(struct udevice *dev, u32 reg, u32 mask, u32 set)
73{
74 u32 val;
75
76 val = mtk_r32(dev, reg);
77 val &= ~mask;
78 val |= set;
79 mtk_w32(dev, reg, val);
80}
81
82static int mtk_hw_pin_field_lookup(struct udevice *dev, int pin,
83 const struct mtk_pin_reg_calc *rc,
84 struct mtk_pin_field *pfd)
85{
86 const struct mtk_pin_field_calc *c, *e;
87 u32 bits;
88
89 c = rc->range;
90 e = c + rc->nranges;
91
92 while (c < e) {
93 if (pin >= c->s_pin && pin <= c->e_pin)
94 break;
95 c++;
96 }
97
98 if (c >= e)
99 return -EINVAL;
100
101 /* Calculated bits as the overall offset the pin is located at,
102 * if c->fixed is held, that determines the all the pins in the
103 * range use the same field with the s_pin.
104 */
105 bits = c->fixed ? c->s_bit : c->s_bit + (pin - c->s_pin) * (c->x_bits);
106
107 /* Fill pfd from bits. For example 32-bit register applied is assumed
108 * when c->sz_reg is equal to 32.
109 */
110 pfd->offset = c->s_addr + c->x_addrs * (bits / c->sz_reg);
111 pfd->bitpos = bits % c->sz_reg;
112 pfd->mask = (1 << c->x_bits) - 1;
113
114 /* pfd->next is used for indicating that bit wrapping-around happens
115 * which requires the manipulation for bit 0 starting in the next
116 * register to form the complete field read/write.
117 */
118 pfd->next = pfd->bitpos + c->x_bits > c->sz_reg ? c->x_addrs : 0;
119
120 return 0;
121}
122
123static int mtk_hw_pin_field_get(struct udevice *dev, int pin,
124 int field, struct mtk_pin_field *pfd)
125{
126 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
127 const struct mtk_pin_reg_calc *rc;
128
129 if (field < 0 || field >= PINCTRL_PIN_REG_MAX)
130 return -EINVAL;
131
132 if (priv->soc->reg_cal && priv->soc->reg_cal[field].range)
133 rc = &priv->soc->reg_cal[field];
134 else
135 return -EINVAL;
136
137 return mtk_hw_pin_field_lookup(dev, pin, rc, pfd);
138}
139
140static void mtk_hw_bits_part(struct mtk_pin_field *pf, int *h, int *l)
141{
142 *l = 32 - pf->bitpos;
143 *h = get_count_order(pf->mask) - *l;
144}
145
146static void mtk_hw_write_cross_field(struct udevice *dev,
147 struct mtk_pin_field *pf, int value)
148{
149 int nbits_l, nbits_h;
150
151 mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
152
153 mtk_rmw(dev, pf->offset, pf->mask << pf->bitpos,
154 (value & pf->mask) << pf->bitpos);
155
156 mtk_rmw(dev, pf->offset + pf->next, BIT(nbits_h) - 1,
157 (value & pf->mask) >> nbits_l);
158}
159
160static void mtk_hw_read_cross_field(struct udevice *dev,
161 struct mtk_pin_field *pf, int *value)
162{
163 int nbits_l, nbits_h, h, l;
164
165 mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
166
167 l = (mtk_r32(dev, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1);
168 h = (mtk_r32(dev, pf->offset + pf->next)) & (BIT(nbits_h) - 1);
169
170 *value = (h << nbits_l) | l;
171}
172
173static int mtk_hw_set_value(struct udevice *dev, int pin, int field,
174 int value)
175{
176 struct mtk_pin_field pf;
177 int err;
178
179 err = mtk_hw_pin_field_get(dev, pin, field, &pf);
180 if (err)
181 return err;
182
183 if (!pf.next)
184 mtk_rmw(dev, pf.offset, pf.mask << pf.bitpos,
185 (value & pf.mask) << pf.bitpos);
186 else
187 mtk_hw_write_cross_field(dev, &pf, value);
188
189 return 0;
190}
191
192static int mtk_hw_get_value(struct udevice *dev, int pin, int field,
193 int *value)
194{
195 struct mtk_pin_field pf;
196 int err;
197
198 err = mtk_hw_pin_field_get(dev, pin, field, &pf);
199 if (err)
200 return err;
201
202 if (!pf.next)
203 *value = (mtk_r32(dev, pf.offset) >> pf.bitpos) & pf.mask;
204 else
205 mtk_hw_read_cross_field(dev, &pf, value);
206
207 return 0;
208}
209
210static int mtk_get_groups_count(struct udevice *dev)
211{
212 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
213
214 return priv->soc->ngrps;
215}
216
217static const char *mtk_get_pin_name(struct udevice *dev,
218 unsigned int selector)
219{
220 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
221
developerdeb84062021-03-05 10:22:11 +0800222 if (!priv->soc->pins[selector].name)
developer84c7a632018-11-15 10:07:58 +0800223 return mtk_pinctrl_dummy_name;
224
225 return priv->soc->pins[selector].name;
226}
227
228static int mtk_get_pins_count(struct udevice *dev)
229{
230 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
231
232 return priv->soc->npins;
233}
234
developer0163c082021-03-05 10:22:19 +0800235static int mtk_get_pin_muxing(struct udevice *dev, unsigned int selector,
236 char *buf, int size)
237{
238 int val, err;
239
240 err = mtk_hw_get_value(dev, selector, PINCTRL_PIN_REG_MODE, &val);
241 if (err)
242 return err;
243
244 snprintf(buf, size, "Aux Func.%d", val);
245 return 0;
246}
247
developer84c7a632018-11-15 10:07:58 +0800248static const char *mtk_get_group_name(struct udevice *dev,
249 unsigned int selector)
250{
251 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
252
253 if (!priv->soc->grps[selector].name)
254 return mtk_pinctrl_dummy_name;
255
256 return priv->soc->grps[selector].name;
257}
258
259static int mtk_get_functions_count(struct udevice *dev)
260{
261 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
262
263 return priv->soc->nfuncs;
264}
265
266static const char *mtk_get_function_name(struct udevice *dev,
267 unsigned int selector)
268{
269 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
270
271 if (!priv->soc->funcs[selector].name)
272 return mtk_pinctrl_dummy_name;
273
274 return priv->soc->funcs[selector].name;
275}
276
277static int mtk_pinmux_group_set(struct udevice *dev,
278 unsigned int group_selector,
279 unsigned int func_selector)
280{
281 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
282 const struct mtk_group_desc *grp =
283 &priv->soc->grps[group_selector];
284 int i;
285
286 for (i = 0; i < grp->num_pins; i++) {
287 int *pin_modes = grp->data;
288
289 mtk_hw_set_value(dev, grp->pins[i], PINCTRL_PIN_REG_MODE,
290 pin_modes[i]);
291 }
292
293 return 0;
294}
295
296#if CONFIG_IS_ENABLED(PINCONF)
297static const struct pinconf_param mtk_conf_params[] = {
298 { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
299 { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
300 { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
301 { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
302 { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
303 { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
304 { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
305 { "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
306 { "output-high", PIN_CONFIG_OUTPUT, 1, },
307 { "output-low", PIN_CONFIG_OUTPUT, 0, },
308 { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
309};
310
developer6e84c2f2022-04-21 14:23:51 +0800311int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, bool disable,
312 bool pullup, u32 val)
313{
314 return mtk_pinconf_bias_set_pu_pd(dev, pin, disable, pullup, val);
315}
developer74d69012020-01-10 16:30:28 +0800316
developer6e84c2f2022-04-21 14:23:51 +0800317int mtk_pinconf_bias_set_v1(struct udevice *dev, u32 pin, bool disable,
318 bool pullup, u32 val)
developer74d69012020-01-10 16:30:28 +0800319{
developer6e84c2f2022-04-21 14:23:51 +0800320 int err;
developer74d69012020-01-10 16:30:28 +0800321
developer6e84c2f2022-04-21 14:23:51 +0800322 /* try pupd_r1_r0 if pullen_pullsel return error */
323 err = mtk_pinconf_bias_set_pullen_pullsel(dev, pin, disable, pullup,
324 val);
325 if (err)
326 return mtk_pinconf_bias_set_pupd_r1_r0(dev, pin, disable,
327 pullup, val);
328
329 return err;
330}
331
332int mtk_pinconf_bias_set_pu_pd(struct udevice *dev, u32 pin, bool disable,
333 bool pullup, u32 val)
334{
335 int err;
developer74d69012020-01-10 16:30:28 +0800336
337 if (disable) {
338 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PU, 0);
339 if (err)
340 return err;
341 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PD, 0);
342 if (err)
343 return err;
developer74d69012020-01-10 16:30:28 +0800344 } else {
345 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PU, pullup);
346 if (err)
347 return err;
348 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PD, !pullup);
349 if (err)
350 return err;
351 }
352
353 return 0;
354}
355
developer6e84c2f2022-04-21 14:23:51 +0800356int mtk_pinconf_bias_set_pullen_pullsel(struct udevice *dev, u32 pin,
357 bool disable, bool pullup, u32 val)
developer74d69012020-01-10 16:30:28 +0800358{
developer6e84c2f2022-04-21 14:23:51 +0800359 int err;
developer74d69012020-01-10 16:30:28 +0800360
361 if (disable) {
362 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN, 0);
363 if (err)
364 return err;
365 } else {
366 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN, 1);
367 if (err)
368 return err;
369 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLSEL,
370 pullup);
371 if (err)
372 return err;
373 }
374
developer6e84c2f2022-04-21 14:23:51 +0800375 return 0;
376}
377
378int mtk_pinconf_bias_set_pupd_r1_r0(struct udevice *dev, u32 pin, bool disable,
379 bool pullup, u32 val)
380{
381 int err, r0, r1;
382
383 r0 = !!(val & 1);
384 r1 = !!(val & 2);
385
386 if (disable) {
387 pullup = 0;
388 r0 = 0;
389 r1 = 0;
David Woodhouse32102752020-06-19 12:40:20 +0100390 }
391
developer6e84c2f2022-04-21 14:23:51 +0800392 /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
393 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PUPD, !pullup);
394 if (err)
395 return err;
396
397 /* Also set PUPD/R0/R1 if the pin has them */
398 mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_R0, r0);
399 mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_R1, r1);
400
developer74d69012020-01-10 16:30:28 +0800401 return 0;
402}
403
developer6e84c2f2022-04-21 14:23:51 +0800404int mtk_pinconf_bias_set(struct udevice *dev, u32 pin, u32 arg, u32 val)
405{
406 int err;
407 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
408 int rev = priv->soc->rev;
409 bool disable, pullup;
410
411 disable = (arg == PIN_CONFIG_BIAS_DISABLE);
412 pullup = (arg == PIN_CONFIG_BIAS_PULL_UP);
413
414 if (rev == MTK_PINCTRL_V0)
415 err = mtk_pinconf_bias_set_v0(dev, pin, disable, pullup, val);
416 else
417 err = mtk_pinconf_bias_set_v1(dev, pin, disable, pullup, val);
418
419 return err;
420}
421
developer74d69012020-01-10 16:30:28 +0800422int mtk_pinconf_input_enable_v1(struct udevice *dev, u32 pin, u32 arg)
423{
424 int err;
425
426 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_IES, 1);
427 if (err)
428 return err;
429 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 0);
430 if (err)
431 return err;
developer6e84c2f2022-04-21 14:23:51 +0800432
developer74d69012020-01-10 16:30:28 +0800433 return 0;
434}
435
developer6e84c2f2022-04-21 14:23:51 +0800436int mtk_pinconf_input_enable(struct udevice *dev, u32 pin, u32 arg)
437{
438 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
439 int rev = priv->soc->rev;
440
441 if (rev == MTK_PINCTRL_V1)
442 return mtk_pinconf_input_enable_v1(dev, pin, arg);
443
444 return 0;
445}
446
developer74d69012020-01-10 16:30:28 +0800447int mtk_pinconf_drive_set_v0(struct udevice *dev, u32 pin, u32 arg)
developer84c7a632018-11-15 10:07:58 +0800448{
449 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
450 const struct mtk_pin_desc *desc = &priv->soc->pins[pin];
451 const struct mtk_drive_desc *tb;
452 int err = -ENOTSUPP;
453
454 tb = &mtk_drive[desc->drv_n];
455 /* 4mA when (e8, e4) = (0, 0)
456 * 8mA when (e8, e4) = (0, 1)
457 * 12mA when (e8, e4) = (1, 0)
458 * 16mA when (e8, e4) = (1, 1)
459 */
460 if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
461 arg = (arg / tb->step - 1) * tb->scal;
developer74d69012020-01-10 16:30:28 +0800462 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_E4,
463 arg & 0x1);
464 if (err)
465 return err;
466 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_E8,
467 (arg & 0x2) >> 1);
468 if (err)
469 return err;
470 }
471
472 return 0;
473}
developer84c7a632018-11-15 10:07:58 +0800474
developer74d69012020-01-10 16:30:28 +0800475int mtk_pinconf_drive_set_v1(struct udevice *dev, u32 pin, u32 arg)
476{
477 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
478 const struct mtk_pin_desc *desc = &priv->soc->pins[pin];
479 const struct mtk_drive_desc *tb;
480 int err = -ENOTSUPP;
481
482 tb = &mtk_drive[desc->drv_n];
483 if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
484 arg = (arg / tb->step - 1) * tb->scal;
developer84c7a632018-11-15 10:07:58 +0800485 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DRV, arg);
486 if (err)
487 return err;
488 }
489
490 return 0;
491}
492
developer6e84c2f2022-04-21 14:23:51 +0800493int mtk_pinconf_drive_set(struct udevice *dev, u32 pin, u32 arg)
494{
495 int err;
496 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
497 int rev = priv->soc->rev;
498
499 if (rev == MTK_PINCTRL_V0)
500 err = mtk_pinconf_drive_set_v0(dev, pin, arg);
501 else
502 err = mtk_pinconf_drive_set_v1(dev, pin, arg);
503
504 return err;
505}
506
developer84c7a632018-11-15 10:07:58 +0800507static int mtk_pinconf_set(struct udevice *dev, unsigned int pin,
508 unsigned int param, unsigned int arg)
509{
510 int err = 0;
511
512 switch (param) {
513 case PIN_CONFIG_BIAS_DISABLE:
514 case PIN_CONFIG_BIAS_PULL_UP:
515 case PIN_CONFIG_BIAS_PULL_DOWN:
developer6e84c2f2022-04-21 14:23:51 +0800516 err = mtk_pinconf_bias_set(dev, pin, param, arg);
developer84c7a632018-11-15 10:07:58 +0800517 if (err)
518 goto err;
519 break;
520 case PIN_CONFIG_OUTPUT_ENABLE:
521 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_SMT, 0);
522 if (err)
523 goto err;
524 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 1);
525 if (err)
526 goto err;
527 break;
528 case PIN_CONFIG_INPUT_ENABLE:
developer6e84c2f2022-04-21 14:23:51 +0800529 err = mtk_pinconf_input_enable(dev, pin, param);
developer84c7a632018-11-15 10:07:58 +0800530 if (err)
531 goto err;
532 break;
533 case PIN_CONFIG_OUTPUT:
534 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 1);
535 if (err)
536 goto err;
537
538 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DO, arg);
539 if (err)
540 goto err;
541 break;
542 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
543 /* arg = 1: Input mode & SMT enable ;
544 * arg = 0: Output mode & SMT disable
545 */
546 arg = arg ? 2 : 1;
547 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR,
548 arg & 1);
549 if (err)
550 goto err;
551
552 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_SMT,
553 !!(arg & 2));
554 if (err)
555 goto err;
556 break;
557 case PIN_CONFIG_DRIVE_STRENGTH:
developer6e84c2f2022-04-21 14:23:51 +0800558 err = mtk_pinconf_drive_set(dev, pin, arg);
developer84c7a632018-11-15 10:07:58 +0800559 if (err)
560 goto err;
561 break;
562
563 default:
564 err = -ENOTSUPP;
565 }
566
567err:
568
569 return err;
570}
571
572static int mtk_pinconf_group_set(struct udevice *dev,
573 unsigned int group_selector,
574 unsigned int param, unsigned int arg)
575{
576 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
577 const struct mtk_group_desc *grp =
578 &priv->soc->grps[group_selector];
579 int i, ret;
580
581 for (i = 0; i < grp->num_pins; i++) {
582 ret = mtk_pinconf_set(dev, grp->pins[i], param, arg);
583 if (ret)
584 return ret;
585 }
586
587 return 0;
588}
589#endif
590
591const struct pinctrl_ops mtk_pinctrl_ops = {
592 .get_pins_count = mtk_get_pins_count,
593 .get_pin_name = mtk_get_pin_name,
developer0163c082021-03-05 10:22:19 +0800594 .get_pin_muxing = mtk_get_pin_muxing,
developer84c7a632018-11-15 10:07:58 +0800595 .get_groups_count = mtk_get_groups_count,
596 .get_group_name = mtk_get_group_name,
597 .get_functions_count = mtk_get_functions_count,
598 .get_function_name = mtk_get_function_name,
599 .pinmux_group_set = mtk_pinmux_group_set,
600#if CONFIG_IS_ENABLED(PINCONF)
601 .pinconf_num_params = ARRAY_SIZE(mtk_conf_params),
602 .pinconf_params = mtk_conf_params,
603 .pinconf_set = mtk_pinconf_set,
604 .pinconf_group_set = mtk_pinconf_group_set,
605#endif
606 .set_state = pinctrl_generic_set_state,
607};
608
developerf4154da2021-03-05 10:22:26 +0800609#if CONFIG_IS_ENABLED(DM_GPIO) || \
Simon Glass035939e2021-07-10 21:14:30 -0600610 (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO))
developer84c7a632018-11-15 10:07:58 +0800611static int mtk_gpio_get(struct udevice *dev, unsigned int off)
612{
613 int val, err;
614
615 err = mtk_hw_get_value(dev->parent, off, PINCTRL_PIN_REG_DI, &val);
616 if (err)
617 return err;
618
619 return !!val;
620}
621
622static int mtk_gpio_set(struct udevice *dev, unsigned int off, int val)
623{
624 return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DO, !!val);
625}
626
627static int mtk_gpio_get_direction(struct udevice *dev, unsigned int off)
628{
629 int val, err;
630
631 err = mtk_hw_get_value(dev->parent, off, PINCTRL_PIN_REG_DIR, &val);
632 if (err)
633 return err;
634
635 return val ? GPIOF_OUTPUT : GPIOF_INPUT;
636}
637
638static int mtk_gpio_direction_input(struct udevice *dev, unsigned int off)
639{
640 return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DIR, 0);
641}
642
643static int mtk_gpio_direction_output(struct udevice *dev,
644 unsigned int off, int val)
645{
646 mtk_gpio_set(dev, off, val);
647
648 /* And set the requested value */
649 return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DIR, 1);
650}
651
652static int mtk_gpio_request(struct udevice *dev, unsigned int off,
653 const char *label)
654{
developer74d69012020-01-10 16:30:28 +0800655 struct mtk_pinctrl_priv *priv = dev_get_priv(dev->parent);
656
657 return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_MODE,
658 priv->soc->gpio_mode);
developer84c7a632018-11-15 10:07:58 +0800659}
660
661static int mtk_gpio_probe(struct udevice *dev)
662{
663 struct mtk_pinctrl_priv *priv = dev_get_priv(dev->parent);
664 struct gpio_dev_priv *uc_priv;
665
666 uc_priv = dev_get_uclass_priv(dev);
667 uc_priv->bank_name = priv->soc->name;
668 uc_priv->gpio_count = priv->soc->npins;
669
670 return 0;
671}
672
673static const struct dm_gpio_ops mtk_gpio_ops = {
674 .request = mtk_gpio_request,
675 .set_value = mtk_gpio_set,
676 .get_value = mtk_gpio_get,
677 .get_function = mtk_gpio_get_direction,
678 .direction_input = mtk_gpio_direction_input,
679 .direction_output = mtk_gpio_direction_output,
680};
681
682static struct driver mtk_gpio_driver = {
683 .name = "mediatek_gpio",
684 .id = UCLASS_GPIO,
685 .probe = mtk_gpio_probe,
686 .ops = &mtk_gpio_ops,
687};
688
689static int mtk_gpiochip_register(struct udevice *parent)
690{
691 struct uclass_driver *drv;
692 struct udevice *dev;
693 int ret;
694 ofnode node;
695
696 drv = lists_uclass_lookup(UCLASS_GPIO);
697 if (!drv)
698 return -ENOENT;
699
Heinrich Schuchardt0c67d122020-12-27 21:18:26 +0100700 ret = -ENOENT;
developer84c7a632018-11-15 10:07:58 +0800701 dev_for_each_subnode(node, parent)
702 if (ofnode_read_bool(node, "gpio-controller")) {
703 ret = 0;
704 break;
705 }
706
707 if (ret)
708 return ret;
709
710 ret = device_bind_with_driver_data(parent, &mtk_gpio_driver,
711 "mediatek_gpio", 0, node,
712 &dev);
713 if (ret)
714 return ret;
715
716 return 0;
717}
developerf4154da2021-03-05 10:22:26 +0800718#endif
developer84c7a632018-11-15 10:07:58 +0800719
720int mtk_pinctrl_common_probe(struct udevice *dev,
721 struct mtk_pinctrl_soc *soc)
722{
723 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
developerf4154da2021-03-05 10:22:26 +0800724 int ret = 0;
developer84c7a632018-11-15 10:07:58 +0800725
726 priv->base = dev_read_addr_ptr(dev);
Sean Anderson42db70b2020-06-24 06:41:13 -0400727 if (!priv->base)
developer84c7a632018-11-15 10:07:58 +0800728 return -EINVAL;
729
730 priv->soc = soc;
731
developerf4154da2021-03-05 10:22:26 +0800732#if CONFIG_IS_ENABLED(DM_GPIO) || \
Simon Glass035939e2021-07-10 21:14:30 -0600733 (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO))
developer84c7a632018-11-15 10:07:58 +0800734 ret = mtk_gpiochip_register(dev);
developerf4154da2021-03-05 10:22:26 +0800735#endif
developer84c7a632018-11-15 10:07:58 +0800736
developerf4154da2021-03-05 10:22:26 +0800737 return ret;
developer84c7a632018-11-15 10:07:58 +0800738}