1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2018 MediaTek Inc.
4 *
5 * Author: Sean Wang <sean.wang@mediatek.com>
6 *
7 */
8
9 #include <dt-bindings/pinctrl/mt65xx.h>
10 #include <linux/device.h>
11 #include <linux/err.h>
12 #include <linux/gpio/driver.h>
13 #include <linux/platform_device.h>
14 #include <linux/io.h>
15 #include <linux/module.h>
16 #include <linux/of_irq.h>
17
18 #include "mtk-eint.h"
19 #include "pinctrl-mtk-common-v2.h"
20
21 /**
22 * struct mtk_drive_desc - the structure that holds the information
23 * of the driving current
24 * @min: the minimum current of this group
25 * @max: the maximum current of this group
26 * @step: the step current of this group
27 * @scal: the weight factor
28 *
29 * formula: output = ((input) / step - 1) * scal
30 */
31 struct mtk_drive_desc {
32 u8 min;
33 u8 max;
34 u8 step;
35 u8 scal;
36 };
37
38 /* The groups of drive strength */
39 static const struct mtk_drive_desc mtk_drive[] = {
40 [DRV_GRP0] = { 4, 16, 4, 1 },
41 [DRV_GRP1] = { 4, 16, 4, 2 },
42 [DRV_GRP2] = { 2, 8, 2, 1 },
43 [DRV_GRP3] = { 2, 8, 2, 2 },
44 [DRV_GRP4] = { 2, 16, 2, 1 },
45 };
46
mtk_w32(struct mtk_pinctrl * pctl,u8 i,u32 reg,u32 val)47 static void mtk_w32(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 val)
48 {
49 writel_relaxed(val, pctl->base[i] + reg);
50 }
51
mtk_r32(struct mtk_pinctrl * pctl,u8 i,u32 reg)52 static u32 mtk_r32(struct mtk_pinctrl *pctl, u8 i, u32 reg)
53 {
54 return readl_relaxed(pctl->base[i] + reg);
55 }
56
mtk_rmw(struct mtk_pinctrl * pctl,u8 i,u32 reg,u32 mask,u32 set)57 void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set)
58 {
59 u32 val;
60 unsigned long flags;
61
62 spin_lock_irqsave(&pctl->lock, flags);
63
64 val = mtk_r32(pctl, i, reg);
65 val &= ~mask;
66 val |= set;
67 mtk_w32(pctl, i, reg, val);
68
69 spin_unlock_irqrestore(&pctl->lock, flags);
70 }
71
mtk_hw_pin_field_lookup(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,int field,struct mtk_pin_field * pfd)72 static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
73 const struct mtk_pin_desc *desc,
74 int field, struct mtk_pin_field *pfd)
75 {
76 const struct mtk_pin_field_calc *c;
77 const struct mtk_pin_reg_calc *rc;
78 int start = 0, end, check;
79 bool found = false;
80 u32 bits;
81
82 if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
83 rc = &hw->soc->reg_cal[field];
84 } else {
85 dev_dbg(hw->dev,
86 "Not support field %d for this soc\n", field);
87 return -ENOTSUPP;
88 }
89
90 end = rc->nranges - 1;
91
92 while (start <= end) {
93 check = (start + end) >> 1;
94 if (desc->number >= rc->range[check].s_pin
95 && desc->number <= rc->range[check].e_pin) {
96 found = true;
97 break;
98 } else if (start == end)
99 break;
100 else if (desc->number < rc->range[check].s_pin)
101 end = check - 1;
102 else
103 start = check + 1;
104 }
105
106 if (!found) {
107 dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
108 field, desc->number, desc->name);
109 return -ENOTSUPP;
110 }
111
112 c = rc->range + check;
113
114 if (c->i_base > hw->nbase - 1) {
115 dev_err(hw->dev,
116 "Invalid base for field %d for pin = %d (%s)\n",
117 field, desc->number, desc->name);
118 return -EINVAL;
119 }
120
121 /* Calculated bits as the overall offset the pin is located at,
122 * if c->fixed is held, that determines the all the pins in the
123 * range use the same field with the s_pin.
124 */
125 bits = c->fixed ? c->s_bit : c->s_bit +
126 (desc->number - c->s_pin) * (c->x_bits);
127
128 /* Fill pfd from bits. For example 32-bit register applied is assumed
129 * when c->sz_reg is equal to 32.
130 */
131 pfd->index = c->i_base;
132 pfd->offset = c->s_addr + c->x_addrs * (bits / c->sz_reg);
133 pfd->bitpos = bits % c->sz_reg;
134 pfd->mask = (1 << c->x_bits) - 1;
135
136 /* pfd->next is used for indicating that bit wrapping-around happens
137 * which requires the manipulation for bit 0 starting in the next
138 * register to form the complete field read/write.
139 */
140 pfd->next = pfd->bitpos + c->x_bits > c->sz_reg ? c->x_addrs : 0;
141
142 return 0;
143 }
144
mtk_hw_pin_field_get(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,int field,struct mtk_pin_field * pfd)145 static int mtk_hw_pin_field_get(struct mtk_pinctrl *hw,
146 const struct mtk_pin_desc *desc,
147 int field, struct mtk_pin_field *pfd)
148 {
149 if (field < 0 || field >= PINCTRL_PIN_REG_MAX) {
150 dev_err(hw->dev, "Invalid Field %d\n", field);
151 return -EINVAL;
152 }
153
154 return mtk_hw_pin_field_lookup(hw, desc, field, pfd);
155 }
156
mtk_hw_bits_part(struct mtk_pin_field * pf,int * h,int * l)157 static void mtk_hw_bits_part(struct mtk_pin_field *pf, int *h, int *l)
158 {
159 *l = 32 - pf->bitpos;
160 *h = get_count_order(pf->mask) - *l;
161 }
162
mtk_hw_write_cross_field(struct mtk_pinctrl * hw,struct mtk_pin_field * pf,int value)163 static void mtk_hw_write_cross_field(struct mtk_pinctrl *hw,
164 struct mtk_pin_field *pf, int value)
165 {
166 int nbits_l, nbits_h;
167
168 mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
169
170 mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos,
171 (value & pf->mask) << pf->bitpos);
172
173 mtk_rmw(hw, pf->index, pf->offset + pf->next, BIT(nbits_h) - 1,
174 (value & pf->mask) >> nbits_l);
175 }
176
mtk_hw_read_cross_field(struct mtk_pinctrl * hw,struct mtk_pin_field * pf,int * value)177 static void mtk_hw_read_cross_field(struct mtk_pinctrl *hw,
178 struct mtk_pin_field *pf, int *value)
179 {
180 int nbits_l, nbits_h, h, l;
181
182 mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
183
184 l = (mtk_r32(hw, pf->index, pf->offset)
185 >> pf->bitpos) & (BIT(nbits_l) - 1);
186 h = (mtk_r32(hw, pf->index, pf->offset + pf->next))
187 & (BIT(nbits_h) - 1);
188
189 *value = (h << nbits_l) | l;
190 }
191
mtk_hw_set_value(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,int field,int value)192 int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
193 int field, int value)
194 {
195 struct mtk_pin_field pf;
196 int err;
197
198 err = mtk_hw_pin_field_get(hw, desc, field, &pf);
199 if (err)
200 return err;
201
202 if (value < 0 || value > pf.mask)
203 return -EINVAL;
204
205 if (!pf.next)
206 mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
207 (value & pf.mask) << pf.bitpos);
208 else
209 mtk_hw_write_cross_field(hw, &pf, value);
210
211 return 0;
212 }
213 EXPORT_SYMBOL_GPL(mtk_hw_set_value);
214
mtk_hw_get_value(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,int field,int * value)215 int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
216 int field, int *value)
217 {
218 struct mtk_pin_field pf;
219 int err;
220
221 err = mtk_hw_pin_field_get(hw, desc, field, &pf);
222 if (err)
223 return err;
224
225 if (!pf.next)
226 *value = (mtk_r32(hw, pf.index, pf.offset)
227 >> pf.bitpos) & pf.mask;
228 else
229 mtk_hw_read_cross_field(hw, &pf, value);
230
231 return 0;
232 }
233 EXPORT_SYMBOL_GPL(mtk_hw_get_value);
234
mtk_xt_find_eint_num(struct mtk_pinctrl * hw,unsigned long eint_n)235 static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
236 {
237 const struct mtk_pin_desc *desc;
238 int i = 0;
239
240 desc = (const struct mtk_pin_desc *)hw->soc->pins;
241
242 while (i < hw->soc->npins) {
243 if (desc[i].eint.eint_n == eint_n)
244 return desc[i].number;
245 i++;
246 }
247
248 return EINT_NA;
249 }
250
251 /*
252 * Virtual GPIO only used inside SOC and not being exported to outside SOC.
253 * Some modules use virtual GPIO as eint (e.g. pmif or usb).
254 * In MTK platform, external interrupt (EINT) and GPIO is 1-1 mapping
255 * and we can set GPIO as eint.
256 * But some modules use specific eint which doesn't have real GPIO pin.
257 * So we use virtual GPIO to map it.
258 */
259
mtk_is_virt_gpio(struct mtk_pinctrl * hw,unsigned int gpio_n)260 bool mtk_is_virt_gpio(struct mtk_pinctrl *hw, unsigned int gpio_n)
261 {
262 const struct mtk_pin_desc *desc;
263 bool virt_gpio = false;
264
265 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
266
267 /* if the GPIO is not supported for eint mode */
268 if (desc->eint.eint_m == NO_EINT_SUPPORT)
269 return virt_gpio;
270
271 if (desc->funcs && !desc->funcs[desc->eint.eint_m].name)
272 virt_gpio = true;
273
274 return virt_gpio;
275 }
276 EXPORT_SYMBOL_GPL(mtk_is_virt_gpio);
277
mtk_xt_get_gpio_n(void * data,unsigned long eint_n,unsigned int * gpio_n,struct gpio_chip ** gpio_chip)278 static int mtk_xt_get_gpio_n(void *data, unsigned long eint_n,
279 unsigned int *gpio_n,
280 struct gpio_chip **gpio_chip)
281 {
282 struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
283 const struct mtk_pin_desc *desc;
284
285 desc = (const struct mtk_pin_desc *)hw->soc->pins;
286 *gpio_chip = &hw->chip;
287
288 /* Be greedy to guess first gpio_n is equal to eint_n */
289 if (desc[eint_n].eint.eint_n == eint_n)
290 *gpio_n = eint_n;
291 else
292 *gpio_n = mtk_xt_find_eint_num(hw, eint_n);
293
294 return *gpio_n == EINT_NA ? -EINVAL : 0;
295 }
296
mtk_xt_get_gpio_state(void * data,unsigned long eint_n)297 static int mtk_xt_get_gpio_state(void *data, unsigned long eint_n)
298 {
299 struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
300 const struct mtk_pin_desc *desc;
301 struct gpio_chip *gpio_chip;
302 unsigned int gpio_n;
303 int value, err;
304
305 err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
306 if (err)
307 return err;
308
309 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
310
311 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
312 if (err)
313 return err;
314
315 return !!value;
316 }
317
mtk_xt_set_gpio_as_eint(void * data,unsigned long eint_n)318 static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n)
319 {
320 struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
321 const struct mtk_pin_desc *desc;
322 struct gpio_chip *gpio_chip;
323 unsigned int gpio_n;
324 int err;
325
326 err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
327 if (err)
328 return err;
329
330 if (mtk_is_virt_gpio(hw, gpio_n))
331 return 0;
332
333 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
334
335 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
336 desc->eint.eint_m);
337 if (err)
338 return err;
339
340 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_INPUT);
341 if (err)
342 return err;
343
344 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, MTK_ENABLE);
345 /* SMT is supposed to be supported by every real GPIO and doesn't
346 * support virtual GPIOs, so the extra condition err != -ENOTSUPP
347 * is just for adding EINT support to these virtual GPIOs. It should
348 * add an extra flag in the pin descriptor when more pins with
349 * distinctive characteristic come out.
350 */
351 if (err && err != -ENOTSUPP)
352 return err;
353
354 return 0;
355 }
356
357 static const struct mtk_eint_xt mtk_eint_xt = {
358 .get_gpio_n = mtk_xt_get_gpio_n,
359 .get_gpio_state = mtk_xt_get_gpio_state,
360 .set_gpio_as_eint = mtk_xt_set_gpio_as_eint,
361 };
362
mtk_build_eint(struct mtk_pinctrl * hw,struct platform_device * pdev)363 int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
364 {
365 struct device_node *np = pdev->dev.of_node;
366 int ret;
367
368 if (!IS_ENABLED(CONFIG_EINT_MTK))
369 return 0;
370
371 if (!of_property_read_bool(np, "interrupt-controller"))
372 return -ENODEV;
373
374 hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
375 if (!hw->eint)
376 return -ENOMEM;
377
378 hw->eint->base = devm_platform_ioremap_resource_byname(pdev, "eint");
379 if (IS_ERR(hw->eint->base)) {
380 ret = PTR_ERR(hw->eint->base);
381 goto err_free_eint;
382 }
383
384 hw->eint->irq = irq_of_parse_and_map(np, 0);
385 if (!hw->eint->irq) {
386 ret = -EINVAL;
387 goto err_free_eint;
388 }
389
390 if (!hw->soc->eint_hw) {
391 ret = -ENODEV;
392 goto err_free_eint;
393 }
394
395 hw->eint->dev = &pdev->dev;
396 hw->eint->hw = hw->soc->eint_hw;
397 hw->eint->pctl = hw;
398 hw->eint->gpio_xlate = &mtk_eint_xt;
399
400 return mtk_eint_do_init(hw->eint);
401
402 err_free_eint:
403 devm_kfree(hw->dev, hw->eint);
404 hw->eint = NULL;
405 return ret;
406 }
407 EXPORT_SYMBOL_GPL(mtk_build_eint);
408
409 /* Revision 0 */
mtk_pinconf_bias_disable_set(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc)410 int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw,
411 const struct mtk_pin_desc *desc)
412 {
413 int err;
414
415 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU,
416 MTK_DISABLE);
417 if (err)
418 return err;
419
420 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD,
421 MTK_DISABLE);
422 if (err)
423 return err;
424
425 return 0;
426 }
427 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set);
428
mtk_pinconf_bias_disable_get(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,int * res)429 int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw,
430 const struct mtk_pin_desc *desc, int *res)
431 {
432 int v, v2;
433 int err;
434
435 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &v);
436 if (err)
437 return err;
438
439 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &v2);
440 if (err)
441 return err;
442
443 if (v == MTK_ENABLE || v2 == MTK_ENABLE)
444 return -EINVAL;
445
446 *res = 1;
447
448 return 0;
449 }
450 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get);
451
mtk_pinconf_bias_set(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,bool pullup)452 int mtk_pinconf_bias_set(struct mtk_pinctrl *hw,
453 const struct mtk_pin_desc *desc, bool pullup)
454 {
455 int err, arg;
456
457 arg = pullup ? 1 : 2;
458
459 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, arg & 1);
460 if (err)
461 return err;
462
463 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD,
464 !!(arg & 2));
465 if (err)
466 return err;
467
468 return 0;
469 }
470 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set);
471
mtk_pinconf_bias_get(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,bool pullup,int * res)472 int mtk_pinconf_bias_get(struct mtk_pinctrl *hw,
473 const struct mtk_pin_desc *desc, bool pullup, int *res)
474 {
475 int reg, err, v;
476
477 reg = pullup ? PINCTRL_PIN_REG_PU : PINCTRL_PIN_REG_PD;
478
479 err = mtk_hw_get_value(hw, desc, reg, &v);
480 if (err)
481 return err;
482
483 if (!v)
484 return -EINVAL;
485
486 *res = 1;
487
488 return 0;
489 }
490 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get);
491
492 /* Revision 1 */
mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc)493 int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl *hw,
494 const struct mtk_pin_desc *desc)
495 {
496 return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN,
497 MTK_DISABLE);
498 }
499 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set_rev1);
500
mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,int * res)501 int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl *hw,
502 const struct mtk_pin_desc *desc, int *res)
503 {
504 int v, err;
505
506 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, &v);
507 if (err)
508 return err;
509
510 if (v == MTK_ENABLE)
511 return -EINVAL;
512
513 *res = 1;
514
515 return 0;
516 }
517 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get_rev1);
518
mtk_pinconf_bias_set_rev1(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,bool pullup)519 int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
520 const struct mtk_pin_desc *desc, bool pullup)
521 {
522 int err, arg;
523
524 arg = pullup ? MTK_PULLUP : MTK_PULLDOWN;
525
526 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN,
527 MTK_ENABLE);
528 if (err)
529 return err;
530
531 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, arg);
532 if (err)
533 return err;
534
535 return 0;
536 }
537 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_rev1);
538
mtk_pinconf_bias_get_rev1(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,bool pullup,int * res)539 int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
540 const struct mtk_pin_desc *desc, bool pullup,
541 int *res)
542 {
543 int err, v;
544
545 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, &v);
546 if (err)
547 return err;
548
549 if (v == MTK_DISABLE)
550 return -EINVAL;
551
552 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, &v);
553 if (err)
554 return err;
555
556 if (pullup ^ (v == MTK_PULLUP))
557 return -EINVAL;
558
559 *res = 1;
560
561 return 0;
562 }
563 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_rev1);
564
565 /* Combo for the following pull register type:
566 * 1. PU + PD
567 * 2. PULLSEL + PULLEN
568 * 3. PUPD + R0 + R1
569 */
mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 pullup,u32 arg)570 static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
571 const struct mtk_pin_desc *desc,
572 u32 pullup, u32 arg)
573 {
574 int err, pu, pd;
575
576 if (arg == MTK_DISABLE) {
577 pu = 0;
578 pd = 0;
579 } else if ((arg == MTK_ENABLE) && pullup) {
580 pu = 1;
581 pd = 0;
582 } else if ((arg == MTK_ENABLE) && !pullup) {
583 pu = 0;
584 pd = 1;
585 } else {
586 err = -EINVAL;
587 goto out;
588 }
589
590 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
591 if (err)
592 goto out;
593
594 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
595
596 out:
597 return err;
598 }
599
mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 pullup,u32 arg)600 static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
601 const struct mtk_pin_desc *desc,
602 u32 pullup, u32 arg)
603 {
604 int err, enable;
605
606 if (arg == MTK_DISABLE)
607 enable = 0;
608 else if (arg == MTK_ENABLE)
609 enable = 1;
610 else {
611 err = -EINVAL;
612 goto out;
613 }
614
615 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
616 if (err)
617 goto out;
618
619 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
620
621 out:
622 return err;
623 }
624
mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 pullup,u32 arg)625 static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
626 const struct mtk_pin_desc *desc,
627 u32 pullup, u32 arg)
628 {
629 int err, r0, r1;
630
631 if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) {
632 pullup = 0;
633 r0 = 0;
634 r1 = 0;
635 } else if (arg == MTK_PUPD_SET_R1R0_01) {
636 r0 = 1;
637 r1 = 0;
638 } else if (arg == MTK_PUPD_SET_R1R0_10) {
639 r0 = 0;
640 r1 = 1;
641 } else if (arg == MTK_PUPD_SET_R1R0_11) {
642 r0 = 1;
643 r1 = 1;
644 } else {
645 err = -EINVAL;
646 goto out;
647 }
648
649 /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
650 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup);
651 if (err)
652 goto out;
653
654 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0);
655 if (err)
656 goto out;
657
658 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1);
659
660 out:
661 return err;
662 }
663
mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 * pullup,u32 * enable)664 static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
665 const struct mtk_pin_desc *desc,
666 u32 *pullup, u32 *enable)
667 {
668 int err, pu, pd;
669
670 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
671 if (err)
672 goto out;
673
674 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
675 if (err)
676 goto out;
677
678 if (pu == 0 && pd == 0) {
679 *pullup = 0;
680 *enable = MTK_DISABLE;
681 } else if (pu == 1 && pd == 0) {
682 *pullup = 1;
683 *enable = MTK_ENABLE;
684 } else if (pu == 0 && pd == 1) {
685 *pullup = 0;
686 *enable = MTK_ENABLE;
687 } else
688 err = -EINVAL;
689
690 out:
691 return err;
692 }
693
mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 * pullup,u32 * enable)694 static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
695 const struct mtk_pin_desc *desc,
696 u32 *pullup, u32 *enable)
697 {
698 int err;
699
700 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
701 if (err)
702 goto out;
703
704 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
705
706 out:
707 return err;
708 }
709
mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 * pullup,u32 * enable)710 static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
711 const struct mtk_pin_desc *desc,
712 u32 *pullup, u32 *enable)
713 {
714 int err, r0, r1;
715
716 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup);
717 if (err)
718 goto out;
719 /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
720 *pullup = !(*pullup);
721
722 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0);
723 if (err)
724 goto out;
725
726 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1);
727 if (err)
728 goto out;
729
730 if ((r1 == 0) && (r0 == 0))
731 *enable = MTK_PUPD_SET_R1R0_00;
732 else if ((r1 == 0) && (r0 == 1))
733 *enable = MTK_PUPD_SET_R1R0_01;
734 else if ((r1 == 1) && (r0 == 0))
735 *enable = MTK_PUPD_SET_R1R0_10;
736 else if ((r1 == 1) && (r0 == 1))
737 *enable = MTK_PUPD_SET_R1R0_11;
738 else
739 err = -EINVAL;
740
741 out:
742 return err;
743 }
744
mtk_pinconf_bias_set_combo(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 pullup,u32 arg)745 int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
746 const struct mtk_pin_desc *desc,
747 u32 pullup, u32 arg)
748 {
749 int err;
750
751 err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
752 if (!err)
753 goto out;
754
755 err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
756 if (!err)
757 goto out;
758
759 err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
760
761 out:
762 return err;
763 }
764 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo);
765
mtk_pinconf_bias_get_combo(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 * pullup,u32 * enable)766 int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
767 const struct mtk_pin_desc *desc,
768 u32 *pullup, u32 *enable)
769 {
770 int err;
771
772 err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
773 if (!err)
774 goto out;
775
776 err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
777 if (!err)
778 goto out;
779
780 err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
781
782 out:
783 return err;
784 }
785 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_combo);
786
787 /* Revision 0 */
mtk_pinconf_drive_set(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 arg)788 int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
789 const struct mtk_pin_desc *desc, u32 arg)
790 {
791 const struct mtk_drive_desc *tb;
792 int err = -ENOTSUPP;
793
794 tb = &mtk_drive[desc->drv_n];
795 /* 4mA when (e8, e4) = (0, 0)
796 * 8mA when (e8, e4) = (0, 1)
797 * 12mA when (e8, e4) = (1, 0)
798 * 16mA when (e8, e4) = (1, 1)
799 */
800 if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
801 arg = (arg / tb->step - 1) * tb->scal;
802 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_E4,
803 arg & 0x1);
804 if (err)
805 return err;
806
807 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_E8,
808 (arg & 0x2) >> 1);
809 if (err)
810 return err;
811 }
812
813 return err;
814 }
815 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set);
816
mtk_pinconf_drive_get(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,int * val)817 int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
818 const struct mtk_pin_desc *desc, int *val)
819 {
820 const struct mtk_drive_desc *tb;
821 int err, val1, val2;
822
823 tb = &mtk_drive[desc->drv_n];
824
825 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_E4, &val1);
826 if (err)
827 return err;
828
829 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_E8, &val2);
830 if (err)
831 return err;
832
833 /* 4mA when (e8, e4) = (0, 0); 8mA when (e8, e4) = (0, 1)
834 * 12mA when (e8, e4) = (1, 0); 16mA when (e8, e4) = (1, 1)
835 */
836 *val = (((val2 << 1) + val1) / tb->scal + 1) * tb->step;
837
838 return 0;
839 }
840 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get);
841
842 /* Revision 1 */
mtk_pinconf_drive_set_rev1(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 arg)843 int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
844 const struct mtk_pin_desc *desc, u32 arg)
845 {
846 const struct mtk_drive_desc *tb;
847 int err = -ENOTSUPP;
848
849 tb = &mtk_drive[desc->drv_n];
850
851 if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
852 arg = (arg / tb->step - 1) * tb->scal;
853
854 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV,
855 arg);
856 if (err)
857 return err;
858 }
859
860 return err;
861 }
862 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_rev1);
863
mtk_pinconf_drive_get_rev1(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,int * val)864 int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
865 const struct mtk_pin_desc *desc, int *val)
866 {
867 const struct mtk_drive_desc *tb;
868 int err, val1;
869
870 tb = &mtk_drive[desc->drv_n];
871
872 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, &val1);
873 if (err)
874 return err;
875
876 *val = ((val1 & 0x7) / tb->scal + 1) * tb->step;
877
878 return 0;
879 }
880 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_rev1);
881
mtk_pinconf_drive_set_raw(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 arg)882 int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
883 const struct mtk_pin_desc *desc, u32 arg)
884 {
885 return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
886 }
887 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_raw);
888
mtk_pinconf_drive_get_raw(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,int * val)889 int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
890 const struct mtk_pin_desc *desc, int *val)
891 {
892 return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
893 }
894 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_raw);
895
mtk_pinconf_adv_pull_set(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,bool pullup,u32 arg)896 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
897 const struct mtk_pin_desc *desc, bool pullup,
898 u32 arg)
899 {
900 int err;
901
902 /* 10K off & 50K (75K) off, when (R0, R1) = (0, 0);
903 * 10K off & 50K (75K) on, when (R0, R1) = (0, 1);
904 * 10K on & 50K (75K) off, when (R0, R1) = (1, 0);
905 * 10K on & 50K (75K) on, when (R0, R1) = (1, 1)
906 */
907 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, arg & 1);
908 if (err)
909 return 0;
910
911 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1,
912 !!(arg & 2));
913 if (err)
914 return 0;
915
916 arg = pullup ? 0 : 1;
917
918 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, arg);
919
920 /* If PUPD register is not supported for that pin, let's fallback to
921 * general bias control.
922 */
923 if (err == -ENOTSUPP) {
924 if (hw->soc->bias_set) {
925 err = hw->soc->bias_set(hw, desc, pullup);
926 if (err)
927 return err;
928 } else {
929 err = mtk_pinconf_bias_set_rev1(hw, desc, pullup);
930 if (err)
931 err = mtk_pinconf_bias_set(hw, desc, pullup);
932 }
933 }
934
935 return err;
936 }
937 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_set);
938
mtk_pinconf_adv_pull_get(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,bool pullup,u32 * val)939 int mtk_pinconf_adv_pull_get(struct mtk_pinctrl *hw,
940 const struct mtk_pin_desc *desc, bool pullup,
941 u32 *val)
942 {
943 u32 t, t2;
944 int err;
945
946 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, &t);
947
948 /* If PUPD register is not supported for that pin, let's fallback to
949 * general bias control.
950 */
951 if (err == -ENOTSUPP) {
952 if (hw->soc->bias_get) {
953 err = hw->soc->bias_get(hw, desc, pullup, val);
954 if (err)
955 return err;
956 } else {
957 return -ENOTSUPP;
958 }
959 } else {
960 /* t == 0 supposes PULLUP for the customized PULL setup */
961 if (err)
962 return err;
963
964 if (pullup ^ !t)
965 return -EINVAL;
966 }
967
968 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &t);
969 if (err)
970 return err;
971
972 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &t2);
973 if (err)
974 return err;
975
976 *val = (t | t2 << 1) & 0x7;
977
978 return 0;
979 }
980 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_get);
981
mtk_pinconf_adv_drive_set(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 arg)982 int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw,
983 const struct mtk_pin_desc *desc, u32 arg)
984 {
985 int err;
986 int en = arg & 1;
987 int e0 = !!(arg & 2);
988 int e1 = !!(arg & 4);
989
990 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_EN, en);
991 if (err)
992 return err;
993
994 if (!en)
995 return err;
996
997 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_E0, e0);
998 if (err)
999 return err;
1000
1001 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_E1, e1);
1002 if (err)
1003 return err;
1004
1005 return err;
1006 }
1007 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set);
1008
mtk_pinconf_adv_drive_get(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 * val)1009 int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw,
1010 const struct mtk_pin_desc *desc, u32 *val)
1011 {
1012 u32 en, e0, e1;
1013 int err;
1014
1015 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_EN, &en);
1016 if (err)
1017 return err;
1018
1019 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_E0, &e0);
1020 if (err)
1021 return err;
1022
1023 err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_E1, &e1);
1024 if (err)
1025 return err;
1026
1027 *val = (en | e0 << 1 | e1 << 2) & 0x7;
1028
1029 return 0;
1030 }
1031 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get);
1032
mtk_pinconf_adv_drive_set_raw(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 arg)1033 int mtk_pinconf_adv_drive_set_raw(struct mtk_pinctrl *hw,
1034 const struct mtk_pin_desc *desc, u32 arg)
1035 {
1036 return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_ADV, arg);
1037 }
1038 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set_raw);
1039
mtk_pinconf_adv_drive_get_raw(struct mtk_pinctrl * hw,const struct mtk_pin_desc * desc,u32 * val)1040 int mtk_pinconf_adv_drive_get_raw(struct mtk_pinctrl *hw,
1041 const struct mtk_pin_desc *desc, u32 *val)
1042 {
1043 return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_ADV, val);
1044 }
1045 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get_raw);
1046
1047 MODULE_LICENSE("GPL v2");
1048 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
1049 MODULE_DESCRIPTION("Pin configuration library module for mediatek SoCs");
1050