blob: 37fc28bb779048c2b404f638ae514dbd3d96938d [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
developer84c7a632018-11-15 10:07:58 +08007#include <dm.h>
8#include <dm/device-internal.h>
9#include <dm/lists.h>
10#include <dm/pinctrl.h>
11#include <asm/io.h>
12#include <asm-generic/gpio.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060013#include <linux/bitops.h>
developer84c7a632018-11-15 10:07:58 +080014
15#include "pinctrl-mtk-common.h"
16
Fabien Parent105f6c82019-07-18 19:08:08 +020017#if CONFIG_IS_ENABLED(PINCONF)
developer84c7a632018-11-15 10:07:58 +080018/**
19 * struct mtk_drive_desc - the structure that holds the information
20 * of the driving current
21 * @min: the minimum current of this group
22 * @max: the maximum current of this group
23 * @step: the step current of this group
24 * @scal: the weight factor
25 *
26 * formula: output = ((input) / step - 1) * scal
27 */
28struct mtk_drive_desc {
29 u8 min;
30 u8 max;
31 u8 step;
32 u8 scal;
33};
34
35/* The groups of drive strength */
36static const struct mtk_drive_desc mtk_drive[] = {
37 [DRV_GRP0] = { 4, 16, 4, 1 },
38 [DRV_GRP1] = { 4, 16, 4, 2 },
39 [DRV_GRP2] = { 2, 8, 2, 1 },
40 [DRV_GRP3] = { 2, 8, 2, 2 },
41 [DRV_GRP4] = { 2, 16, 2, 1 },
42};
Fabien Parent105f6c82019-07-18 19:08:08 +020043#endif
developer84c7a632018-11-15 10:07:58 +080044
45static const char *mtk_pinctrl_dummy_name = "_dummy";
46
developera7482d32022-04-21 14:23:52 +080047static void mtk_w32(struct udevice *dev, u8 i, u32 reg, u32 val)
developer84c7a632018-11-15 10:07:58 +080048{
49 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
50
developera7482d32022-04-21 14:23:52 +080051 __raw_writel(val, priv->base[i] + reg);
developer84c7a632018-11-15 10:07:58 +080052}
53
developera7482d32022-04-21 14:23:52 +080054static u32 mtk_r32(struct udevice *dev, u8 i, u32 reg)
developer84c7a632018-11-15 10:07:58 +080055{
56 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
57
developera7482d32022-04-21 14:23:52 +080058 return __raw_readl(priv->base[i] + reg);
developer84c7a632018-11-15 10:07:58 +080059}
60
61static inline int get_count_order(unsigned int count)
62{
63 int order;
64
65 order = fls(count) - 1;
66 if (count & (count - 1))
67 order++;
68 return order;
69}
70
71void mtk_rmw(struct udevice *dev, u32 reg, u32 mask, u32 set)
72{
developera7482d32022-04-21 14:23:52 +080073 return mtk_i_rmw(dev, 0, reg, mask, set);
74}
75
76void mtk_i_rmw(struct udevice *dev, u8 i, u32 reg, u32 mask, u32 set)
77{
developer84c7a632018-11-15 10:07:58 +080078 u32 val;
79
developera7482d32022-04-21 14:23:52 +080080 val = mtk_r32(dev, i, reg);
developer84c7a632018-11-15 10:07:58 +080081 val &= ~mask;
82 val |= set;
developera7482d32022-04-21 14:23:52 +080083 mtk_w32(dev, i, reg, val);
developer84c7a632018-11-15 10:07:58 +080084}
85
86static int mtk_hw_pin_field_lookup(struct udevice *dev, int pin,
87 const struct mtk_pin_reg_calc *rc,
88 struct mtk_pin_field *pfd)
89{
developera7482d32022-04-21 14:23:52 +080090 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
developer84c7a632018-11-15 10:07:58 +080091 const struct mtk_pin_field_calc *c, *e;
92 u32 bits;
developera7482d32022-04-21 14:23:52 +080093 u32 base_calc = priv->soc->base_calc;
developer84c7a632018-11-15 10:07:58 +080094
95 c = rc->range;
96 e = c + rc->nranges;
97
98 while (c < e) {
99 if (pin >= c->s_pin && pin <= c->e_pin)
100 break;
101 c++;
102 }
103
104 if (c >= e)
105 return -EINVAL;
106
107 /* Calculated bits as the overall offset the pin is located at,
108 * if c->fixed is held, that determines the all the pins in the
109 * range use the same field with the s_pin.
110 */
111 bits = c->fixed ? c->s_bit : c->s_bit + (pin - c->s_pin) * (c->x_bits);
112
113 /* Fill pfd from bits. For example 32-bit register applied is assumed
114 * when c->sz_reg is equal to 32.
115 */
116 pfd->offset = c->s_addr + c->x_addrs * (bits / c->sz_reg);
117 pfd->bitpos = bits % c->sz_reg;
118 pfd->mask = (1 << c->x_bits) - 1;
119
developera7482d32022-04-21 14:23:52 +0800120 if (base_calc)
121 pfd->index = c->i_base;
122 else
123 pfd->index = 0;
124
developer84c7a632018-11-15 10:07:58 +0800125 /* pfd->next is used for indicating that bit wrapping-around happens
126 * which requires the manipulation for bit 0 starting in the next
127 * register to form the complete field read/write.
128 */
129 pfd->next = pfd->bitpos + c->x_bits > c->sz_reg ? c->x_addrs : 0;
130
131 return 0;
132}
133
134static int mtk_hw_pin_field_get(struct udevice *dev, int pin,
135 int field, struct mtk_pin_field *pfd)
136{
137 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
138 const struct mtk_pin_reg_calc *rc;
139
140 if (field < 0 || field >= PINCTRL_PIN_REG_MAX)
141 return -EINVAL;
142
143 if (priv->soc->reg_cal && priv->soc->reg_cal[field].range)
144 rc = &priv->soc->reg_cal[field];
145 else
146 return -EINVAL;
147
148 return mtk_hw_pin_field_lookup(dev, pin, rc, pfd);
149}
150
151static void mtk_hw_bits_part(struct mtk_pin_field *pf, int *h, int *l)
152{
153 *l = 32 - pf->bitpos;
154 *h = get_count_order(pf->mask) - *l;
155}
156
157static void mtk_hw_write_cross_field(struct udevice *dev,
158 struct mtk_pin_field *pf, int value)
159{
160 int nbits_l, nbits_h;
161
162 mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
163
developera7482d32022-04-21 14:23:52 +0800164 mtk_i_rmw(dev, pf->index, pf->offset, pf->mask << pf->bitpos,
developer84c7a632018-11-15 10:07:58 +0800165 (value & pf->mask) << pf->bitpos);
166
developera7482d32022-04-21 14:23:52 +0800167 mtk_i_rmw(dev, pf->index, pf->offset + pf->next, BIT(nbits_h) - 1,
developer84c7a632018-11-15 10:07:58 +0800168 (value & pf->mask) >> nbits_l);
169}
170
171static void mtk_hw_read_cross_field(struct udevice *dev,
172 struct mtk_pin_field *pf, int *value)
173{
174 int nbits_l, nbits_h, h, l;
175
176 mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
177
developera7482d32022-04-21 14:23:52 +0800178 l = (mtk_r32(dev, pf->index, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1);
179 h = (mtk_r32(dev, pf->index, pf->offset + pf->next)) & (BIT(nbits_h) - 1);
developer84c7a632018-11-15 10:07:58 +0800180
181 *value = (h << nbits_l) | l;
182}
183
184static int mtk_hw_set_value(struct udevice *dev, int pin, int field,
185 int value)
186{
187 struct mtk_pin_field pf;
188 int err;
189
190 err = mtk_hw_pin_field_get(dev, pin, field, &pf);
191 if (err)
192 return err;
193
194 if (!pf.next)
developera7482d32022-04-21 14:23:52 +0800195 mtk_i_rmw(dev, pf.index, pf.offset, pf.mask << pf.bitpos,
developer84c7a632018-11-15 10:07:58 +0800196 (value & pf.mask) << pf.bitpos);
197 else
198 mtk_hw_write_cross_field(dev, &pf, value);
199
200 return 0;
201}
202
203static int mtk_hw_get_value(struct udevice *dev, int pin, int field,
204 int *value)
205{
206 struct mtk_pin_field pf;
207 int err;
208
209 err = mtk_hw_pin_field_get(dev, pin, field, &pf);
210 if (err)
211 return err;
212
213 if (!pf.next)
developera7482d32022-04-21 14:23:52 +0800214 *value = (mtk_r32(dev, pf.index, pf.offset) >> pf.bitpos) & pf.mask;
developer84c7a632018-11-15 10:07:58 +0800215 else
216 mtk_hw_read_cross_field(dev, &pf, value);
217
218 return 0;
219}
220
developerf8d22692022-04-21 14:23:53 +0800221#if CONFIG_IS_ENABLED(PINCONF)
222static int mtk_get_pin_io_type(struct udevice *dev, int pin,
223 struct mtk_io_type_desc *io_type)
224{
225 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
226 u8 io_n = priv->soc->pins[pin].io_n;
227
228 if (io_n >= priv->soc->ntype)
229 return -EINVAL;
230
231 io_type->name = priv->soc->io_type[io_n].name;
232 io_type->bias_set = priv->soc->io_type[io_n].bias_set;
233 io_type->drive_set = priv->soc->io_type[io_n].drive_set;
234 io_type->input_enable = priv->soc->io_type[io_n].input_enable;
235
236 return 0;
237}
238#endif
239
developer84c7a632018-11-15 10:07:58 +0800240static int mtk_get_groups_count(struct udevice *dev)
241{
242 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
243
244 return priv->soc->ngrps;
245}
246
247static const char *mtk_get_pin_name(struct udevice *dev,
248 unsigned int selector)
249{
250 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
251
developerdeb84062021-03-05 10:22:11 +0800252 if (!priv->soc->pins[selector].name)
developer84c7a632018-11-15 10:07:58 +0800253 return mtk_pinctrl_dummy_name;
254
255 return priv->soc->pins[selector].name;
256}
257
258static int mtk_get_pins_count(struct udevice *dev)
259{
260 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
261
262 return priv->soc->npins;
263}
264
developer0163c082021-03-05 10:22:19 +0800265static int mtk_get_pin_muxing(struct udevice *dev, unsigned int selector,
266 char *buf, int size)
267{
268 int val, err;
developer0163c082021-03-05 10:22:19 +0800269 err = mtk_hw_get_value(dev, selector, PINCTRL_PIN_REG_MODE, &val);
270 if (err)
271 return err;
272
273 snprintf(buf, size, "Aux Func.%d", val);
274 return 0;
275}
276
developer84c7a632018-11-15 10:07:58 +0800277static const char *mtk_get_group_name(struct udevice *dev,
278 unsigned int selector)
279{
280 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
281
282 if (!priv->soc->grps[selector].name)
283 return mtk_pinctrl_dummy_name;
284
285 return priv->soc->grps[selector].name;
286}
287
288static int mtk_get_functions_count(struct udevice *dev)
289{
290 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
291
292 return priv->soc->nfuncs;
293}
294
295static const char *mtk_get_function_name(struct udevice *dev,
296 unsigned int selector)
297{
298 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
299
300 if (!priv->soc->funcs[selector].name)
301 return mtk_pinctrl_dummy_name;
302
303 return priv->soc->funcs[selector].name;
304}
305
developerdac0f762023-07-19 17:16:46 +0800306static int mtk_pinmux_set(struct udevice *dev, unsigned int pin_selector,
307 unsigned int func_selector)
308{
309 int err;
310
311 err = mtk_hw_set_value(dev, pin_selector, PINCTRL_PIN_REG_MODE,
312 func_selector);
313 if (err)
314 return err;
315
316 return 0;
317}
318
developer84c7a632018-11-15 10:07:58 +0800319static int mtk_pinmux_group_set(struct udevice *dev,
320 unsigned int group_selector,
321 unsigned int func_selector)
322{
323 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
324 const struct mtk_group_desc *grp =
325 &priv->soc->grps[group_selector];
326 int i;
327
328 for (i = 0; i < grp->num_pins; i++) {
developer67873bd2023-07-19 17:16:37 +0800329 const int *pin_modes = grp->data;
developer84c7a632018-11-15 10:07:58 +0800330
331 mtk_hw_set_value(dev, grp->pins[i], PINCTRL_PIN_REG_MODE,
332 pin_modes[i]);
333 }
334
335 return 0;
336}
337
338#if CONFIG_IS_ENABLED(PINCONF)
339static const struct pinconf_param mtk_conf_params[] = {
340 { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
341 { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
342 { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
343 { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
344 { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
345 { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
346 { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
347 { "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
348 { "output-high", PIN_CONFIG_OUTPUT, 1, },
349 { "output-low", PIN_CONFIG_OUTPUT, 0, },
350 { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
351};
352
developer6e84c2f2022-04-21 14:23:51 +0800353int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, bool disable,
354 bool pullup, u32 val)
355{
356 return mtk_pinconf_bias_set_pu_pd(dev, pin, disable, pullup, val);
357}
developer74d69012020-01-10 16:30:28 +0800358
developer6e84c2f2022-04-21 14:23:51 +0800359int mtk_pinconf_bias_set_v1(struct udevice *dev, u32 pin, bool disable,
360 bool pullup, u32 val)
developer74d69012020-01-10 16:30:28 +0800361{
developer6e84c2f2022-04-21 14:23:51 +0800362 int err;
developer74d69012020-01-10 16:30:28 +0800363
Daniel Golle8c9bb0a2023-04-12 21:36:43 +0100364 /* set pupd_r1_r0 if pullen_pullsel succeeded */
developer6e84c2f2022-04-21 14:23:51 +0800365 err = mtk_pinconf_bias_set_pullen_pullsel(dev, pin, disable, pullup,
366 val);
Daniel Golle8c9bb0a2023-04-12 21:36:43 +0100367 if (!err)
developer6e84c2f2022-04-21 14:23:51 +0800368 return mtk_pinconf_bias_set_pupd_r1_r0(dev, pin, disable,
369 pullup, val);
370
371 return err;
372}
373
374int mtk_pinconf_bias_set_pu_pd(struct udevice *dev, u32 pin, bool disable,
375 bool pullup, u32 val)
376{
377 int err;
developer74d69012020-01-10 16:30:28 +0800378
379 if (disable) {
380 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PU, 0);
381 if (err)
382 return err;
383 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PD, 0);
384 if (err)
385 return err;
developer74d69012020-01-10 16:30:28 +0800386 } else {
387 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PU, pullup);
388 if (err)
389 return err;
390 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PD, !pullup);
391 if (err)
392 return err;
393 }
394
395 return 0;
396}
397
developer6e84c2f2022-04-21 14:23:51 +0800398int mtk_pinconf_bias_set_pullen_pullsel(struct udevice *dev, u32 pin,
399 bool disable, bool pullup, u32 val)
developer74d69012020-01-10 16:30:28 +0800400{
developer6e84c2f2022-04-21 14:23:51 +0800401 int err;
developer74d69012020-01-10 16:30:28 +0800402
403 if (disable) {
404 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN, 0);
405 if (err)
406 return err;
407 } else {
408 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN, 1);
409 if (err)
410 return err;
411 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLSEL,
412 pullup);
413 if (err)
414 return err;
415 }
416
developer6e84c2f2022-04-21 14:23:51 +0800417 return 0;
418}
419
420int mtk_pinconf_bias_set_pupd_r1_r0(struct udevice *dev, u32 pin, bool disable,
421 bool pullup, u32 val)
422{
423 int err, r0, r1;
424
425 r0 = !!(val & 1);
426 r1 = !!(val & 2);
427
428 if (disable) {
429 pullup = 0;
430 r0 = 0;
431 r1 = 0;
David Woodhouse32102752020-06-19 12:40:20 +0100432 }
433
developer6e84c2f2022-04-21 14:23:51 +0800434 /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
435 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PUPD, !pullup);
436 if (err)
437 return err;
438
439 /* Also set PUPD/R0/R1 if the pin has them */
440 mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_R0, r0);
441 mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_R1, r1);
442
developer74d69012020-01-10 16:30:28 +0800443 return 0;
444}
445
developer6e84c2f2022-04-21 14:23:51 +0800446int mtk_pinconf_bias_set(struct udevice *dev, u32 pin, u32 arg, u32 val)
447{
448 int err;
449 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
developerf8d22692022-04-21 14:23:53 +0800450 struct mtk_io_type_desc io_type;
developer6e84c2f2022-04-21 14:23:51 +0800451 int rev = priv->soc->rev;
452 bool disable, pullup;
453
454 disable = (arg == PIN_CONFIG_BIAS_DISABLE);
455 pullup = (arg == PIN_CONFIG_BIAS_PULL_UP);
456
developerf8d22692022-04-21 14:23:53 +0800457 if (!mtk_get_pin_io_type(dev, pin, &io_type)) {
458 if (io_type.bias_set)
459 err = io_type.bias_set(dev, pin, disable, pullup,
460 val);
461 else
462 err = -EINVAL;
463
464 } else if (rev == MTK_PINCTRL_V0) {
developer6e84c2f2022-04-21 14:23:51 +0800465 err = mtk_pinconf_bias_set_v0(dev, pin, disable, pullup, val);
developerf8d22692022-04-21 14:23:53 +0800466 } else {
developer6e84c2f2022-04-21 14:23:51 +0800467 err = mtk_pinconf_bias_set_v1(dev, pin, disable, pullup, val);
developerf8d22692022-04-21 14:23:53 +0800468 }
developer6e84c2f2022-04-21 14:23:51 +0800469
470 return err;
471}
472
developer74d69012020-01-10 16:30:28 +0800473int mtk_pinconf_input_enable_v1(struct udevice *dev, u32 pin, u32 arg)
474{
475 int err;
476
477 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_IES, 1);
478 if (err)
479 return err;
480 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 0);
481 if (err)
482 return err;
developer6e84c2f2022-04-21 14:23:51 +0800483
developer74d69012020-01-10 16:30:28 +0800484 return 0;
485}
486
developer6e84c2f2022-04-21 14:23:51 +0800487int mtk_pinconf_input_enable(struct udevice *dev, u32 pin, u32 arg)
488{
489 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
developerf8d22692022-04-21 14:23:53 +0800490 struct mtk_io_type_desc io_type;
491
developer6e84c2f2022-04-21 14:23:51 +0800492 int rev = priv->soc->rev;
493
developerf8d22692022-04-21 14:23:53 +0800494 if (!mtk_get_pin_io_type(dev, pin, &io_type))
495 if (io_type.input_enable)
496 return io_type.input_enable(dev, pin, arg);
developer6e84c2f2022-04-21 14:23:51 +0800497 if (rev == MTK_PINCTRL_V1)
498 return mtk_pinconf_input_enable_v1(dev, pin, arg);
499
500 return 0;
501}
502
developer74d69012020-01-10 16:30:28 +0800503int mtk_pinconf_drive_set_v0(struct udevice *dev, u32 pin, u32 arg)
developer84c7a632018-11-15 10:07:58 +0800504{
505 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
506 const struct mtk_pin_desc *desc = &priv->soc->pins[pin];
507 const struct mtk_drive_desc *tb;
508 int err = -ENOTSUPP;
509
510 tb = &mtk_drive[desc->drv_n];
511 /* 4mA when (e8, e4) = (0, 0)
512 * 8mA when (e8, e4) = (0, 1)
513 * 12mA when (e8, e4) = (1, 0)
514 * 16mA when (e8, e4) = (1, 1)
515 */
516 if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
517 arg = (arg / tb->step - 1) * tb->scal;
developer74d69012020-01-10 16:30:28 +0800518 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_E4,
519 arg & 0x1);
520 if (err)
521 return err;
522 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_E8,
523 (arg & 0x2) >> 1);
524 if (err)
525 return err;
526 }
527
developerb42024c2023-07-19 17:16:42 +0800528 return err;
developer74d69012020-01-10 16:30:28 +0800529}
developer84c7a632018-11-15 10:07:58 +0800530
developer74d69012020-01-10 16:30:28 +0800531int mtk_pinconf_drive_set_v1(struct udevice *dev, u32 pin, u32 arg)
532{
533 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
534 const struct mtk_pin_desc *desc = &priv->soc->pins[pin];
535 const struct mtk_drive_desc *tb;
536 int err = -ENOTSUPP;
537
538 tb = &mtk_drive[desc->drv_n];
539 if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
540 arg = (arg / tb->step - 1) * tb->scal;
developer84c7a632018-11-15 10:07:58 +0800541 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DRV, arg);
542 if (err)
543 return err;
544 }
545
developerb42024c2023-07-19 17:16:42 +0800546 return err;
developer84c7a632018-11-15 10:07:58 +0800547}
548
developer6e84c2f2022-04-21 14:23:51 +0800549int mtk_pinconf_drive_set(struct udevice *dev, u32 pin, u32 arg)
550{
551 int err;
552 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
developerf8d22692022-04-21 14:23:53 +0800553 struct mtk_io_type_desc io_type;
developer6e84c2f2022-04-21 14:23:51 +0800554 int rev = priv->soc->rev;
555
developerf8d22692022-04-21 14:23:53 +0800556 if (!mtk_get_pin_io_type(dev, pin, &io_type)) {
557 if (io_type.drive_set)
558 err = io_type.drive_set(dev, pin, arg);
559 else
560 err = -EINVAL;
561 } else if (rev == MTK_PINCTRL_V0) {
developer6e84c2f2022-04-21 14:23:51 +0800562 err = mtk_pinconf_drive_set_v0(dev, pin, arg);
developerf8d22692022-04-21 14:23:53 +0800563 } else {
developer6e84c2f2022-04-21 14:23:51 +0800564 err = mtk_pinconf_drive_set_v1(dev, pin, arg);
developerf8d22692022-04-21 14:23:53 +0800565 }
developer6e84c2f2022-04-21 14:23:51 +0800566
567 return err;
568}
569
developer84c7a632018-11-15 10:07:58 +0800570static int mtk_pinconf_set(struct udevice *dev, unsigned int pin,
571 unsigned int param, unsigned int arg)
572{
573 int err = 0;
574
575 switch (param) {
576 case PIN_CONFIG_BIAS_DISABLE:
577 case PIN_CONFIG_BIAS_PULL_UP:
578 case PIN_CONFIG_BIAS_PULL_DOWN:
developer6e84c2f2022-04-21 14:23:51 +0800579 err = mtk_pinconf_bias_set(dev, pin, param, arg);
developer84c7a632018-11-15 10:07:58 +0800580 if (err)
581 goto err;
582 break;
583 case PIN_CONFIG_OUTPUT_ENABLE:
584 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_SMT, 0);
585 if (err)
586 goto err;
587 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 1);
588 if (err)
589 goto err;
590 break;
591 case PIN_CONFIG_INPUT_ENABLE:
developer6e84c2f2022-04-21 14:23:51 +0800592 err = mtk_pinconf_input_enable(dev, pin, param);
developer84c7a632018-11-15 10:07:58 +0800593 if (err)
594 goto err;
595 break;
596 case PIN_CONFIG_OUTPUT:
597 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 1);
598 if (err)
599 goto err;
600
601 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DO, arg);
602 if (err)
603 goto err;
604 break;
605 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
606 /* arg = 1: Input mode & SMT enable ;
607 * arg = 0: Output mode & SMT disable
608 */
609 arg = arg ? 2 : 1;
610 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR,
611 arg & 1);
612 if (err)
613 goto err;
614
615 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_SMT,
616 !!(arg & 2));
617 if (err)
618 goto err;
619 break;
620 case PIN_CONFIG_DRIVE_STRENGTH:
developer6e84c2f2022-04-21 14:23:51 +0800621 err = mtk_pinconf_drive_set(dev, pin, arg);
developer84c7a632018-11-15 10:07:58 +0800622 if (err)
623 goto err;
624 break;
625
626 default:
627 err = -ENOTSUPP;
628 }
629
630err:
631
632 return err;
633}
634
635static int mtk_pinconf_group_set(struct udevice *dev,
636 unsigned int group_selector,
637 unsigned int param, unsigned int arg)
638{
639 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
640 const struct mtk_group_desc *grp =
641 &priv->soc->grps[group_selector];
642 int i, ret;
643
644 for (i = 0; i < grp->num_pins; i++) {
645 ret = mtk_pinconf_set(dev, grp->pins[i], param, arg);
646 if (ret)
647 return ret;
648 }
649
650 return 0;
651}
652#endif
653
654const struct pinctrl_ops mtk_pinctrl_ops = {
655 .get_pins_count = mtk_get_pins_count,
656 .get_pin_name = mtk_get_pin_name,
developer0163c082021-03-05 10:22:19 +0800657 .get_pin_muxing = mtk_get_pin_muxing,
developer84c7a632018-11-15 10:07:58 +0800658 .get_groups_count = mtk_get_groups_count,
659 .get_group_name = mtk_get_group_name,
660 .get_functions_count = mtk_get_functions_count,
661 .get_function_name = mtk_get_function_name,
developerdac0f762023-07-19 17:16:46 +0800662 .pinmux_set = mtk_pinmux_set,
developer84c7a632018-11-15 10:07:58 +0800663 .pinmux_group_set = mtk_pinmux_group_set,
664#if CONFIG_IS_ENABLED(PINCONF)
665 .pinconf_num_params = ARRAY_SIZE(mtk_conf_params),
666 .pinconf_params = mtk_conf_params,
667 .pinconf_set = mtk_pinconf_set,
668 .pinconf_group_set = mtk_pinconf_group_set,
669#endif
670 .set_state = pinctrl_generic_set_state,
671};
672
developerf4154da2021-03-05 10:22:26 +0800673#if CONFIG_IS_ENABLED(DM_GPIO) || \
Simon Glass035939e2021-07-10 21:14:30 -0600674 (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO))
developer84c7a632018-11-15 10:07:58 +0800675static int mtk_gpio_get(struct udevice *dev, unsigned int off)
676{
677 int val, err;
678
679 err = mtk_hw_get_value(dev->parent, off, PINCTRL_PIN_REG_DI, &val);
680 if (err)
681 return err;
682
683 return !!val;
684}
685
686static int mtk_gpio_set(struct udevice *dev, unsigned int off, int val)
687{
688 return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DO, !!val);
689}
690
691static int mtk_gpio_get_direction(struct udevice *dev, unsigned int off)
692{
693 int val, err;
694
695 err = mtk_hw_get_value(dev->parent, off, PINCTRL_PIN_REG_DIR, &val);
696 if (err)
697 return err;
698
699 return val ? GPIOF_OUTPUT : GPIOF_INPUT;
700}
701
702static int mtk_gpio_direction_input(struct udevice *dev, unsigned int off)
703{
704 return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DIR, 0);
705}
706
707static int mtk_gpio_direction_output(struct udevice *dev,
708 unsigned int off, int val)
709{
710 mtk_gpio_set(dev, off, val);
711
712 /* And set the requested value */
713 return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DIR, 1);
714}
715
716static int mtk_gpio_request(struct udevice *dev, unsigned int off,
717 const char *label)
718{
developer74d69012020-01-10 16:30:28 +0800719 struct mtk_pinctrl_priv *priv = dev_get_priv(dev->parent);
720
721 return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_MODE,
722 priv->soc->gpio_mode);
developer84c7a632018-11-15 10:07:58 +0800723}
724
725static int mtk_gpio_probe(struct udevice *dev)
726{
727 struct mtk_pinctrl_priv *priv = dev_get_priv(dev->parent);
728 struct gpio_dev_priv *uc_priv;
729
730 uc_priv = dev_get_uclass_priv(dev);
731 uc_priv->bank_name = priv->soc->name;
732 uc_priv->gpio_count = priv->soc->npins;
733
734 return 0;
735}
736
737static const struct dm_gpio_ops mtk_gpio_ops = {
738 .request = mtk_gpio_request,
739 .set_value = mtk_gpio_set,
740 .get_value = mtk_gpio_get,
741 .get_function = mtk_gpio_get_direction,
742 .direction_input = mtk_gpio_direction_input,
743 .direction_output = mtk_gpio_direction_output,
744};
745
746static struct driver mtk_gpio_driver = {
747 .name = "mediatek_gpio",
748 .id = UCLASS_GPIO,
749 .probe = mtk_gpio_probe,
750 .ops = &mtk_gpio_ops,
751};
752
753static int mtk_gpiochip_register(struct udevice *parent)
754{
755 struct uclass_driver *drv;
756 struct udevice *dev;
757 int ret;
758 ofnode node;
759
760 drv = lists_uclass_lookup(UCLASS_GPIO);
761 if (!drv)
762 return -ENOENT;
763
Heinrich Schuchardt0c67d122020-12-27 21:18:26 +0100764 ret = -ENOENT;
developer84c7a632018-11-15 10:07:58 +0800765 dev_for_each_subnode(node, parent)
766 if (ofnode_read_bool(node, "gpio-controller")) {
767 ret = 0;
768 break;
769 }
770
771 if (ret)
772 return ret;
773
774 ret = device_bind_with_driver_data(parent, &mtk_gpio_driver,
775 "mediatek_gpio", 0, node,
776 &dev);
777 if (ret)
778 return ret;
779
780 return 0;
781}
developerf4154da2021-03-05 10:22:26 +0800782#endif
developer84c7a632018-11-15 10:07:58 +0800783
784int mtk_pinctrl_common_probe(struct udevice *dev,
developer67873bd2023-07-19 17:16:37 +0800785 const struct mtk_pinctrl_soc *soc)
developer84c7a632018-11-15 10:07:58 +0800786{
787 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
developerf4154da2021-03-05 10:22:26 +0800788 int ret = 0;
developera7482d32022-04-21 14:23:52 +0800789 u32 i = 0;
790 fdt_addr_t addr;
791 u32 base_calc = soc->base_calc;
792 u32 nbase_names = soc->nbase_names;
developer84c7a632018-11-15 10:07:58 +0800793
794 priv->soc = soc;
795
developera7482d32022-04-21 14:23:52 +0800796 if (!base_calc)
797 nbase_names = 1;
798
799 for (i = 0; i < nbase_names; i++) {
800 addr = devfdt_get_addr_index(dev, i);
801 if (addr == FDT_ADDR_T_NONE)
802 return -EINVAL;
803 priv->base[i] = (void __iomem *)addr;
804 }
805
developerf4154da2021-03-05 10:22:26 +0800806#if CONFIG_IS_ENABLED(DM_GPIO) || \
Simon Glass035939e2021-07-10 21:14:30 -0600807 (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO))
developer84c7a632018-11-15 10:07:58 +0800808 ret = mtk_gpiochip_register(dev);
developerf4154da2021-03-05 10:22:26 +0800809#endif
developer84c7a632018-11-15 10:07:58 +0800810
developerf4154da2021-03-05 10:22:26 +0800811 return ret;
developer84c7a632018-11-15 10:07:58 +0800812}