1
2
3
4
5
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
23
24
25
26
27
28
29
30
31struct mtk_drive_desc {
32 u8 min;
33 u8 max;
34 u8 step;
35 u8 scal;
36};
37
38
39static 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
47static void mtk_w32(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 val)
48{
49 writel_relaxed(val, pctl->base[i] + reg);
50}
51
52static u32 mtk_r32(struct mtk_pinctrl *pctl, u8 i, u32 reg)
53{
54 return readl_relaxed(pctl->base[i] + reg);
55}
56
57void 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
72static 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
122
123
124
125 bits = c->fixed ? c->s_bit : c->s_bit +
126 (desc->number - c->s_pin) * (c->x_bits);
127
128
129
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
137
138
139
140 pfd->next = pfd->bitpos + c->x_bits > c->sz_reg ? c->x_addrs : 0;
141
142 return 0;
143}
144
145static 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
157static 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
163static 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
177static 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
192int 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}
213EXPORT_SYMBOL_GPL(mtk_hw_set_value);
214
215int 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}
233EXPORT_SYMBOL_GPL(mtk_hw_get_value);
234
235static 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
253
254
255
256
257
258
259
260bool 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
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}
276EXPORT_SYMBOL_GPL(mtk_is_virt_gpio);
277
278static 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
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
297static 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
318static 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
346
347
348
349
350
351 if (err && err != -ENOTSUPP)
352 return err;
353
354 return 0;
355}
356
357static 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
363int 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
402err_free_eint:
403 devm_kfree(hw->dev, hw->eint);
404 hw->eint = NULL;
405 return ret;
406}
407EXPORT_SYMBOL_GPL(mtk_build_eint);
408
409
410int 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}
427EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set);
428
429int 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}
450EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get);
451
452int 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}
470EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set);
471
472int 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}
490EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get);
491
492
493int 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}
499EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set_rev1);
500
501int 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}
517EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get_rev1);
518
519int 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}
537EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_rev1);
538
539int 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}
563EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_rev1);
564
565
566
567
568
569
570static 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
596out:
597 return err;
598}
599
600static 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
621out:
622 return err;
623}
624
625static 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
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
660out:
661 return err;
662}
663
664static 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
690out:
691 return err;
692}
693
694static 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
706out:
707 return err;
708}
709
710static 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
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
741out:
742 return err;
743}
744
745int 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
761out:
762 return err;
763}
764EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo);
765
766int 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
782out:
783 return err;
784}
785EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_combo);
786
787
788int 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
796
797
798
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}
815EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set);
816
817int 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
834
835
836 *val = (((val2 << 1) + val1) / tb->scal + 1) * tb->step;
837
838 return 0;
839}
840EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get);
841
842
843int 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}
862EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_rev1);
863
864int 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}
880EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_rev1);
881
882int 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}
887EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_raw);
888
889int 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}
894EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_raw);
895
896int 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
903
904
905
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
921
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}
937EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_set);
938
939int 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
949
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
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}
980EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_get);
981
982int 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}
1007EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set);
1008
1009int 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}
1031EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get);
1032
1033int 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}
1038EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set_raw);
1039
1040int 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}
1045EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get_raw);
1046
1047MODULE_LICENSE("GPL v2");
1048MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
1049MODULE_DESCRIPTION("Pin configuration library module for mediatek SoCs");
1050