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