blob: 0baef57c1c2f9ac32679e03941955f41c47b994d [file] [log] [blame]
Ryder Lee01aa9d12018-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 Glasscd93d622020-05-10 11:40:13 -060014#include <linux/bitops.h>
Ryder Lee01aa9d12018-11-15 10:07:58 +080015
16#include "pinctrl-mtk-common.h"
17
Fabien Parente66b2022019-07-18 19:08:08 +020018#if CONFIG_IS_ENABLED(PINCONF)
Ryder Lee01aa9d12018-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 Parente66b2022019-07-18 19:08:08 +020044#endif
Ryder Lee01aa9d12018-11-15 10:07:58 +080045
46static const char *mtk_pinctrl_dummy_name = "_dummy";
47
Sam Shih10334e02022-04-21 14:23:52 +080048static void mtk_w32(struct udevice *dev, u8 i, u32 reg, u32 val)
Ryder Lee01aa9d12018-11-15 10:07:58 +080049{
50 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
51
Sam Shih10334e02022-04-21 14:23:52 +080052 __raw_writel(val, priv->base[i] + reg);
Ryder Lee01aa9d12018-11-15 10:07:58 +080053}
54
Sam Shih10334e02022-04-21 14:23:52 +080055static u32 mtk_r32(struct udevice *dev, u8 i, u32 reg)
Ryder Lee01aa9d12018-11-15 10:07:58 +080056{
57 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
58
Sam Shih10334e02022-04-21 14:23:52 +080059 return __raw_readl(priv->base[i] + reg);
Ryder Lee01aa9d12018-11-15 10:07:58 +080060}
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{
Sam Shih10334e02022-04-21 14:23:52 +080074 return mtk_i_rmw(dev, 0, reg, mask, set);
75}
76
77void mtk_i_rmw(struct udevice *dev, u8 i, u32 reg, u32 mask, u32 set)
78{
Ryder Lee01aa9d12018-11-15 10:07:58 +080079 u32 val;
80
Sam Shih10334e02022-04-21 14:23:52 +080081 val = mtk_r32(dev, i, reg);
Ryder Lee01aa9d12018-11-15 10:07:58 +080082 val &= ~mask;
83 val |= set;
Sam Shih10334e02022-04-21 14:23:52 +080084 mtk_w32(dev, i, reg, val);
Ryder Lee01aa9d12018-11-15 10:07:58 +080085}
86
87static int mtk_hw_pin_field_lookup(struct udevice *dev, int pin,
88 const struct mtk_pin_reg_calc *rc,
89 struct mtk_pin_field *pfd)
90{
Sam Shih10334e02022-04-21 14:23:52 +080091 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
Ryder Lee01aa9d12018-11-15 10:07:58 +080092 const struct mtk_pin_field_calc *c, *e;
93 u32 bits;
Sam Shih10334e02022-04-21 14:23:52 +080094 u32 base_calc = priv->soc->base_calc;
Ryder Lee01aa9d12018-11-15 10:07:58 +080095
96 c = rc->range;
97 e = c + rc->nranges;
98
99 while (c < e) {
100 if (pin >= c->s_pin && pin <= c->e_pin)
101 break;
102 c++;
103 }
104
105 if (c >= e)
106 return -EINVAL;
107
108 /* Calculated bits as the overall offset the pin is located at,
109 * if c->fixed is held, that determines the all the pins in the
110 * range use the same field with the s_pin.
111 */
112 bits = c->fixed ? c->s_bit : c->s_bit + (pin - c->s_pin) * (c->x_bits);
113
114 /* Fill pfd from bits. For example 32-bit register applied is assumed
115 * when c->sz_reg is equal to 32.
116 */
117 pfd->offset = c->s_addr + c->x_addrs * (bits / c->sz_reg);
118 pfd->bitpos = bits % c->sz_reg;
119 pfd->mask = (1 << c->x_bits) - 1;
120
Sam Shih10334e02022-04-21 14:23:52 +0800121 if (base_calc)
122 pfd->index = c->i_base;
123 else
124 pfd->index = 0;
125
Ryder Lee01aa9d12018-11-15 10:07:58 +0800126 /* pfd->next is used for indicating that bit wrapping-around happens
127 * which requires the manipulation for bit 0 starting in the next
128 * register to form the complete field read/write.
129 */
130 pfd->next = pfd->bitpos + c->x_bits > c->sz_reg ? c->x_addrs : 0;
131
132 return 0;
133}
134
135static int mtk_hw_pin_field_get(struct udevice *dev, int pin,
136 int field, struct mtk_pin_field *pfd)
137{
138 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
139 const struct mtk_pin_reg_calc *rc;
140
141 if (field < 0 || field >= PINCTRL_PIN_REG_MAX)
142 return -EINVAL;
143
144 if (priv->soc->reg_cal && priv->soc->reg_cal[field].range)
145 rc = &priv->soc->reg_cal[field];
146 else
147 return -EINVAL;
148
149 return mtk_hw_pin_field_lookup(dev, pin, rc, pfd);
150}
151
152static void mtk_hw_bits_part(struct mtk_pin_field *pf, int *h, int *l)
153{
154 *l = 32 - pf->bitpos;
155 *h = get_count_order(pf->mask) - *l;
156}
157
158static void mtk_hw_write_cross_field(struct udevice *dev,
159 struct mtk_pin_field *pf, int value)
160{
161 int nbits_l, nbits_h;
162
163 mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
164
Sam Shih10334e02022-04-21 14:23:52 +0800165 mtk_i_rmw(dev, pf->index, pf->offset, pf->mask << pf->bitpos,
Ryder Lee01aa9d12018-11-15 10:07:58 +0800166 (value & pf->mask) << pf->bitpos);
167
Sam Shih10334e02022-04-21 14:23:52 +0800168 mtk_i_rmw(dev, pf->index, pf->offset + pf->next, BIT(nbits_h) - 1,
Ryder Lee01aa9d12018-11-15 10:07:58 +0800169 (value & pf->mask) >> nbits_l);
170}
171
172static void mtk_hw_read_cross_field(struct udevice *dev,
173 struct mtk_pin_field *pf, int *value)
174{
175 int nbits_l, nbits_h, h, l;
176
177 mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
178
Sam Shih10334e02022-04-21 14:23:52 +0800179 l = (mtk_r32(dev, pf->index, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1);
180 h = (mtk_r32(dev, pf->index, pf->offset + pf->next)) & (BIT(nbits_h) - 1);
Ryder Lee01aa9d12018-11-15 10:07:58 +0800181
182 *value = (h << nbits_l) | l;
183}
184
185static int mtk_hw_set_value(struct udevice *dev, int pin, int field,
186 int value)
187{
188 struct mtk_pin_field pf;
189 int err;
190
191 err = mtk_hw_pin_field_get(dev, pin, field, &pf);
192 if (err)
193 return err;
194
195 if (!pf.next)
Sam Shih10334e02022-04-21 14:23:52 +0800196 mtk_i_rmw(dev, pf.index, pf.offset, pf.mask << pf.bitpos,
Ryder Lee01aa9d12018-11-15 10:07:58 +0800197 (value & pf.mask) << pf.bitpos);
198 else
199 mtk_hw_write_cross_field(dev, &pf, value);
200
201 return 0;
202}
203
204static int mtk_hw_get_value(struct udevice *dev, int pin, int field,
205 int *value)
206{
207 struct mtk_pin_field pf;
208 int err;
209
210 err = mtk_hw_pin_field_get(dev, pin, field, &pf);
211 if (err)
212 return err;
213
214 if (!pf.next)
Sam Shih10334e02022-04-21 14:23:52 +0800215 *value = (mtk_r32(dev, pf.index, pf.offset) >> pf.bitpos) & pf.mask;
Ryder Lee01aa9d12018-11-15 10:07:58 +0800216 else
217 mtk_hw_read_cross_field(dev, &pf, value);
218
219 return 0;
220}
221
Sam Shih1a80ef52022-04-21 14:23:53 +0800222#if CONFIG_IS_ENABLED(PINCONF)
223static int mtk_get_pin_io_type(struct udevice *dev, int pin,
224 struct mtk_io_type_desc *io_type)
225{
226 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
227 u8 io_n = priv->soc->pins[pin].io_n;
228
229 if (io_n >= priv->soc->ntype)
230 return -EINVAL;
231
232 io_type->name = priv->soc->io_type[io_n].name;
233 io_type->bias_set = priv->soc->io_type[io_n].bias_set;
234 io_type->drive_set = priv->soc->io_type[io_n].drive_set;
235 io_type->input_enable = priv->soc->io_type[io_n].input_enable;
236
237 return 0;
238}
239#endif
240
Ryder Lee01aa9d12018-11-15 10:07:58 +0800241static int mtk_get_groups_count(struct udevice *dev)
242{
243 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
244
245 return priv->soc->ngrps;
246}
247
248static const char *mtk_get_pin_name(struct udevice *dev,
249 unsigned int selector)
250{
251 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
252
Sam Shih4fc5d4c2021-03-05 10:22:11 +0800253 if (!priv->soc->pins[selector].name)
Ryder Lee01aa9d12018-11-15 10:07:58 +0800254 return mtk_pinctrl_dummy_name;
255
256 return priv->soc->pins[selector].name;
257}
258
259static int mtk_get_pins_count(struct udevice *dev)
260{
261 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
262
263 return priv->soc->npins;
264}
265
Sam Shihe254d2c2021-03-05 10:22:19 +0800266static int mtk_get_pin_muxing(struct udevice *dev, unsigned int selector,
267 char *buf, int size)
268{
269 int val, err;
Sam Shihe254d2c2021-03-05 10:22:19 +0800270 err = mtk_hw_get_value(dev, selector, PINCTRL_PIN_REG_MODE, &val);
271 if (err)
272 return err;
273
274 snprintf(buf, size, "Aux Func.%d", val);
275 return 0;
276}
277
Ryder Lee01aa9d12018-11-15 10:07:58 +0800278static const char *mtk_get_group_name(struct udevice *dev,
279 unsigned int selector)
280{
281 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
282
283 if (!priv->soc->grps[selector].name)
284 return mtk_pinctrl_dummy_name;
285
286 return priv->soc->grps[selector].name;
287}
288
289static int mtk_get_functions_count(struct udevice *dev)
290{
291 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
292
293 return priv->soc->nfuncs;
294}
295
296static const char *mtk_get_function_name(struct udevice *dev,
297 unsigned int selector)
298{
299 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
300
301 if (!priv->soc->funcs[selector].name)
302 return mtk_pinctrl_dummy_name;
303
304 return priv->soc->funcs[selector].name;
305}
306
Weijie Gaof9c61062023-07-19 17:16:46 +0800307static int mtk_pinmux_set(struct udevice *dev, unsigned int pin_selector,
308 unsigned int func_selector)
309{
310 int err;
311
312 err = mtk_hw_set_value(dev, pin_selector, PINCTRL_PIN_REG_MODE,
313 func_selector);
314 if (err)
315 return err;
316
317 return 0;
318}
319
Ryder Lee01aa9d12018-11-15 10:07:58 +0800320static int mtk_pinmux_group_set(struct udevice *dev,
321 unsigned int group_selector,
322 unsigned int func_selector)
323{
324 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
325 const struct mtk_group_desc *grp =
326 &priv->soc->grps[group_selector];
327 int i;
328
329 for (i = 0; i < grp->num_pins; i++) {
Weijie Gao7cb50cd2023-07-19 17:16:37 +0800330 const int *pin_modes = grp->data;
Ryder Lee01aa9d12018-11-15 10:07:58 +0800331
332 mtk_hw_set_value(dev, grp->pins[i], PINCTRL_PIN_REG_MODE,
333 pin_modes[i]);
334 }
335
336 return 0;
337}
338
339#if CONFIG_IS_ENABLED(PINCONF)
340static const struct pinconf_param mtk_conf_params[] = {
341 { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
342 { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
343 { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
344 { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
345 { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
346 { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
347 { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
348 { "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
349 { "output-high", PIN_CONFIG_OUTPUT, 1, },
350 { "output-low", PIN_CONFIG_OUTPUT, 0, },
351 { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
352};
353
Sam Shihdafe0fb2022-04-21 14:23:51 +0800354int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, bool disable,
355 bool pullup, u32 val)
Sam Shihcf400b62020-01-10 16:30:28 +0800356{
Sam Shihdafe0fb2022-04-21 14:23:51 +0800357 return mtk_pinconf_bias_set_pu_pd(dev, pin, disable, pullup, val);
358}
Sam Shihcf400b62020-01-10 16:30:28 +0800359
Sam Shihdafe0fb2022-04-21 14:23:51 +0800360int mtk_pinconf_bias_set_v1(struct udevice *dev, u32 pin, bool disable,
361 bool pullup, u32 val)
362{
363 int err;
364
Daniel Gollebcfb23e2023-04-12 21:36:43 +0100365 /* set pupd_r1_r0 if pullen_pullsel succeeded */
Sam Shihdafe0fb2022-04-21 14:23:51 +0800366 err = mtk_pinconf_bias_set_pullen_pullsel(dev, pin, disable, pullup,
367 val);
Daniel Gollebcfb23e2023-04-12 21:36:43 +0100368 if (!err)
Sam Shihdafe0fb2022-04-21 14:23:51 +0800369 return mtk_pinconf_bias_set_pupd_r1_r0(dev, pin, disable,
370 pullup, val);
371
372 return err;
373}
374
375int mtk_pinconf_bias_set_pu_pd(struct udevice *dev, u32 pin, bool disable,
376 bool pullup, u32 val)
377{
378 int err;
Sam Shihcf400b62020-01-10 16:30:28 +0800379
380 if (disable) {
381 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PU, 0);
382 if (err)
383 return err;
384 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PD, 0);
385 if (err)
386 return err;
Sam Shihcf400b62020-01-10 16:30:28 +0800387 } else {
388 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PU, pullup);
389 if (err)
390 return err;
391 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PD, !pullup);
392 if (err)
393 return err;
394 }
395
396 return 0;
397}
398
Sam Shihdafe0fb2022-04-21 14:23:51 +0800399int mtk_pinconf_bias_set_pullen_pullsel(struct udevice *dev, u32 pin,
400 bool disable, bool pullup, u32 val)
Sam Shihcf400b62020-01-10 16:30:28 +0800401{
Sam Shihdafe0fb2022-04-21 14:23:51 +0800402 int err;
Sam Shihcf400b62020-01-10 16:30:28 +0800403
404 if (disable) {
405 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN, 0);
406 if (err)
407 return err;
408 } else {
409 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN, 1);
410 if (err)
411 return err;
412 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLSEL,
413 pullup);
414 if (err)
415 return err;
416 }
417
Sam Shihdafe0fb2022-04-21 14:23:51 +0800418 return 0;
419}
420
421int mtk_pinconf_bias_set_pupd_r1_r0(struct udevice *dev, u32 pin, bool disable,
422 bool pullup, u32 val)
423{
424 int err, r0, r1;
425
426 r0 = !!(val & 1);
427 r1 = !!(val & 2);
428
429 if (disable) {
430 pullup = 0;
431 r0 = 0;
432 r1 = 0;
David Woodhousee05fdd92020-06-19 12:40:20 +0100433 }
434
Sam Shihdafe0fb2022-04-21 14:23:51 +0800435 /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
436 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PUPD, !pullup);
437 if (err)
438 return err;
439
440 /* Also set PUPD/R0/R1 if the pin has them */
441 mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_R0, r0);
442 mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_R1, r1);
443
Sam Shihcf400b62020-01-10 16:30:28 +0800444 return 0;
445}
446
Sam Shihdafe0fb2022-04-21 14:23:51 +0800447int mtk_pinconf_bias_set(struct udevice *dev, u32 pin, u32 arg, u32 val)
448{
449 int err;
450 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
Sam Shih1a80ef52022-04-21 14:23:53 +0800451 struct mtk_io_type_desc io_type;
Sam Shihdafe0fb2022-04-21 14:23:51 +0800452 int rev = priv->soc->rev;
453 bool disable, pullup;
454
455 disable = (arg == PIN_CONFIG_BIAS_DISABLE);
456 pullup = (arg == PIN_CONFIG_BIAS_PULL_UP);
457
Sam Shih1a80ef52022-04-21 14:23:53 +0800458 if (!mtk_get_pin_io_type(dev, pin, &io_type)) {
459 if (io_type.bias_set)
460 err = io_type.bias_set(dev, pin, disable, pullup,
461 val);
462 else
463 err = -EINVAL;
464
465 } else if (rev == MTK_PINCTRL_V0) {
Sam Shihdafe0fb2022-04-21 14:23:51 +0800466 err = mtk_pinconf_bias_set_v0(dev, pin, disable, pullup, val);
Sam Shih1a80ef52022-04-21 14:23:53 +0800467 } else {
Sam Shihdafe0fb2022-04-21 14:23:51 +0800468 err = mtk_pinconf_bias_set_v1(dev, pin, disable, pullup, val);
Sam Shih1a80ef52022-04-21 14:23:53 +0800469 }
Sam Shihdafe0fb2022-04-21 14:23:51 +0800470
471 return err;
472}
473
Sam Shihcf400b62020-01-10 16:30:28 +0800474int mtk_pinconf_input_enable_v1(struct udevice *dev, u32 pin, u32 arg)
475{
476 int err;
477
478 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_IES, 1);
479 if (err)
480 return err;
481 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 0);
482 if (err)
483 return err;
Sam Shihdafe0fb2022-04-21 14:23:51 +0800484
485 return 0;
486}
487
488int mtk_pinconf_input_enable(struct udevice *dev, u32 pin, u32 arg)
489{
490 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
Sam Shih1a80ef52022-04-21 14:23:53 +0800491 struct mtk_io_type_desc io_type;
492
Sam Shihdafe0fb2022-04-21 14:23:51 +0800493 int rev = priv->soc->rev;
494
Sam Shih1a80ef52022-04-21 14:23:53 +0800495 if (!mtk_get_pin_io_type(dev, pin, &io_type))
496 if (io_type.input_enable)
497 return io_type.input_enable(dev, pin, arg);
Sam Shihdafe0fb2022-04-21 14:23:51 +0800498 if (rev == MTK_PINCTRL_V1)
499 return mtk_pinconf_input_enable_v1(dev, pin, arg);
500
Sam Shihcf400b62020-01-10 16:30:28 +0800501 return 0;
502}
503
504int mtk_pinconf_drive_set_v0(struct udevice *dev, u32 pin, u32 arg)
Ryder Lee01aa9d12018-11-15 10:07:58 +0800505{
506 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
507 const struct mtk_pin_desc *desc = &priv->soc->pins[pin];
508 const struct mtk_drive_desc *tb;
509 int err = -ENOTSUPP;
510
511 tb = &mtk_drive[desc->drv_n];
512 /* 4mA when (e8, e4) = (0, 0)
513 * 8mA when (e8, e4) = (0, 1)
514 * 12mA when (e8, e4) = (1, 0)
515 * 16mA when (e8, e4) = (1, 1)
516 */
517 if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
518 arg = (arg / tb->step - 1) * tb->scal;
Sam Shihcf400b62020-01-10 16:30:28 +0800519 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_E4,
520 arg & 0x1);
521 if (err)
522 return err;
523 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_E8,
524 (arg & 0x2) >> 1);
525 if (err)
526 return err;
527 }
Ryder Lee01aa9d12018-11-15 10:07:58 +0800528
Weijie Gao4fd0be02023-07-19 17:16:42 +0800529 return err;
Sam Shihcf400b62020-01-10 16:30:28 +0800530}
531
Sam Shihcf400b62020-01-10 16:30:28 +0800532int mtk_pinconf_drive_set_v1(struct udevice *dev, u32 pin, u32 arg)
533{
534 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
535 const struct mtk_pin_desc *desc = &priv->soc->pins[pin];
536 const struct mtk_drive_desc *tb;
537 int err = -ENOTSUPP;
538
539 tb = &mtk_drive[desc->drv_n];
540 if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
541 arg = (arg / tb->step - 1) * tb->scal;
Ryder Lee01aa9d12018-11-15 10:07:58 +0800542 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DRV, arg);
543 if (err)
544 return err;
545 }
546
Weijie Gao4fd0be02023-07-19 17:16:42 +0800547 return err;
Ryder Lee01aa9d12018-11-15 10:07:58 +0800548}
549
Sam Shihdafe0fb2022-04-21 14:23:51 +0800550int mtk_pinconf_drive_set(struct udevice *dev, u32 pin, u32 arg)
551{
552 int err;
553 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
Sam Shih1a80ef52022-04-21 14:23:53 +0800554 struct mtk_io_type_desc io_type;
Sam Shihdafe0fb2022-04-21 14:23:51 +0800555 int rev = priv->soc->rev;
556
Sam Shih1a80ef52022-04-21 14:23:53 +0800557 if (!mtk_get_pin_io_type(dev, pin, &io_type)) {
558 if (io_type.drive_set)
559 err = io_type.drive_set(dev, pin, arg);
560 else
561 err = -EINVAL;
562 } else if (rev == MTK_PINCTRL_V0) {
Sam Shihdafe0fb2022-04-21 14:23:51 +0800563 err = mtk_pinconf_drive_set_v0(dev, pin, arg);
Sam Shih1a80ef52022-04-21 14:23:53 +0800564 } else {
Sam Shihdafe0fb2022-04-21 14:23:51 +0800565 err = mtk_pinconf_drive_set_v1(dev, pin, arg);
Sam Shih1a80ef52022-04-21 14:23:53 +0800566 }
Sam Shihdafe0fb2022-04-21 14:23:51 +0800567
568 return err;
569}
570
Ryder Lee01aa9d12018-11-15 10:07:58 +0800571static int mtk_pinconf_set(struct udevice *dev, unsigned int pin,
572 unsigned int param, unsigned int arg)
573{
574 int err = 0;
575
576 switch (param) {
577 case PIN_CONFIG_BIAS_DISABLE:
578 case PIN_CONFIG_BIAS_PULL_UP:
579 case PIN_CONFIG_BIAS_PULL_DOWN:
Sam Shihdafe0fb2022-04-21 14:23:51 +0800580 err = mtk_pinconf_bias_set(dev, pin, param, arg);
Ryder Lee01aa9d12018-11-15 10:07:58 +0800581 if (err)
582 goto err;
583 break;
584 case PIN_CONFIG_OUTPUT_ENABLE:
585 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_SMT, 0);
586 if (err)
587 goto err;
588 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 1);
589 if (err)
590 goto err;
591 break;
592 case PIN_CONFIG_INPUT_ENABLE:
Sam Shihdafe0fb2022-04-21 14:23:51 +0800593 err = mtk_pinconf_input_enable(dev, pin, param);
Ryder Lee01aa9d12018-11-15 10:07:58 +0800594 if (err)
595 goto err;
596 break;
597 case PIN_CONFIG_OUTPUT:
598 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 1);
599 if (err)
600 goto err;
601
602 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DO, arg);
603 if (err)
604 goto err;
605 break;
606 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
607 /* arg = 1: Input mode & SMT enable ;
608 * arg = 0: Output mode & SMT disable
609 */
610 arg = arg ? 2 : 1;
611 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR,
612 arg & 1);
613 if (err)
614 goto err;
615
616 err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_SMT,
617 !!(arg & 2));
618 if (err)
619 goto err;
620 break;
621 case PIN_CONFIG_DRIVE_STRENGTH:
Sam Shihdafe0fb2022-04-21 14:23:51 +0800622 err = mtk_pinconf_drive_set(dev, pin, arg);
Ryder Lee01aa9d12018-11-15 10:07:58 +0800623 if (err)
624 goto err;
625 break;
626
627 default:
628 err = -ENOTSUPP;
629 }
630
631err:
632
633 return err;
634}
635
636static int mtk_pinconf_group_set(struct udevice *dev,
637 unsigned int group_selector,
638 unsigned int param, unsigned int arg)
639{
640 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
641 const struct mtk_group_desc *grp =
642 &priv->soc->grps[group_selector];
643 int i, ret;
644
645 for (i = 0; i < grp->num_pins; i++) {
646 ret = mtk_pinconf_set(dev, grp->pins[i], param, arg);
647 if (ret)
648 return ret;
649 }
650
651 return 0;
652}
653#endif
654
655const struct pinctrl_ops mtk_pinctrl_ops = {
656 .get_pins_count = mtk_get_pins_count,
657 .get_pin_name = mtk_get_pin_name,
Sam Shihe254d2c2021-03-05 10:22:19 +0800658 .get_pin_muxing = mtk_get_pin_muxing,
Ryder Lee01aa9d12018-11-15 10:07:58 +0800659 .get_groups_count = mtk_get_groups_count,
660 .get_group_name = mtk_get_group_name,
661 .get_functions_count = mtk_get_functions_count,
662 .get_function_name = mtk_get_function_name,
Weijie Gaof9c61062023-07-19 17:16:46 +0800663 .pinmux_set = mtk_pinmux_set,
Ryder Lee01aa9d12018-11-15 10:07:58 +0800664 .pinmux_group_set = mtk_pinmux_group_set,
665#if CONFIG_IS_ENABLED(PINCONF)
666 .pinconf_num_params = ARRAY_SIZE(mtk_conf_params),
667 .pinconf_params = mtk_conf_params,
668 .pinconf_set = mtk_pinconf_set,
669 .pinconf_group_set = mtk_pinconf_group_set,
670#endif
671 .set_state = pinctrl_generic_set_state,
672};
673
Weijie Gao70a2b422021-03-05 10:22:26 +0800674#if CONFIG_IS_ENABLED(DM_GPIO) || \
Simon Glass83061db2021-07-10 21:14:30 -0600675 (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO))
Ryder Lee01aa9d12018-11-15 10:07:58 +0800676static int mtk_gpio_get(struct udevice *dev, unsigned int off)
677{
678 int val, err;
679
680 err = mtk_hw_get_value(dev->parent, off, PINCTRL_PIN_REG_DI, &val);
681 if (err)
682 return err;
683
684 return !!val;
685}
686
687static int mtk_gpio_set(struct udevice *dev, unsigned int off, int val)
688{
689 return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DO, !!val);
690}
691
692static int mtk_gpio_get_direction(struct udevice *dev, unsigned int off)
693{
694 int val, err;
695
696 err = mtk_hw_get_value(dev->parent, off, PINCTRL_PIN_REG_DIR, &val);
697 if (err)
698 return err;
699
700 return val ? GPIOF_OUTPUT : GPIOF_INPUT;
701}
702
703static int mtk_gpio_direction_input(struct udevice *dev, unsigned int off)
704{
705 return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DIR, 0);
706}
707
708static int mtk_gpio_direction_output(struct udevice *dev,
709 unsigned int off, int val)
710{
711 mtk_gpio_set(dev, off, val);
712
713 /* And set the requested value */
714 return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DIR, 1);
715}
716
717static int mtk_gpio_request(struct udevice *dev, unsigned int off,
718 const char *label)
719{
Sam Shihcf400b62020-01-10 16:30:28 +0800720 struct mtk_pinctrl_priv *priv = dev_get_priv(dev->parent);
721
722 return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_MODE,
723 priv->soc->gpio_mode);
Ryder Lee01aa9d12018-11-15 10:07:58 +0800724}
725
726static int mtk_gpio_probe(struct udevice *dev)
727{
728 struct mtk_pinctrl_priv *priv = dev_get_priv(dev->parent);
729 struct gpio_dev_priv *uc_priv;
730
731 uc_priv = dev_get_uclass_priv(dev);
732 uc_priv->bank_name = priv->soc->name;
733 uc_priv->gpio_count = priv->soc->npins;
734
735 return 0;
736}
737
738static const struct dm_gpio_ops mtk_gpio_ops = {
739 .request = mtk_gpio_request,
740 .set_value = mtk_gpio_set,
741 .get_value = mtk_gpio_get,
742 .get_function = mtk_gpio_get_direction,
743 .direction_input = mtk_gpio_direction_input,
744 .direction_output = mtk_gpio_direction_output,
745};
746
747static struct driver mtk_gpio_driver = {
748 .name = "mediatek_gpio",
749 .id = UCLASS_GPIO,
750 .probe = mtk_gpio_probe,
751 .ops = &mtk_gpio_ops,
752};
753
754static int mtk_gpiochip_register(struct udevice *parent)
755{
756 struct uclass_driver *drv;
757 struct udevice *dev;
758 int ret;
759 ofnode node;
760
761 drv = lists_uclass_lookup(UCLASS_GPIO);
762 if (!drv)
763 return -ENOENT;
764
Heinrich Schuchardt97bf7372020-12-27 21:18:26 +0100765 ret = -ENOENT;
Ryder Lee01aa9d12018-11-15 10:07:58 +0800766 dev_for_each_subnode(node, parent)
767 if (ofnode_read_bool(node, "gpio-controller")) {
768 ret = 0;
769 break;
770 }
771
772 if (ret)
773 return ret;
774
775 ret = device_bind_with_driver_data(parent, &mtk_gpio_driver,
776 "mediatek_gpio", 0, node,
777 &dev);
778 if (ret)
779 return ret;
780
781 return 0;
782}
Weijie Gao70a2b422021-03-05 10:22:26 +0800783#endif
Ryder Lee01aa9d12018-11-15 10:07:58 +0800784
785int mtk_pinctrl_common_probe(struct udevice *dev,
Weijie Gao7cb50cd2023-07-19 17:16:37 +0800786 const struct mtk_pinctrl_soc *soc)
Ryder Lee01aa9d12018-11-15 10:07:58 +0800787{
788 struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
Weijie Gao70a2b422021-03-05 10:22:26 +0800789 int ret = 0;
Sam Shih10334e02022-04-21 14:23:52 +0800790 u32 i = 0;
791 fdt_addr_t addr;
792 u32 base_calc = soc->base_calc;
793 u32 nbase_names = soc->nbase_names;
Ryder Lee01aa9d12018-11-15 10:07:58 +0800794
795 priv->soc = soc;
796
Sam Shih10334e02022-04-21 14:23:52 +0800797 if (!base_calc)
798 nbase_names = 1;
799
800 for (i = 0; i < nbase_names; i++) {
801 addr = devfdt_get_addr_index(dev, i);
802 if (addr == FDT_ADDR_T_NONE)
803 return -EINVAL;
804 priv->base[i] = (void __iomem *)addr;
805 }
806
Weijie Gao70a2b422021-03-05 10:22:26 +0800807#if CONFIG_IS_ENABLED(DM_GPIO) || \
Simon Glass83061db2021-07-10 21:14:30 -0600808 (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO))
Ryder Lee01aa9d12018-11-15 10:07:58 +0800809 ret = mtk_gpiochip_register(dev);
Weijie Gao70a2b422021-03-05 10:22:26 +0800810#endif
Ryder Lee01aa9d12018-11-15 10:07:58 +0800811
Weijie Gao70a2b422021-03-05 10:22:26 +0800812 return ret;
Ryder Lee01aa9d12018-11-15 10:07:58 +0800813}