1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2018 MediaTek Inc.
5 * Author: Sean Wang <sean.wang@mediatek.com>
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>
15 #include <linux/module.h>
16 #include <linux/of_irq.h>
19 #include "pinctrl-mtk-common-v2.h"
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
29 * formula: output = ((input) / step - 1) * scal
31 struct mtk_drive_desc
{
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 },
47 static void mtk_w32(struct mtk_pinctrl
*pctl
, u8 i
, u32 reg
, u32 val
)
49 writel_relaxed(val
, pctl
->base
[i
] + reg
);
52 static u32
mtk_r32(struct mtk_pinctrl
*pctl
, u8 i
, u32 reg
)
54 return readl_relaxed(pctl
->base
[i
] + reg
);
57 void mtk_rmw(struct mtk_pinctrl
*pctl
, u8 i
, u32 reg
, u32 mask
, u32 set
)
62 spin_lock_irqsave(&pctl
->lock
, flags
);
64 val
= mtk_r32(pctl
, i
, reg
);
67 mtk_w32(pctl
, i
, reg
, val
);
69 spin_unlock_irqrestore(&pctl
->lock
, flags
);
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
)
76 const struct mtk_pin_field_calc
*c
;
77 const struct mtk_pin_reg_calc
*rc
;
78 int start
= 0, end
, check
;
82 if (hw
->soc
->reg_cal
&& hw
->soc
->reg_cal
[field
].range
) {
83 rc
= &hw
->soc
->reg_cal
[field
];
86 "Not support field %d for this soc\n", field
);
90 end
= rc
->nranges
- 1;
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
) {
98 } else if (start
== end
)
100 else if (desc
->number
< rc
->range
[check
].s_pin
)
107 dev_dbg(hw
->dev
, "Not support field %d for pin = %d (%s)\n",
108 field
, desc
->number
, desc
->name
);
112 c
= rc
->range
+ check
;
114 if (c
->i_base
> hw
->nbase
- 1) {
116 "Invalid base for field %d for pin = %d (%s)\n",
117 field
, desc
->number
, desc
->name
);
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.
125 bits
= c
->fixed
? c
->s_bit
: c
->s_bit
+
126 (desc
->number
- c
->s_pin
) * (c
->x_bits
);
128 /* Fill pfd from bits. For example 32-bit register applied is assumed
129 * when c->sz_reg is equal to 32.
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;
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.
140 pfd
->next
= pfd
->bitpos
+ c
->x_bits
> c
->sz_reg
? c
->x_addrs
: 0;
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
)
149 if (field
< 0 || field
>= PINCTRL_PIN_REG_MAX
) {
150 dev_err(hw
->dev
, "Invalid Field %d\n", field
);
154 return mtk_hw_pin_field_lookup(hw
, desc
, field
, pfd
);
157 static void mtk_hw_bits_part(struct mtk_pin_field
*pf
, int *h
, int *l
)
159 *l
= 32 - pf
->bitpos
;
160 *h
= get_count_order(pf
->mask
) - *l
;
163 static void mtk_hw_write_cross_field(struct mtk_pinctrl
*hw
,
164 struct mtk_pin_field
*pf
, int value
)
166 int nbits_l
, nbits_h
;
168 mtk_hw_bits_part(pf
, &nbits_h
, &nbits_l
);
170 mtk_rmw(hw
, pf
->index
, pf
->offset
, pf
->mask
<< pf
->bitpos
,
171 (value
& pf
->mask
) << pf
->bitpos
);
173 mtk_rmw(hw
, pf
->index
, pf
->offset
+ pf
->next
, BIT(nbits_h
) - 1,
174 (value
& pf
->mask
) >> nbits_l
);
177 static void mtk_hw_read_cross_field(struct mtk_pinctrl
*hw
,
178 struct mtk_pin_field
*pf
, int *value
)
180 int nbits_l
, nbits_h
, h
, l
;
182 mtk_hw_bits_part(pf
, &nbits_h
, &nbits_l
);
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);
189 *value
= (h
<< nbits_l
) | l
;
192 int mtk_hw_set_value(struct mtk_pinctrl
*hw
, const struct mtk_pin_desc
*desc
,
193 int field
, int value
)
195 struct mtk_pin_field pf
;
198 err
= mtk_hw_pin_field_get(hw
, desc
, field
, &pf
);
202 if (value
< 0 || value
> pf
.mask
)
206 mtk_rmw(hw
, pf
.index
, pf
.offset
, pf
.mask
<< pf
.bitpos
,
207 (value
& pf
.mask
) << pf
.bitpos
);
209 mtk_hw_write_cross_field(hw
, &pf
, value
);
213 EXPORT_SYMBOL_GPL(mtk_hw_set_value
);
215 int mtk_hw_get_value(struct mtk_pinctrl
*hw
, const struct mtk_pin_desc
*desc
,
216 int field
, int *value
)
218 struct mtk_pin_field pf
;
221 err
= mtk_hw_pin_field_get(hw
, desc
, field
, &pf
);
226 *value
= (mtk_r32(hw
, pf
.index
, pf
.offset
)
227 >> pf
.bitpos
) & pf
.mask
;
229 mtk_hw_read_cross_field(hw
, &pf
, value
);
233 EXPORT_SYMBOL_GPL(mtk_hw_get_value
);
235 static int mtk_xt_find_eint_num(struct mtk_pinctrl
*hw
, unsigned long eint_n
)
237 const struct mtk_pin_desc
*desc
;
240 desc
= (const struct mtk_pin_desc
*)hw
->soc
->pins
;
242 while (i
< hw
->soc
->npins
) {
243 if (desc
[i
].eint
.eint_n
== eint_n
)
244 return desc
[i
].number
;
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.
260 bool mtk_is_virt_gpio(struct mtk_pinctrl
*hw
, unsigned int gpio_n
)
262 const struct mtk_pin_desc
*desc
;
263 bool virt_gpio
= false;
265 desc
= (const struct mtk_pin_desc
*)&hw
->soc
->pins
[gpio_n
];
267 /* if the GPIO is not supported for eint mode */
268 if (desc
->eint
.eint_m
== NO_EINT_SUPPORT
)
271 if (desc
->funcs
&& !desc
->funcs
[desc
->eint
.eint_m
].name
)
276 EXPORT_SYMBOL_GPL(mtk_is_virt_gpio
);
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
)
282 struct mtk_pinctrl
*hw
= (struct mtk_pinctrl
*)data
;
283 const struct mtk_pin_desc
*desc
;
285 desc
= (const struct mtk_pin_desc
*)hw
->soc
->pins
;
286 *gpio_chip
= &hw
->chip
;
289 * Be greedy to guess first gpio_n is equal to eint_n.
290 * Only eint virtual eint number is greater than gpio number.
292 if (hw
->soc
->npins
> eint_n
&&
293 desc
[eint_n
].eint
.eint_n
== eint_n
)
296 *gpio_n
= mtk_xt_find_eint_num(hw
, eint_n
);
298 return *gpio_n
== EINT_NA
? -EINVAL
: 0;
301 static int mtk_xt_get_gpio_state(void *data
, unsigned long eint_n
)
303 struct mtk_pinctrl
*hw
= (struct mtk_pinctrl
*)data
;
304 const struct mtk_pin_desc
*desc
;
305 struct gpio_chip
*gpio_chip
;
309 err
= mtk_xt_get_gpio_n(hw
, eint_n
, &gpio_n
, &gpio_chip
);
313 desc
= (const struct mtk_pin_desc
*)&hw
->soc
->pins
[gpio_n
];
315 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_DI
, &value
);
322 static int mtk_xt_set_gpio_as_eint(void *data
, unsigned long eint_n
)
324 struct mtk_pinctrl
*hw
= (struct mtk_pinctrl
*)data
;
325 const struct mtk_pin_desc
*desc
;
326 struct gpio_chip
*gpio_chip
;
330 err
= mtk_xt_get_gpio_n(hw
, eint_n
, &gpio_n
, &gpio_chip
);
334 if (mtk_is_virt_gpio(hw
, gpio_n
))
337 desc
= (const struct mtk_pin_desc
*)&hw
->soc
->pins
[gpio_n
];
339 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_MODE
,
344 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_DIR
, MTK_INPUT
);
348 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_SMT
, MTK_ENABLE
);
349 /* SMT is supposed to be supported by every real GPIO and doesn't
350 * support virtual GPIOs, so the extra condition err != -ENOTSUPP
351 * is just for adding EINT support to these virtual GPIOs. It should
352 * add an extra flag in the pin descriptor when more pins with
353 * distinctive characteristic come out.
355 if (err
&& err
!= -ENOTSUPP
)
361 static const struct mtk_eint_xt mtk_eint_xt
= {
362 .get_gpio_n
= mtk_xt_get_gpio_n
,
363 .get_gpio_state
= mtk_xt_get_gpio_state
,
364 .set_gpio_as_eint
= mtk_xt_set_gpio_as_eint
,
367 int mtk_build_eint(struct mtk_pinctrl
*hw
, struct platform_device
*pdev
)
369 struct device_node
*np
= pdev
->dev
.of_node
;
372 if (!IS_ENABLED(CONFIG_EINT_MTK
))
375 if (!of_property_read_bool(np
, "interrupt-controller"))
378 hw
->eint
= devm_kzalloc(hw
->dev
, sizeof(*hw
->eint
), GFP_KERNEL
);
382 hw
->eint
->base
= devm_platform_ioremap_resource_byname(pdev
, "eint");
383 if (IS_ERR(hw
->eint
->base
)) {
384 ret
= PTR_ERR(hw
->eint
->base
);
388 hw
->eint
->irq
= irq_of_parse_and_map(np
, 0);
389 if (!hw
->eint
->irq
) {
394 if (!hw
->soc
->eint_hw
) {
399 hw
->eint
->dev
= &pdev
->dev
;
400 hw
->eint
->hw
= hw
->soc
->eint_hw
;
402 hw
->eint
->gpio_xlate
= &mtk_eint_xt
;
404 return mtk_eint_do_init(hw
->eint
);
407 devm_kfree(hw
->dev
, hw
->eint
);
411 EXPORT_SYMBOL_GPL(mtk_build_eint
);
414 int mtk_pinconf_bias_disable_set(struct mtk_pinctrl
*hw
,
415 const struct mtk_pin_desc
*desc
)
419 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_PU
,
424 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_PD
,
431 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set
);
433 int mtk_pinconf_bias_disable_get(struct mtk_pinctrl
*hw
,
434 const struct mtk_pin_desc
*desc
, int *res
)
439 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_PU
, &v
);
443 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_PD
, &v2
);
447 if (v
== MTK_ENABLE
|| v2
== MTK_ENABLE
)
454 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get
);
456 int mtk_pinconf_bias_set(struct mtk_pinctrl
*hw
,
457 const struct mtk_pin_desc
*desc
, bool pullup
)
461 arg
= pullup
? 1 : 2;
463 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_PU
, arg
& 1);
467 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_PD
,
474 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set
);
476 int mtk_pinconf_bias_get(struct mtk_pinctrl
*hw
,
477 const struct mtk_pin_desc
*desc
, bool pullup
, int *res
)
481 reg
= pullup
? PINCTRL_PIN_REG_PU
: PINCTRL_PIN_REG_PD
;
483 err
= mtk_hw_get_value(hw
, desc
, reg
, &v
);
494 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get
);
497 int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl
*hw
,
498 const struct mtk_pin_desc
*desc
)
500 return mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_PULLEN
,
503 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set_rev1
);
505 int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl
*hw
,
506 const struct mtk_pin_desc
*desc
, int *res
)
510 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_PULLEN
, &v
);
521 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get_rev1
);
523 int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl
*hw
,
524 const struct mtk_pin_desc
*desc
, bool pullup
)
528 arg
= pullup
? MTK_PULLUP
: MTK_PULLDOWN
;
530 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_PULLEN
,
535 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_PULLSEL
, arg
);
541 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_rev1
);
543 int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl
*hw
,
544 const struct mtk_pin_desc
*desc
, bool pullup
,
549 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_PULLEN
, &v
);
553 if (v
== MTK_DISABLE
)
556 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_PULLSEL
, &v
);
560 if (pullup
^ (v
== MTK_PULLUP
))
567 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_rev1
);
569 /* Combo for the following pull register type:
571 * 2. PULLSEL + PULLEN
574 static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl
*hw
,
575 const struct mtk_pin_desc
*desc
,
580 if (arg
== MTK_DISABLE
) {
583 } else if ((arg
== MTK_ENABLE
) && pullup
) {
586 } else if ((arg
== MTK_ENABLE
) && !pullup
) {
594 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_PU
, pu
);
598 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_PD
, pd
);
604 static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl
*hw
,
605 const struct mtk_pin_desc
*desc
,
610 if (arg
== MTK_DISABLE
)
612 else if (arg
== MTK_ENABLE
)
619 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_PULLEN
, enable
);
623 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_PULLSEL
, pullup
);
629 static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl
*hw
,
630 const struct mtk_pin_desc
*desc
,
635 if ((arg
== MTK_DISABLE
) || (arg
== MTK_PUPD_SET_R1R0_00
)) {
639 } else if (arg
== MTK_PUPD_SET_R1R0_01
) {
642 } else if (arg
== MTK_PUPD_SET_R1R0_10
) {
645 } else if (arg
== MTK_PUPD_SET_R1R0_11
) {
653 /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
654 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_PUPD
, !pullup
);
658 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_R0
, r0
);
662 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_R1
, r1
);
668 static int mtk_hw_pin_rsel_lookup(struct mtk_pinctrl
*hw
,
669 const struct mtk_pin_desc
*desc
,
670 u32 pullup
, u32 arg
, u32
*rsel_val
)
672 const struct mtk_pin_rsel
*rsel
;
676 rsel
= hw
->soc
->pin_rsel
;
678 for (check
= 0; check
<= hw
->soc
->npin_rsel
- 1; check
++) {
679 if (desc
->number
>= rsel
[check
].s_pin
&&
680 desc
->number
<= rsel
[check
].e_pin
) {
682 if (rsel
[check
].up_rsel
== arg
) {
684 *rsel_val
= rsel
[check
].rsel_index
;
688 if (rsel
[check
].down_rsel
== arg
) {
690 *rsel_val
= rsel
[check
].rsel_index
;
698 dev_err(hw
->dev
, "Not support rsel value %d Ohm for pin = %d (%s)\n",
699 arg
, desc
->number
, desc
->name
);
706 static int mtk_pinconf_bias_set_rsel(struct mtk_pinctrl
*hw
,
707 const struct mtk_pin_desc
*desc
,
712 if (hw
->rsel_si_unit
) {
713 /* find pin rsel_index from pin_rsel array*/
714 err
= mtk_hw_pin_rsel_lookup(hw
, desc
, pullup
, arg
, &rsel_val
);
718 if (arg
< MTK_PULL_SET_RSEL_000
|| arg
> MTK_PULL_SET_RSEL_111
)
721 rsel_val
= arg
- MTK_PULL_SET_RSEL_000
;
724 return mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_RSEL
, rsel_val
);
727 static int mtk_pinconf_bias_set_pu_pd_rsel(struct mtk_pinctrl
*hw
,
728 const struct mtk_pin_desc
*desc
,
731 u32 enable
= arg
== MTK_DISABLE
? MTK_DISABLE
: MTK_ENABLE
;
734 if (arg
!= MTK_DISABLE
) {
735 err
= mtk_pinconf_bias_set_rsel(hw
, desc
, pullup
, arg
);
740 return mtk_pinconf_bias_set_pu_pd(hw
, desc
, pullup
, enable
);
743 int mtk_pinconf_bias_set_combo(struct mtk_pinctrl
*hw
,
744 const struct mtk_pin_desc
*desc
,
750 if (hw
->soc
->pull_type
)
751 try_all_type
= hw
->soc
->pull_type
[desc
->number
];
753 try_all_type
= MTK_PULL_TYPE_MASK
;
755 if (try_all_type
& MTK_PULL_RSEL_TYPE
) {
756 err
= mtk_pinconf_bias_set_pu_pd_rsel(hw
, desc
, pullup
, arg
);
761 if (try_all_type
& MTK_PULL_PU_PD_TYPE
) {
762 err
= mtk_pinconf_bias_set_pu_pd(hw
, desc
, pullup
, arg
);
767 if (try_all_type
& MTK_PULL_PULLSEL_TYPE
) {
768 err
= mtk_pinconf_bias_set_pullsel_pullen(hw
, desc
,
774 if (try_all_type
& MTK_PULL_PUPD_R1R0_TYPE
)
775 err
= mtk_pinconf_bias_set_pupd_r1_r0(hw
, desc
, pullup
, arg
);
778 dev_err(hw
->dev
, "Invalid pull argument\n");
782 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo
);
784 static int mtk_rsel_get_si_unit(struct mtk_pinctrl
*hw
,
785 const struct mtk_pin_desc
*desc
,
786 u32 pullup
, u32 rsel_val
, u32
*si_unit
)
788 const struct mtk_pin_rsel
*rsel
;
791 rsel
= hw
->soc
->pin_rsel
;
793 for (check
= 0; check
<= hw
->soc
->npin_rsel
- 1; check
++) {
794 if (desc
->number
>= rsel
[check
].s_pin
&&
795 desc
->number
<= rsel
[check
].e_pin
) {
796 if (rsel_val
== rsel
[check
].rsel_index
) {
798 *si_unit
= rsel
[check
].up_rsel
;
800 *si_unit
= rsel
[check
].down_rsel
;
809 static int mtk_pinconf_bias_get_pu_pd_rsel(struct mtk_pinctrl
*hw
,
810 const struct mtk_pin_desc
*desc
,
811 u32
*pullup
, u32
*enable
)
813 int pu
, pd
, rsel
, err
;
815 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_RSEL
, &rsel
);
819 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_PU
, &pu
);
823 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_PD
, &pd
);
827 if (pu
== 0 && pd
== 0) {
829 *enable
= MTK_DISABLE
;
830 } else if (pu
== 1 && pd
== 0) {
832 if (hw
->rsel_si_unit
)
833 mtk_rsel_get_si_unit(hw
, desc
, *pullup
, rsel
, enable
);
835 *enable
= rsel
+ MTK_PULL_SET_RSEL_000
;
836 } else if (pu
== 0 && pd
== 1) {
838 if (hw
->rsel_si_unit
)
839 mtk_rsel_get_si_unit(hw
, desc
, *pullup
, rsel
, enable
);
841 *enable
= rsel
+ MTK_PULL_SET_RSEL_000
;
851 static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl
*hw
,
852 const struct mtk_pin_desc
*desc
,
853 u32
*pullup
, u32
*enable
)
857 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_PU
, &pu
);
861 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_PD
, &pd
);
865 if (pu
== 0 && pd
== 0) {
867 *enable
= MTK_DISABLE
;
868 } else if (pu
== 1 && pd
== 0) {
870 *enable
= MTK_ENABLE
;
871 } else if (pu
== 0 && pd
== 1) {
873 *enable
= MTK_ENABLE
;
881 static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl
*hw
,
882 const struct mtk_pin_desc
*desc
,
883 u32
*pullup
, u32
*enable
)
887 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_PULLSEL
, pullup
);
891 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_PULLEN
, enable
);
897 static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl
*hw
,
898 const struct mtk_pin_desc
*desc
,
899 u32
*pullup
, u32
*enable
)
903 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_PUPD
, pullup
);
906 /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
907 *pullup
= !(*pullup
);
909 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_R0
, &r0
);
913 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_R1
, &r1
);
917 if ((r1
== 0) && (r0
== 0))
918 *enable
= MTK_PUPD_SET_R1R0_00
;
919 else if ((r1
== 0) && (r0
== 1))
920 *enable
= MTK_PUPD_SET_R1R0_01
;
921 else if ((r1
== 1) && (r0
== 0))
922 *enable
= MTK_PUPD_SET_R1R0_10
;
923 else if ((r1
== 1) && (r0
== 1))
924 *enable
= MTK_PUPD_SET_R1R0_11
;
932 int mtk_pinconf_bias_get_combo(struct mtk_pinctrl
*hw
,
933 const struct mtk_pin_desc
*desc
,
934 u32
*pullup
, u32
*enable
)
939 if (hw
->soc
->pull_type
)
940 try_all_type
= hw
->soc
->pull_type
[desc
->number
];
942 try_all_type
= MTK_PULL_TYPE_MASK
;
944 if (try_all_type
& MTK_PULL_RSEL_TYPE
) {
945 err
= mtk_pinconf_bias_get_pu_pd_rsel(hw
, desc
, pullup
, enable
);
950 if (try_all_type
& MTK_PULL_PU_PD_TYPE
) {
951 err
= mtk_pinconf_bias_get_pu_pd(hw
, desc
, pullup
, enable
);
956 if (try_all_type
& MTK_PULL_PULLSEL_TYPE
) {
957 err
= mtk_pinconf_bias_get_pullsel_pullen(hw
, desc
,
963 if (try_all_type
& MTK_PULL_PUPD_R1R0_TYPE
)
964 err
= mtk_pinconf_bias_get_pupd_r1_r0(hw
, desc
, pullup
, enable
);
968 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_combo
);
971 int mtk_pinconf_drive_set(struct mtk_pinctrl
*hw
,
972 const struct mtk_pin_desc
*desc
, u32 arg
)
974 const struct mtk_drive_desc
*tb
;
977 tb
= &mtk_drive
[desc
->drv_n
];
978 /* 4mA when (e8, e4) = (0, 0)
979 * 8mA when (e8, e4) = (0, 1)
980 * 12mA when (e8, e4) = (1, 0)
981 * 16mA when (e8, e4) = (1, 1)
983 if ((arg
>= tb
->min
&& arg
<= tb
->max
) && !(arg
% tb
->step
)) {
984 arg
= (arg
/ tb
->step
- 1) * tb
->scal
;
985 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_E4
,
990 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_E8
,
998 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set
);
1000 int mtk_pinconf_drive_get(struct mtk_pinctrl
*hw
,
1001 const struct mtk_pin_desc
*desc
, int *val
)
1003 const struct mtk_drive_desc
*tb
;
1004 int err
, val1
, val2
;
1006 tb
= &mtk_drive
[desc
->drv_n
];
1008 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_E4
, &val1
);
1012 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_E8
, &val2
);
1016 /* 4mA when (e8, e4) = (0, 0); 8mA when (e8, e4) = (0, 1)
1017 * 12mA when (e8, e4) = (1, 0); 16mA when (e8, e4) = (1, 1)
1019 *val
= (((val2
<< 1) + val1
) / tb
->scal
+ 1) * tb
->step
;
1023 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get
);
1026 int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl
*hw
,
1027 const struct mtk_pin_desc
*desc
, u32 arg
)
1029 const struct mtk_drive_desc
*tb
;
1030 int err
= -ENOTSUPP
;
1032 tb
= &mtk_drive
[desc
->drv_n
];
1034 if ((arg
>= tb
->min
&& arg
<= tb
->max
) && !(arg
% tb
->step
)) {
1035 arg
= (arg
/ tb
->step
- 1) * tb
->scal
;
1037 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_DRV
,
1045 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_rev1
);
1047 int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl
*hw
,
1048 const struct mtk_pin_desc
*desc
, int *val
)
1050 const struct mtk_drive_desc
*tb
;
1053 tb
= &mtk_drive
[desc
->drv_n
];
1055 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_DRV
, &val1
);
1059 *val
= ((val1
& 0x7) / tb
->scal
+ 1) * tb
->step
;
1063 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_rev1
);
1065 int mtk_pinconf_drive_set_raw(struct mtk_pinctrl
*hw
,
1066 const struct mtk_pin_desc
*desc
, u32 arg
)
1068 return mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_DRV
, arg
);
1070 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_raw
);
1072 int mtk_pinconf_drive_get_raw(struct mtk_pinctrl
*hw
,
1073 const struct mtk_pin_desc
*desc
, int *val
)
1075 return mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_DRV
, val
);
1077 EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_raw
);
1079 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl
*hw
,
1080 const struct mtk_pin_desc
*desc
, bool pullup
,
1085 /* 10K off & 50K (75K) off, when (R0, R1) = (0, 0);
1086 * 10K off & 50K (75K) on, when (R0, R1) = (0, 1);
1087 * 10K on & 50K (75K) off, when (R0, R1) = (1, 0);
1088 * 10K on & 50K (75K) on, when (R0, R1) = (1, 1)
1090 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_R0
, arg
& 1);
1094 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_R1
,
1099 arg
= pullup
? 0 : 1;
1101 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_PUPD
, arg
);
1103 /* If PUPD register is not supported for that pin, let's fallback to
1104 * general bias control.
1106 if (err
== -ENOTSUPP
) {
1107 if (hw
->soc
->bias_set
) {
1108 err
= hw
->soc
->bias_set(hw
, desc
, pullup
);
1112 err
= mtk_pinconf_bias_set_rev1(hw
, desc
, pullup
);
1114 err
= mtk_pinconf_bias_set(hw
, desc
, pullup
);
1120 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_set
);
1122 int mtk_pinconf_adv_pull_get(struct mtk_pinctrl
*hw
,
1123 const struct mtk_pin_desc
*desc
, bool pullup
,
1129 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_PUPD
, &t
);
1131 /* If PUPD register is not supported for that pin, let's fallback to
1132 * general bias control.
1134 if (err
== -ENOTSUPP
) {
1135 if (hw
->soc
->bias_get
) {
1136 err
= hw
->soc
->bias_get(hw
, desc
, pullup
, val
);
1143 /* t == 0 supposes PULLUP for the customized PULL setup */
1151 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_R0
, &t
);
1155 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_R1
, &t2
);
1159 *val
= (t
| t2
<< 1) & 0x7;
1163 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_get
);
1165 int mtk_pinconf_adv_drive_set(struct mtk_pinctrl
*hw
,
1166 const struct mtk_pin_desc
*desc
, u32 arg
)
1170 int e0
= !!(arg
& 2);
1171 int e1
= !!(arg
& 4);
1173 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_DRV_EN
, en
);
1180 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_DRV_E0
, e0
);
1184 err
= mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_DRV_E1
, e1
);
1190 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set
);
1192 int mtk_pinconf_adv_drive_get(struct mtk_pinctrl
*hw
,
1193 const struct mtk_pin_desc
*desc
, u32
*val
)
1198 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_DRV_EN
, &en
);
1202 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_DRV_E0
, &e0
);
1206 err
= mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_DRV_E1
, &e1
);
1210 *val
= (en
| e0
<< 1 | e1
<< 2) & 0x7;
1214 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get
);
1216 int mtk_pinconf_adv_drive_set_raw(struct mtk_pinctrl
*hw
,
1217 const struct mtk_pin_desc
*desc
, u32 arg
)
1219 return mtk_hw_set_value(hw
, desc
, PINCTRL_PIN_REG_DRV_ADV
, arg
);
1221 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set_raw
);
1223 int mtk_pinconf_adv_drive_get_raw(struct mtk_pinctrl
*hw
,
1224 const struct mtk_pin_desc
*desc
, u32
*val
)
1226 return mtk_hw_get_value(hw
, desc
, PINCTRL_PIN_REG_DRV_ADV
, val
);
1228 EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get_raw
);
1230 MODULE_LICENSE("GPL v2");
1231 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
1232 MODULE_DESCRIPTION("Pin configuration library module for mediatek SoCs");