c53e2c391e32b46626807fbfcd1beb8cc30060b6
[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 (desc->funcs && !desc->funcs[desc->eint.eint_m].name)
263                 virt_gpio = true;
264
265         return virt_gpio;
266 }
267
268 static int mtk_xt_get_gpio_n(void *data, unsigned long eint_n,
269                              unsigned int *gpio_n,
270                              struct gpio_chip **gpio_chip)
271 {
272         struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
273         const struct mtk_pin_desc *desc;
274
275         desc = (const struct mtk_pin_desc *)hw->soc->pins;
276         *gpio_chip = &hw->chip;
277
278         /* Be greedy to guess first gpio_n is equal to eint_n */
279         if (desc[eint_n].eint.eint_n == eint_n)
280                 *gpio_n = eint_n;
281         else
282                 *gpio_n = mtk_xt_find_eint_num(hw, eint_n);
283
284         return *gpio_n == EINT_NA ? -EINVAL : 0;
285 }
286
287 static int mtk_xt_get_gpio_state(void *data, unsigned long eint_n)
288 {
289         struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
290         const struct mtk_pin_desc *desc;
291         struct gpio_chip *gpio_chip;
292         unsigned int gpio_n;
293         int value, err;
294
295         err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
296         if (err)
297                 return err;
298
299         desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
300
301         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
302         if (err)
303                 return err;
304
305         return !!value;
306 }
307
308 static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n)
309 {
310         struct mtk_pinctrl *hw = (struct mtk_pinctrl *)data;
311         const struct mtk_pin_desc *desc;
312         struct gpio_chip *gpio_chip;
313         unsigned int gpio_n;
314         int err;
315
316         err = mtk_xt_get_gpio_n(hw, eint_n, &gpio_n, &gpio_chip);
317         if (err)
318                 return err;
319
320         if (mtk_is_virt_gpio(hw, gpio_n))
321                 return 0;
322
323         desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];
324
325         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
326                                desc->eint.eint_m);
327         if (err)
328                 return err;
329
330         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_INPUT);
331         if (err)
332                 return err;
333
334         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, MTK_ENABLE);
335         /* SMT is supposed to be supported by every real GPIO and doesn't
336          * support virtual GPIOs, so the extra condition err != -ENOTSUPP
337          * is just for adding EINT support to these virtual GPIOs. It should
338          * add an extra flag in the pin descriptor when more pins with
339          * distinctive characteristic come out.
340          */
341         if (err && err != -ENOTSUPP)
342                 return err;
343
344         return 0;
345 }
346
347 static const struct mtk_eint_xt mtk_eint_xt = {
348         .get_gpio_n = mtk_xt_get_gpio_n,
349         .get_gpio_state = mtk_xt_get_gpio_state,
350         .set_gpio_as_eint = mtk_xt_set_gpio_as_eint,
351 };
352
353 int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
354 {
355         struct device_node *np = pdev->dev.of_node;
356         struct resource *res;
357
358         if (!IS_ENABLED(CONFIG_EINT_MTK))
359                 return 0;
360
361         if (!of_property_read_bool(np, "interrupt-controller"))
362                 return -ENODEV;
363
364         hw->eint = devm_kzalloc(hw->dev, sizeof(*hw->eint), GFP_KERNEL);
365         if (!hw->eint)
366                 return -ENOMEM;
367
368         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "eint");
369         if (!res) {
370                 dev_err(&pdev->dev, "Unable to get eint resource\n");
371                 return -ENODEV;
372         }
373
374         hw->eint->base = devm_ioremap_resource(&pdev->dev, res);
375         if (IS_ERR(hw->eint->base))
376                 return PTR_ERR(hw->eint->base);
377
378         hw->eint->irq = irq_of_parse_and_map(np, 0);
379         if (!hw->eint->irq)
380                 return -EINVAL;
381
382         if (!hw->soc->eint_hw)
383                 return -ENODEV;
384
385         hw->eint->dev = &pdev->dev;
386         hw->eint->hw = hw->soc->eint_hw;
387         hw->eint->pctl = hw;
388         hw->eint->gpio_xlate = &mtk_eint_xt;
389
390         return mtk_eint_do_init(hw->eint);
391 }
392 EXPORT_SYMBOL_GPL(mtk_build_eint);
393
394 /* Revision 0 */
395 int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw,
396                                  const struct mtk_pin_desc *desc)
397 {
398         int err;
399
400         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU,
401                                MTK_DISABLE);
402         if (err)
403                 return err;
404
405         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD,
406                                MTK_DISABLE);
407         if (err)
408                 return err;
409
410         return 0;
411 }
412 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set);
413
414 int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw,
415                                  const struct mtk_pin_desc *desc, int *res)
416 {
417         int v, v2;
418         int err;
419
420         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &v);
421         if (err)
422                 return err;
423
424         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &v2);
425         if (err)
426                 return err;
427
428         if (v == MTK_ENABLE || v2 == MTK_ENABLE)
429                 return -EINVAL;
430
431         *res = 1;
432
433         return 0;
434 }
435 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get);
436
437 int mtk_pinconf_bias_set(struct mtk_pinctrl *hw,
438                          const struct mtk_pin_desc *desc, bool pullup)
439 {
440         int err, arg;
441
442         arg = pullup ? 1 : 2;
443
444         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, arg & 1);
445         if (err)
446                 return err;
447
448         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD,
449                                !!(arg & 2));
450         if (err)
451                 return err;
452
453         return 0;
454 }
455 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set);
456
457 int mtk_pinconf_bias_get(struct mtk_pinctrl *hw,
458                          const struct mtk_pin_desc *desc, bool pullup, int *res)
459 {
460         int reg, err, v;
461
462         reg = pullup ? PINCTRL_PIN_REG_PU : PINCTRL_PIN_REG_PD;
463
464         err = mtk_hw_get_value(hw, desc, reg, &v);
465         if (err)
466                 return err;
467
468         if (!v)
469                 return -EINVAL;
470
471         *res = 1;
472
473         return 0;
474 }
475 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get);
476
477 /* Revision 1 */
478 int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl *hw,
479                                       const struct mtk_pin_desc *desc)
480 {
481         int err;
482
483         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN,
484                                MTK_DISABLE);
485         if (err)
486                 return err;
487
488         return 0;
489 }
490 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set_rev1);
491
492 int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl *hw,
493                                       const struct mtk_pin_desc *desc, int *res)
494 {
495         int v, err;
496
497         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, &v);
498         if (err)
499                 return err;
500
501         if (v == MTK_ENABLE)
502                 return -EINVAL;
503
504         *res = 1;
505
506         return 0;
507 }
508 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get_rev1);
509
510 int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
511                               const struct mtk_pin_desc *desc, bool pullup)
512 {
513         int err, arg;
514
515         arg = pullup ? MTK_PULLUP : MTK_PULLDOWN;
516
517         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN,
518                                MTK_ENABLE);
519         if (err)
520                 return err;
521
522         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, arg);
523         if (err)
524                 return err;
525
526         return 0;
527 }
528 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_rev1);
529
530 int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
531                               const struct mtk_pin_desc *desc, bool pullup,
532                               int *res)
533 {
534         int err, v;
535
536         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, &v);
537         if (err)
538                 return err;
539
540         if (v == MTK_DISABLE)
541                 return -EINVAL;
542
543         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, &v);
544         if (err)
545                 return err;
546
547         if (pullup ^ (v == MTK_PULLUP))
548                 return -EINVAL;
549
550         *res = 1;
551
552         return 0;
553 }
554 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_rev1);
555
556 /* Combo for the following pull register type:
557  * 1. PU + PD
558  * 2. PULLSEL + PULLEN
559  * 3. PUPD + R0 + R1
560  */
561 static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
562                                 const struct mtk_pin_desc *desc,
563                                 u32 pullup, u32 arg)
564 {
565         int err, pu, pd;
566
567         if (arg == MTK_DISABLE) {
568                 pu = 0;
569                 pd = 0;
570         } else if ((arg == MTK_ENABLE) && pullup) {
571                 pu = 1;
572                 pd = 0;
573         } else if ((arg == MTK_ENABLE) && !pullup) {
574                 pu = 0;
575                 pd = 1;
576         } else {
577                 err = -EINVAL;
578                 goto out;
579         }
580
581         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
582         if (err)
583                 goto out;
584
585         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
586
587 out:
588         return err;
589 }
590
591 static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
592                                 const struct mtk_pin_desc *desc,
593                                 u32 pullup, u32 arg)
594 {
595         int err, enable;
596
597         if (arg == MTK_DISABLE)
598                 enable = 0;
599         else if (arg == MTK_ENABLE)
600                 enable = 1;
601         else {
602                 err = -EINVAL;
603                 goto out;
604         }
605
606         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
607         if (err)
608                 goto out;
609
610         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
611
612 out:
613         return err;
614 }
615
616 static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
617                                 const struct mtk_pin_desc *desc,
618                                 u32 pullup, u32 arg)
619 {
620         int err, r0, r1;
621
622         if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) {
623                 pullup = 0;
624                 r0 = 0;
625                 r1 = 0;
626         } else if (arg == MTK_PUPD_SET_R1R0_01) {
627                 r0 = 1;
628                 r1 = 0;
629         } else if (arg == MTK_PUPD_SET_R1R0_10) {
630                 r0 = 0;
631                 r1 = 1;
632         } else if (arg == MTK_PUPD_SET_R1R0_11) {
633                 r0 = 1;
634                 r1 = 1;
635         } else {
636                 err = -EINVAL;
637                 goto out;
638         }
639
640         /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
641         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup);
642         if (err)
643                 goto out;
644
645         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0);
646         if (err)
647                 goto out;
648
649         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1);
650
651 out:
652         return err;
653 }
654
655 static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
656                                 const struct mtk_pin_desc *desc,
657                                 u32 *pullup, u32 *enable)
658 {
659         int err, pu, pd;
660
661         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
662         if (err)
663                 goto out;
664
665         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
666         if (err)
667                 goto out;
668
669         if (pu == 0 && pd == 0) {
670                 *pullup = 0;
671                 *enable = MTK_DISABLE;
672         } else if (pu == 1 && pd == 0) {
673                 *pullup = 1;
674                 *enable = MTK_ENABLE;
675         } else if (pu == 0 && pd == 1) {
676                 *pullup = 0;
677                 *enable = MTK_ENABLE;
678         } else
679                 err = -EINVAL;
680
681 out:
682         return err;
683 }
684
685 static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
686                                 const struct mtk_pin_desc *desc,
687                                 u32 *pullup, u32 *enable)
688 {
689         int err;
690
691         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
692         if (err)
693                 goto out;
694
695         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
696
697 out:
698         return err;
699 }
700
701 static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
702                                 const struct mtk_pin_desc *desc,
703                                 u32 *pullup, u32 *enable)
704 {
705         int err, r0, r1;
706
707         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup);
708         if (err)
709                 goto out;
710         /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
711         *pullup = !(*pullup);
712
713         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0);
714         if (err)
715                 goto out;
716
717         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1);
718         if (err)
719                 goto out;
720
721         if ((r1 == 0) && (r0 == 0))
722                 *enable = MTK_PUPD_SET_R1R0_00;
723         else if ((r1 == 0) && (r0 == 1))
724                 *enable = MTK_PUPD_SET_R1R0_01;
725         else if ((r1 == 1) && (r0 == 0))
726                 *enable = MTK_PUPD_SET_R1R0_10;
727         else if ((r1 == 1) && (r0 == 1))
728                 *enable = MTK_PUPD_SET_R1R0_11;
729         else
730                 err = -EINVAL;
731
732 out:
733         return err;
734 }
735
736 int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
737                                 const struct mtk_pin_desc *desc,
738                                 u32 pullup, u32 arg)
739 {
740         int err;
741
742         err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
743         if (!err)
744                 goto out;
745
746         err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
747         if (!err)
748                 goto out;
749
750         err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
751
752 out:
753         return err;
754 }
755 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo);
756
757 int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
758                               const struct mtk_pin_desc *desc,
759                               u32 *pullup, u32 *enable)
760 {
761         int err;
762
763         err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
764         if (!err)
765                 goto out;
766
767         err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
768         if (!err)
769                 goto out;
770
771         err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
772
773 out:
774         return err;
775 }
776 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_combo);
777
778 /* Revision 0 */
779 int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
780                           const struct mtk_pin_desc *desc, u32 arg)
781 {
782         const struct mtk_drive_desc *tb;
783         int err = -ENOTSUPP;
784
785         tb = &mtk_drive[desc->drv_n];
786         /* 4mA when (e8, e4) = (0, 0)
787          * 8mA when (e8, e4) = (0, 1)
788          * 12mA when (e8, e4) = (1, 0)
789          * 16mA when (e8, e4) = (1, 1)
790          */
791         if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
792                 arg = (arg / tb->step - 1) * tb->scal;
793                 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_E4,
794                                        arg & 0x1);
795                 if (err)
796                         return err;
797
798                 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_E8,
799                                        (arg & 0x2) >> 1);
800                 if (err)
801                         return err;
802         }
803
804         return err;
805 }
806 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set);
807
808 int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
809                           const struct mtk_pin_desc *desc, int *val)
810 {
811         const struct mtk_drive_desc *tb;
812         int err, val1, val2;
813
814         tb = &mtk_drive[desc->drv_n];
815
816         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_E4, &val1);
817         if (err)
818                 return err;
819
820         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_E8, &val2);
821         if (err)
822                 return err;
823
824         /* 4mA when (e8, e4) = (0, 0); 8mA when (e8, e4) = (0, 1)
825          * 12mA when (e8, e4) = (1, 0); 16mA when (e8, e4) = (1, 1)
826          */
827         *val = (((val2 << 1) + val1) / tb->scal + 1) * tb->step;
828
829         return 0;
830 }
831 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get);
832
833 /* Revision 1 */
834 int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
835                                const struct mtk_pin_desc *desc, u32 arg)
836 {
837         const struct mtk_drive_desc *tb;
838         int err = -ENOTSUPP;
839
840         tb = &mtk_drive[desc->drv_n];
841
842         if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
843                 arg = (arg / tb->step - 1) * tb->scal;
844
845                 err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV,
846                                        arg);
847                 if (err)
848                         return err;
849         }
850
851         return err;
852 }
853 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_rev1);
854
855 int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
856                                const struct mtk_pin_desc *desc, int *val)
857 {
858         const struct mtk_drive_desc *tb;
859         int err, val1;
860
861         tb = &mtk_drive[desc->drv_n];
862
863         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, &val1);
864         if (err)
865                 return err;
866
867         *val = ((val1 & 0x7) / tb->scal + 1) * tb->step;
868
869         return 0;
870 }
871 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_rev1);
872
873 int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
874                                const struct mtk_pin_desc *desc, u32 arg)
875 {
876         return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
877 }
878 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_raw);
879
880 int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
881                                const struct mtk_pin_desc *desc, int *val)
882 {
883         return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
884 }
885 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_raw);
886
887 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
888                              const struct mtk_pin_desc *desc, bool pullup,
889                              u32 arg)
890 {
891         int err;
892
893         /* 10K off & 50K (75K) off, when (R0, R1) = (0, 0);
894          * 10K off & 50K (75K) on, when (R0, R1) = (0, 1);
895          * 10K on & 50K (75K) off, when (R0, R1) = (1, 0);
896          * 10K on & 50K (75K) on, when (R0, R1) = (1, 1)
897          */
898         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, arg & 1);
899         if (err)
900                 return 0;
901
902         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1,
903                                !!(arg & 2));
904         if (err)
905                 return 0;
906
907         arg = pullup ? 0 : 1;
908
909         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, arg);
910
911         /* If PUPD register is not supported for that pin, let's fallback to
912          * general bias control.
913          */
914         if (err == -ENOTSUPP) {
915                 if (hw->soc->bias_set) {
916                         err = hw->soc->bias_set(hw, desc, pullup);
917                         if (err)
918                                 return err;
919                 } else {
920                         return -ENOTSUPP;
921                 }
922         }
923
924         return err;
925 }
926 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_set);
927
928 int mtk_pinconf_adv_pull_get(struct mtk_pinctrl *hw,
929                              const struct mtk_pin_desc *desc, bool pullup,
930                              u32 *val)
931 {
932         u32 t, t2;
933         int err;
934
935         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, &t);
936
937         /* If PUPD register is not supported for that pin, let's fallback to
938          * general bias control.
939          */
940         if (err == -ENOTSUPP) {
941                 if (hw->soc->bias_get) {
942                         err = hw->soc->bias_get(hw, desc, pullup, val);
943                         if (err)
944                                 return err;
945                 } else {
946                         return -ENOTSUPP;
947                 }
948         } else {
949                 /* t == 0 supposes PULLUP for the customized PULL setup */
950                 if (err)
951                         return err;
952
953                 if (pullup ^ !t)
954                         return -EINVAL;
955         }
956
957         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &t);
958         if (err)
959                 return err;
960
961         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &t2);
962         if (err)
963                 return err;
964
965         *val = (t | t2 << 1) & 0x7;
966
967         return 0;
968 }
969 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_get);
970
971 int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw,
972                               const struct mtk_pin_desc *desc, u32 arg)
973 {
974         int err;
975         int en = arg & 1;
976         int e0 = !!(arg & 2);
977         int e1 = !!(arg & 4);
978
979         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_EN, en);
980         if (err)
981                 return err;
982
983         if (!en)
984                 return err;
985
986         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_E0, e0);
987         if (err)
988                 return err;
989
990         err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV_E1, e1);
991         if (err)
992                 return err;
993
994         return err;
995 }
996 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set);
997
998 int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw,
999                               const struct mtk_pin_desc *desc, u32 *val)
1000 {
1001         u32 en, e0, e1;
1002         int err;
1003
1004         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_EN, &en);
1005         if (err)
1006                 return err;
1007
1008         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_E0, &e0);
1009         if (err)
1010                 return err;
1011
1012         err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV_E1, &e1);
1013         if (err)
1014                 return err;
1015
1016         *val = (en | e0 << 1 | e1 << 2) & 0x7;
1017
1018         return 0;
1019 }
1020 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get);
1021
1022 MODULE_LICENSE("GPL v2");
1023 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
1024 MODULE_DESCRIPTION("Pin configuration library module for mediatek SoCs");