Re: [PATCH v1 1/2] pinctrl: mediatek: support access registers without race-condition

2020-08-21 Thread Light Hsieh
On Fri, 2020-08-21 at 02:59 -0700, Sean Wang wrote:
> Hi Light,
> 
> On Thu, Aug 20, 2020 at 9:47 PM Light Hsieh  wrote:
> >
> > On Wed, 2020-08-19 at 16:11 -0700, Sean Wang wrote:
> > > Hi Light,
> > >
> > > On Tue, Aug 18, 2020 at 1:36 AM  wrote:
> > > >
> > > > From: Light Hsieh 
> > > >
> > > > Some MediaTek SOC provide more control registers other than value 
> > > > register.
> > >
> > > s/MT6765/Some MediaTek SoC/
> > >
> > > > Generanll, a value register need read-modify-write is at offset 
> > > > 0x0.
> > >
> > > s/Generally/Generanll/
> > >
> > > > A corresponding SET register is at offset 0xXXX4. Write 1s' to some 
> > > > bits
> > > >   of SET register will set same bits in value register.
> > > > A corresponding CLR register is at offset 0xXXX8. Write 1s' to some 
> > > > bits
> > > >   of CLR register will clear same bits in value register.
> > > > For GPIO mode selection, MWR register is provided at offset 0xXXXC.
> > > >   With MWR, the MSBit of GPIO mode selection field is for 
> > > > modification-enable,
> > > >   not for GPIO mode selection, and the remaining LSBits are for mode
> > > >   selection.
> > > >   Take mode selection field with 4-bits as example, to select mode 0~7 
> > > > via
> > > >   MWR register, 8~15 (instead of 0~7) shall be written to corresponding 
> > > > mode
> > > >   selection field.
> > > > When using SET/CLR/MWR registers, read-modify-write of value register 
> > > > is not
> > > >   necessary. This can prevent from race condition when multiple bus 
> > > > masters
> > > >   concurrently read-modify-write the same value register for setting 
> > > > different
> > > >   fields of the same value register.
> > > >
> > > > Signed-off-by: Light Hsieh 
> > > > ---
> > > >  drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 69 
> > > > ++--
> > > >  drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  2 +
> > > >  2 files changed, 67 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
> > > > b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> > > > index b77b18f..51f0b53 100644
> > > > --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> > > > +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> > > > @@ -18,6 +18,29 @@
> > > >  #include "mtk-eint.h"
> > > >  #include "pinctrl-mtk-common-v2.h"
> > > >
> > > > +/* Some MediaTek SOC provide more control registers other than value 
> > > > register.
> > >
> > > s/MT6765/Some MediaTek SoC/
> >
> > Not only MT6765 provides such control registers.
> > Actually, many (but not all) MediaTek SoC support.
> > Other MediaTek SoC can enable such control according to its HW support.
> >
> > >
> > > > + * Generanll, a value register need read-modify-write is at offset 
> > > > 0x0.
> > >
> > > s/Generally/Generanll/
> > >
> > > > + * A corresponding SET register is at offset 0xXXX4. Write 1s' to 
> > > > some bits
> > > > + *  of SET register will set same bits in value register.
> > > > + * A corresponding CLR register is at offset 0xXXX8. Write 1s' to 
> > > > some bits
> > > > + *  of CLR register will clear same bits in value register.
> > > > + * For GPIO mode selection, MWR register is provided at offset 
> > > > 0xXXXC.
> > > > + *  With MWR, the MSBit of GPIO mode selection field is for 
> > > > modification-enable,
> > > > + *  not for GPIO mode selection, and the remaining LSBits are for mode
> > > > + *  selection.
> > > > + *  Take mode selection field with 4-bits as example, to select mode 
> > > > 0~7 via
> > > > + *  MWR register, 8~15 (instead of 0~7) shall be written to 
> > > > corresponding mode
> > > > + *  selection field.
> > > > + * When using SET/CLR/MWR registers, read-modify-write of value 
> > > > register is not
> > > > + *  necessary. This can prevent from race condition when multiple bus 
> > > > 

Re: [PATCH v1 1/2] pinctrl: mediatek: support access registers without race-condition

2020-08-20 Thread Light Hsieh
On Wed, 2020-08-19 at 16:11 -0700, Sean Wang wrote:
> Hi Light,
> 
> On Tue, Aug 18, 2020 at 1:36 AM  wrote:
> >
> > From: Light Hsieh 
> >
> > Some MediaTek SOC provide more control registers other than value register.
> 
> s/MT6765/Some MediaTek SoC/
> 
> > Generanll, a value register need read-modify-write is at offset 0x0.
> 
> s/Generally/Generanll/
> 
> > A corresponding SET register is at offset 0xXXX4. Write 1s' to some bits
> >   of SET register will set same bits in value register.
> > A corresponding CLR register is at offset 0xXXX8. Write 1s' to some bits
> >   of CLR register will clear same bits in value register.
> > For GPIO mode selection, MWR register is provided at offset 0xXXXC.
> >   With MWR, the MSBit of GPIO mode selection field is for 
> > modification-enable,
> >   not for GPIO mode selection, and the remaining LSBits are for mode
> >   selection.
> >   Take mode selection field with 4-bits as example, to select mode 0~7 via
> >   MWR register, 8~15 (instead of 0~7) shall be written to corresponding mode
> >   selection field.
> > When using SET/CLR/MWR registers, read-modify-write of value register is not
> >   necessary. This can prevent from race condition when multiple bus masters
> >   concurrently read-modify-write the same value register for setting 
> > different
> >   fields of the same value register.
> >
> > Signed-off-by: Light Hsieh 
> > ---
> >  drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 69 
> > ++--
> >  drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  2 +
> >  2 files changed, 67 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
> > b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> > index b77b18f..51f0b53 100644
> > --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> > +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> > @@ -18,6 +18,29 @@
> >  #include "mtk-eint.h"
> >  #include "pinctrl-mtk-common-v2.h"
> >
> > +/* Some MediaTek SOC provide more control registers other than value 
> > register.
> 
> s/MT6765/Some MediaTek SoC/

Not only MT6765 provides such control registers.
Actually, many (but not all) MediaTek SoC support.
Other MediaTek SoC can enable such control according to its HW support.

> 
> > + * Generanll, a value register need read-modify-write is at offset 
> > 0x0.
> 
> s/Generally/Generanll/
> 
> > + * A corresponding SET register is at offset 0xXXX4. Write 1s' to some 
> > bits
> > + *  of SET register will set same bits in value register.
> > + * A corresponding CLR register is at offset 0xXXX8. Write 1s' to some 
> > bits
> > + *  of CLR register will clear same bits in value register.
> > + * For GPIO mode selection, MWR register is provided at offset 0xXXXC.
> > + *  With MWR, the MSBit of GPIO mode selection field is for 
> > modification-enable,
> > + *  not for GPIO mode selection, and the remaining LSBits are for mode
> > + *  selection.
> > + *  Take mode selection field with 4-bits as example, to select mode 0~7 
> > via
> > + *  MWR register, 8~15 (instead of 0~7) shall be written to corresponding 
> > mode
> > + *  selection field.
> > + * When using SET/CLR/MWR registers, read-modify-write of value register 
> > is not
> > + *  necessary. This can prevent from race condition when multiple bus 
> > masters
> > + *  concurrently read-modify-write the same value register for setting 
> > different
> > + *  fields of the same value register.
> > + */
> > +
> > +#define SET_OFFSET 0x4
> > +#define CLR_OFFSET 0x8
> 
> can set/clr offset work for mode register?

Yes. However, use set/clr to change mode require 2 register access when
target mode is not all 0's or all 1's.
The mwr HW support is not available on mode register.

> 
> > +#define MWR_OFFSET 0xC
> > +
> >  /**
> >   * struct mtk_drive_desc - the structure that holds the information
> >   * of the driving current
> > @@ -64,6 +87,38 @@ void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, 
> > u32 mask, u32 set)
> > mtk_w32(pctl, i, reg, val);
> >  }
> >
> > +
> > +static void mtk_hw_set_value_race_free(struct mtk_pinctrl *pctl,
> > +   struct mtk_pin_field *pf, u32 value)
> 
> s/mtk_hw_set_value_race_free/mtk_hw_w1sc/ to explictly indicate
> write-one ethier set or clear opera

Re: [PATCH] pinctrl: mediatek: fix mtk_eint link error

2020-04-29 Thread Light Hsieh
On Wed, 2020-04-29 at 15:24 +0200, Arnd Bergmann wrote:
> In a configuration with CONFIG_PINCTRL_MTK_MOORE=y and 
> CONFIG_PINCTRL_MTK_PARIS=m,
> we end up with the mtk_eint driver as a loadable module that cannot be
> linked from built-in code:

How did you set all MTK-related PINCTRL configs?
and what is the generated result of .config?



> aarch64-linux-ld: drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.o: in 
> function `mtk_build_eint':
> (.text+0x304): undefined reference to `mtk_eint_do_init'
> aarch64-linux-ld: drivers/pinctrl/mediatek/pinctrl-moore.o: in function 
> `mtk_gpio_set_config':
> pinctrl-moore.c:(.text+0xf80): undefined reference to `mtk_eint_set_debounce'
> aarch64-linux-ld: drivers/pinctrl/mediatek/pinctrl-moore.o: in function 
> `mtk_gpio_to_irq':
> pinctrl-moore.c:(.text+0x1028): undefined reference to `mtk_eint_find_irq'
> 
> Simplify the Kconfig logic to always select EINT_MTK when it is needed, and
> remove the 'default' statements.
> 
> Fixes: 8174a8512e3e ("pinctrl: mediatek: make MediaTek pinctrl v2 driver 
> ready for buidling loadable module")
> Signed-off-by: Arnd Bergmann 
> ---
>  drivers/pinctrl/mediatek/Kconfig|  4 +---
>  drivers/pinctrl/mediatek/mtk-eint.h | 28 
>  2 files changed, 1 insertion(+), 31 deletions(-)
> 
> diff --git a/drivers/pinctrl/mediatek/Kconfig 
> b/drivers/pinctrl/mediatek/Kconfig
> index f32d3644c509..b6a8d91f4885 100644
> --- a/drivers/pinctrl/mediatek/Kconfig
> +++ b/drivers/pinctrl/mediatek/Kconfig
> @@ -7,8 +7,6 @@ config EINT_MTK
>   depends on PINCTRL_MTK || PINCTRL_MTK_MOORE || PINCTRL_MTK_PARIS || 
> COMPILE_TEST
>   select GPIOLIB
>   select IRQ_DOMAIN
> - default y if PINCTRL_MTK || PINCTRL_MTK_MOORE
> - default PINCTRL_MTK_PARIS
>  
>  config PINCTRL_MTK
>   bool
> @@ -20,6 +18,7 @@ config PINCTRL_MTK
>   select OF_GPIO
>  
>  config PINCTRL_MTK_V2
> + select EINT_MTK
>   tristate
>  
>  config PINCTRL_MTK_MOORE
> @@ -38,7 +37,6 @@ config PINCTRL_MTK_PARIS
>   select PINMUX
>   select GENERIC_PINCONF
>   select GPIOLIB
> - select EINT_MTK
>   select OF_GPIO
>   select PINCTRL_MTK_V2

With this modification,PINCTRK_MTK_MOORE always select EINT_MTK
(indirectly via select PINCTRL_MTK_V2).
However, in previous review, Sean Wang said that PINCTRL_MTK_MOORE does
not always use EINT_MTK so PINCTRL_MTK_MOORE shall not select EINT_MTK
un-conditionally.


>  
> diff --git a/drivers/pinctrl/mediatek/mtk-eint.h 
> b/drivers/pinctrl/mediatek/mtk-eint.h
> index 48468d0fae68..f40dab50a5f3 100644
> --- a/drivers/pinctrl/mediatek/mtk-eint.h
> +++ b/drivers/pinctrl/mediatek/mtk-eint.h
> @@ -68,7 +68,6 @@ struct mtk_eint {
>   const struct mtk_eint_xt *gpio_xlate;
>  };
>  
> -#if IS_ENABLED(CONFIG_EINT_MTK)
>  int mtk_eint_do_init(struct mtk_eint *eint);
>  int mtk_eint_do_suspend(struct mtk_eint *eint);
>  int mtk_eint_do_resume(struct mtk_eint *eint);
> @@ -76,31 +75,4 @@ int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned 
> long eint_n,
> unsigned int debounce);
>  int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n);
>  
> -#else
> -static inline int mtk_eint_do_init(struct mtk_eint *eint)
> -{
> - return -EOPNOTSUPP;
> -}
> -
> -static inline int mtk_eint_do_suspend(struct mtk_eint *eint)
> -{
> - return -EOPNOTSUPP;
> -}
> -
> -static inline int mtk_eint_do_resume(struct mtk_eint *eint)
> -{
> - return -EOPNOTSUPP;
> -}
> -
> -static inline int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long 
> eint_n,
> -   unsigned int debounce)
> -{
> - return -EOPNOTSUPP;
> -}
> -
> -static inline int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long 
> eint_n)
> -{
> - return -EOPNOTSUPP;
> -}
> -#endif
>  #endif /* __MTK_EINT_H */



Re: [PATCH v6 1/5] pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()

2019-09-26 Thread Light Hsieh
Dear reviewers:

Patch v6 improves v5 by:

1.in mtk_pinconf_get() and mtk_pinconf_set() @pinctrl-paris.c:
  * check if pin is in range before using pin as array index of 
 hw->soc->pins[]
2.in mtk_pin_field_lookup() @pinctrl-mtk-common-v2.c:
  * declear start, end, check as signed integer instead of unsigned
integer. Otherwise, kernel fault will occur when s_pin field of
first entry of a mtk_pin_field_calc[] array is not 0.

On Fri, 2019-09-27 at 13:02 +0800, Light Hsieh wrote:
> 1. Check if gpio pin number is in valid range to prevent from get invalid
>pointer 'desc' in the following code:
>   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
> 
> 2. Use binary search in mtk_hw_pin_field_lookup()
>Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
>search.
> 
> ---
>  drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 25 
> +++-
>  drivers/pinctrl/mediatek/pinctrl-paris.c | 25 
> 
>  2 files changed, 45 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
> b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> index 20e1c89..8077855 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> @@ -68,7 +68,8 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
>  {
>   const struct mtk_pin_field_calc *c, *e;
>   const struct mtk_pin_reg_calc *rc;
> - u32 bits;
> + u32 bits, found = 0;
> + int start = 0, end, check;
>  
>   if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
>   rc = &hw->soc->reg_cal[field];
> @@ -79,21 +80,32 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
>   return -ENOTSUPP;
>   }
>  
> + end = rc->nranges - 1;
>   c = rc->range;
>   e = c + rc->nranges;
>  
> - while (c < e) {
> - if (desc->number >= c->s_pin && desc->number <= c->e_pin)
> + while (start <= end) {
> + check = (start + end) >> 1;
> + if (desc->number >= rc->range[check].s_pin
> +  && desc->number <= rc->range[check].e_pin) {
> + found = 1;
>   break;
> - c++;
> + } else if (start == end)
> + break;
> + else if (desc->number < rc->range[check].s_pin)
> + end = check - 1;
> + else
> + start = check + 1;
>   }
>  
> - if (c >= e) {
> + if (!found) {
>   dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
>   field, desc->number, desc->name);
>   return -ENOTSUPP;
>   }
>  
> + c = rc->range + check;
> +
>   if (c->i_base > hw->nbase - 1) {
>   dev_err(hw->dev,
>   "Invalid base for field %d for pin = %d (%s)\n",
> @@ -182,6 +194,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
> mtk_pin_desc *desc,
>   if (err)
>   return err;
>  
> + if (value < 0 || value > pf.mask)
> + return -EINVAL;
> +
>   if (!pf.next)
>   mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
>   (value & pf.mask) << pf.bitpos);
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
> b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 923264d..3e13ae7 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -81,6 +81,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
>   int val, val2, err, reg, ret = 1;
>   const struct mtk_pin_desc *desc;
>  
> + if (pin >= hw->soc->npins)
> + return -EINVAL;
>   desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
>  
>   switch (param) {
> @@ -206,6 +208,10 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, 
> unsigned int pin,
>   int err = 0;
>   u32 reg;
>  
> + if (pin >= hw->soc->npins) {
> + err = -EINVAL;
> + goto err;
> + }
>   desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
>  
>   switch ((u32)param) {
> @@ -693,6 +699,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, 
> unsigned int gpio)
>   const struct mtk_pin_desc *desc;
>   int value, err;
>  
> +   

[PATCH v6 3/5] pinctrl: mediatek: Refine mtk_pinconf_get() and mtk_pinconf_set()

2019-09-26 Thread Light Hsieh
1.Refine mtk_pinconf_get():
1.1 Use only one occurrence of return at end of this function.
1.2 Correct cases for PIN_CONFIG_SLEW_RATE, PIN_CONFIG_INPUT_SCHMITT_ENABLE,
and PIN_CONFIG_OUTPUT_ENABLE -
Use variable ret to receive value in mtk_hw_get_value() (instead of
variable val) since pinconf_to_config_packed() at end of this function
use variable ret to pack config value.

2.Refine mtk_pinconf_set():
2.1 Use only one occurrence of return at end of this function.
2.2 Modify case of PIN_CONFIG_INPUT_ENABLE -
Remove check of ies_present flag and always invoke mtk_hw_set_value()
since mtk_hw_pin_field_lookup() invoked inside mtk_hw_set_value() has
the same effect of checking if ies control is supported.
[The rationale is that: available of a control is always checked
 in mtk_hw_pin_field_lookup() and no need to add ies_present flag
 specially for ies control.]
2.3 Simply code logic for case of PIN_CONFIG_INPUT_SCHMITT.
2.4 Add case for PIN_CONFIG_INPUT_SCHMITT_ENABLE and process it with the
same code for case of PIN_CONFIG_INPUT_SCHMITT.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c |   1 -
 drivers/pinctrl/mediatek/pinctrl-paris.c  | 211 +++---
 2 files changed, 79 insertions(+), 133 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index e024ebc..bada37f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1070,7 +1070,6 @@
.ngrps = ARRAY_SIZE(mtk_pins_mt6765),
.eint_hw = &mt6765_eint_hw,
.gpio_m = 0,
-   .ies_present = true,
.base_names = mt6765_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 5217f76..54f069b 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -78,95 +78,79 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 {
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
u32 param = pinconf_to_config_param(*config);
-   int val, val2, err, reg, ret = 1;
+   int err, reg, ret = 1;
const struct mtk_pin_desc *desc;
 
-   if (pin >= hw->soc->npins)
-   return -EINVAL;
+   if (pin >= hw->soc->npins) {
+   err = -EINVAL;
+   goto out;
+   }
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
 
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
-   if (hw->soc->bias_disable_get) {
+   if (hw->soc->bias_disable_get)
err = hw->soc->bias_disable_get(hw, desc, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_UP:
-   if (hw->soc->bias_get) {
+   if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 1, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
-   if (hw->soc->bias_get) {
+   if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 0, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_SLEW_RATE:
-   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
-   if (err)
-   return err;
-
-   if (!val)
-   return -EINVAL;
-
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
break;
case PIN_CONFIG_INPUT_ENABLE:
case PIN_CONFIG_OUTPUT_ENABLE:
-   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
if (err)
-   return err;
-
-   /* HW takes input mode as zero; output mode as non-zero */
-   if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
-   (!val && param == PIN_CONFIG_OUTPUT_ENABLE))
-   return -EINVAL;
+   goto out;
+   /* CONFIG Current direction return value
+* -  --

[PATCH v6 5/5] pinctrl: mediatek: Add support for pin configuration dump via debugfs.

2019-09-26 Thread Light Hsieh
Add support for pin configuration dump via catting
/sys/kernel/debug/pinctrl/$platform_dependent_path/pinconf-pins.
pinctrl framework had already support such dump. This patch implement the
operation function pointer to fullfill this dump.

---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 88 
 drivers/pinctrl/mediatek/pinctrl-paris.h | 30 +++
 2 files changed, 118 insertions(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 2a47c45..f531908 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -538,12 +538,99 @@ static int mtk_pctrl_get_group_pins(struct pinctrl_dev 
*pctldev,
return 0;
 }
 
+int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int field)
+{
+   const struct mtk_pin_desc *desc;
+   int value, err;
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
+   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+
+   err = mtk_hw_get_value(hw, desc, field, &value);
+   if (err)
+   return err;
+
+   return value;
+}
+
+ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
+   unsigned int gpio, char *buf, unsigned int bufLen)
+{
+   const struct mtk_pin_desc *desc;
+   int pinmux, pullup, pullen, r1 = -1, r0 = -1, len = 0;
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
+   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+   pinmux = mtk_pctrl_get_pinmux(hw, gpio);
+   if (pinmux >= hw->soc->nfuncs)
+   pinmux -= hw->soc->nfuncs;
+
+   mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
+   if (pullen == MTK_PUPD_SET_R1R0_00) {
+   pullen = 0;
+   r1 = 0;
+   r0 = 0;
+   } else if (pullen == MTK_PUPD_SET_R1R0_01) {
+   pullen = 1;
+   r1 = 0;
+   r0 = 1;
+   } else if (pullen == MTK_PUPD_SET_R1R0_10) {
+   pullen = 1;
+   r1 = 1;
+   r0 = 0;
+   } else if (pullen == MTK_PUPD_SET_R1R0_11) {
+   pullen = 1;
+   r1 = 1;
+   r0 = 1;
+   } else if (pullen != MTK_DISABLE && pullen != MTK_ENABLE) {
+   pullen = 0;
+   }
+   len += snprintf(buf + len, bufLen - len,
+   "%03d: %1d%1d%1d%1d%02d%1d%1d%1d%1d",
+   gpio,
+   pinmux,
+   mtk_pctrl_get_direction(hw, gpio),
+   mtk_pctrl_get_out(hw, gpio),
+   mtk_pctrl_get_in(hw, gpio),
+   mtk_pctrl_get_driving(hw, gpio),
+   mtk_pctrl_get_smt(hw, gpio),
+   mtk_pctrl_get_ies(hw, gpio),
+   pullen,
+   pullup);
+
+   if (r1 != -1) {
+   len += snprintf(buf + len, bufLen - len, " (%1d %1d)\n",
+   r1, r0);
+   } else {
+   len += snprintf(buf + len, bufLen - len, "\n");
+   }
+
+   return len;
+}
+
+#define PIN_DBG_BUF_SZ 96
+static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+ unsigned int gpio)
+{
+   struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+   char buf[PIN_DBG_BUF_SZ];
+
+   (void)mtk_pctrl_show_one_pin(hw, gpio, buf, PIN_DBG_BUF_SZ);
+
+   seq_printf(s, "%s", buf);
+}
+
 static const struct pinctrl_ops mtk_pctlops = {
.dt_node_to_map = mtk_pctrl_dt_node_to_map,
.dt_free_map= pinctrl_utils_free_map,
.get_groups_count   = mtk_pctrl_get_groups_count,
.get_group_name = mtk_pctrl_get_group_name,
.get_group_pins = mtk_pctrl_get_group_pins,
+   .pin_dbg_show   = mtk_pctrl_dbg_show,
 };
 
 static int mtk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
@@ -640,6 +727,7 @@ static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, 
unsigned group,
.pin_config_get = mtk_pinconf_get,
.pin_config_group_get   = mtk_pconf_group_get,
.pin_config_group_set   = mtk_pconf_group_set,
+   .is_generic = true,
 };
 
 static struct pinctrl_desc mtk_desc = {
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.h 
b/drivers/pinctrl/mediatek/pinctrl-paris.h
index 3d43771..d73f4b6 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.h
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.h
@@ -60,6 +60,36 @@
 int mtk_paris_pinctrl_probe(struct platform_device *pdev,
const struct mtk_pin_soc *soc);
 
+int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int 
field);
+
+#define mtk_pctrl_get_pinmux(hw, gpio) \
+   mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_MODE)
+
+/* MTK HW use 0 as input, 1 for output
+ * This interface is for get direct register value,
+ * so don't

[PATCH v6 4/5] pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull usage

2019-09-26 Thread Light Hsieh
Refine mtk_pinconf_set()/mtk_pinconf_get() for backward compatibility to
previous Mediatek's bias-pull usage.
In PINCTRL_MTK that use pinctrl-mtk-common.c, bias-pull setting for pins
with 2 pull resistors can be specified as value for bias-pull-up and
bias-pull-down. For example:
bias-pull-up = ;
bias-pull-up = ;
bias-pull-up = ;
bias-pull-up = ;
bias-pull-down = ;
bias-pull-down = ;
bias-pull-down = ;
bias-pull-down = ;

On the other hand, PINCTRL_MTK_PARIS use customized properties
"mediatek,pull-up-adv" and "mediatek,pull-down-adv" to specify bias-pull
setting for pins with 2 pull resistors.
This introduce in-compatibility in device tree and increatse porting
effort to Mediatek's customer that had already used PINCTRL_MTK version.
Besides, if customers are not awared of this change and still write devicetree
for PINCTRL_MTK version, they may encounter runtime failure with pinctrl and
spent time to debug.

This patch add backward compatible to previous Mediatek's bias-pull usage
so that Mediatek's customer need not use a new devicetree property name.
The rationale is that: changing driver implemenation had better leave
interface unchanged.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c|   6 +-
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 285 +++
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  11 +
 drivers/pinctrl/mediatek/pinctrl-paris.c |  49 ++--
 4 files changed, 327 insertions(+), 24 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index bada37f..ae85fdc 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1072,10 +1072,8 @@
.gpio_m = 0,
.base_names = mt6765_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
-   .bias_disable_set = mtk_pinconf_bias_disable_set,
-   .bias_disable_get = mtk_pinconf_bias_disable_get,
-   .bias_set = mtk_pinconf_bias_set,
-   .bias_get = mtk_pinconf_bias_get,
+   .bias_set_combo = mtk_pinconf_bias_set_combo,
+   .bias_get_combo = mtk_pinconf_bias_get_combo,
.drive_set = mtk_pinconf_drive_set_direct_val,
.drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index acfddf9..6d9972f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -13,6 +13,8 @@
 #include 
 #include 
 
+#include 
+
 #include "mtk-eint.h"
 #include "pinctrl-mtk-common-v2.h"
 
@@ -206,6 +208,20 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
return 0;
 }
 
+void mtk_hw_set_value_no_lookup(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   int value, struct mtk_pin_field *pf)
+{
+   if (value < 0 || value > pf->mask)
+   return;
+
+   if (!pf->next)
+   mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos,
+   (value & pf->mask) << pf->bitpos);
+   else
+   mtk_hw_write_cross_field(hw, pf, value);
+}
+
 int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 int field, int *value)
 {
@@ -225,6 +241,17 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
return 0;
 }
 
+void mtk_hw_get_value_no_lookup(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   int *value, struct mtk_pin_field *pf)
+{
+   if (!pf->next)
+   *value = (mtk_r32(hw, pf->index, pf->offset)
+ >> pf->bitpos) & pf->mask;
+   else
+   mtk_hw_read_cross_field(hw, pf, value);
+}
+
 static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
 {
const struct mtk_pin_desc *desc;
@@ -517,6 +544,264 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
return 0;
 }
 
+/* Combo for the following pull register type:
+ * 1. PU + PD
+ * 2. PULLSEL + PULLEN
+ * 3. PUPD + R0 + R1
+ */
+int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   u32 pullup, u32 arg)
+{
+   struct mtk_pin_field pf;
+   int err = -EINVAL;
+   int pu, pd;
+
+   err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PU, &pf);
+   if (err)
+   goto out;
+
+   if (arg == MTK_DISABLE) {
+   pu = 0;
+   pd = 0;
+   } else if ((arg == MTK_ENABLE) && pullup) {
+   pu = 1;
+   pd = 0;
+   } else if ((arg == MTK_ENABLE) && !pullup) {
+   pu = 0;
+  

[PATCH v6 2/5] pinctrl: mediatek: Supporting driving setting without mapping current to register value

2019-09-26 Thread Light Hsieh
Mediatek's smarphone project actual usage does need to know current value
(in mA) in procedure of finding the best driving setting.
The steps in the procedure is like as follow:

1. set driving setting field in setting register as 0, measure waveform,
   perform test, and etc.
2. set driving setting field in setting register as 1, measure waveform,
   perform test, and etc.
...
n. set driving setting field in setting register as n-1, measure
   waveform, perform test, and etc.
Check the results of steps 1~n and adopt the setting that get best result.

This procedure does need to know the mapping between current to register
value.
Therefore, setting driving without mapping current is more pratical for
Mediatek's smartphone usage.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c|  4 ++--
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 21 +
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  5 +
 drivers/pinctrl/mediatek/pinctrl-paris.c |  1 +
 4 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index 32451e8..e024ebc 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1077,8 +1077,8 @@
.bias_disable_get = mtk_pinconf_bias_disable_get,
.bias_set = mtk_pinconf_bias_set,
.bias_get = mtk_pinconf_bias_get,
-   .drive_set = mtk_pinconf_drive_set_rev1,
-   .drive_get = mtk_pinconf_drive_get_rev1,
+   .drive_set = mtk_pinconf_drive_set_direct_val,
+   .drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
.adv_pull_set = mtk_pinconf_adv_pull_set,
 };
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 8077855..acfddf9 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -608,6 +608,27 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
return 0;
 }
 
+/* Revision direct value */
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, u32 arg)
+{
+   int err;
+
+   err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
+
+   return err;
+}
+
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, int *val)
+{
+   int err;
+
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
+
+   return err;
+}
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 const struct mtk_pin_desc *desc, bool pullup,
 u32 arg)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 1b7da42..b3bada0 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -288,6 +288,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
 int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
   const struct mtk_pin_desc *desc, int *val);
 
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, u32 arg);
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, int *val);
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 const struct mtk_pin_desc *desc, bool pullup,
 u32 arg);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 3e13ae7..5217f76 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -970,3 +970,4 @@ static int mtk_paris_pinctrl_resume(struct device *device)
.suspend_noirq = mtk_paris_pinctrl_suspend,
.resume_noirq = mtk_paris_pinctrl_resume,
 };
+
-- 
1.8.1.1.dirty



[PATCH v6 1/5] pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()

2019-09-26 Thread Light Hsieh
1. Check if gpio pin number is in valid range to prevent from get invalid
   pointer 'desc' in the following code:
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];

2. Use binary search in mtk_hw_pin_field_lookup()
   Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
   search.

---
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 25 +++-
 drivers/pinctrl/mediatek/pinctrl-paris.c | 25 
 2 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 20e1c89..8077855 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -68,7 +68,8 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
 {
const struct mtk_pin_field_calc *c, *e;
const struct mtk_pin_reg_calc *rc;
-   u32 bits;
+   u32 bits, found = 0;
+   int start = 0, end, check;
 
if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
rc = &hw->soc->reg_cal[field];
@@ -79,21 +80,32 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
return -ENOTSUPP;
}
 
+   end = rc->nranges - 1;
c = rc->range;
e = c + rc->nranges;
 
-   while (c < e) {
-   if (desc->number >= c->s_pin && desc->number <= c->e_pin)
+   while (start <= end) {
+   check = (start + end) >> 1;
+   if (desc->number >= rc->range[check].s_pin
+&& desc->number <= rc->range[check].e_pin) {
+   found = 1;
break;
-   c++;
+   } else if (start == end)
+   break;
+   else if (desc->number < rc->range[check].s_pin)
+   end = check - 1;
+   else
+   start = check + 1;
}
 
-   if (c >= e) {
+   if (!found) {
dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
field, desc->number, desc->name);
return -ENOTSUPP;
}
 
+   c = rc->range + check;
+
if (c->i_base > hw->nbase - 1) {
dev_err(hw->dev,
"Invalid base for field %d for pin = %d (%s)\n",
@@ -182,6 +194,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
if (err)
return err;
 
+   if (value < 0 || value > pf.mask)
+   return -EINVAL;
+
if (!pf.next)
mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
(value & pf.mask) << pf.bitpos);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 923264d..3e13ae7 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -81,6 +81,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
int val, val2, err, reg, ret = 1;
const struct mtk_pin_desc *desc;
 
+   if (pin >= hw->soc->npins)
+   return -EINVAL;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
 
switch (param) {
@@ -206,6 +208,10 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, 
unsigned int pin,
int err = 0;
u32 reg;
 
+   if (pin >= hw->soc->npins) {
+   err = -EINVAL;
+   goto err;
+   }
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
 
switch ((u32)param) {
@@ -693,6 +699,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, 
unsigned int gpio)
const struct mtk_pin_desc *desc;
int value, err;
 
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
@@ -708,6 +717,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned 
int gpio)
const struct mtk_pin_desc *desc;
int value, err;
 
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
@@ -722,6 +734,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
int gpio, int value)
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
 
+   if (gpio > hw->soc->npins)
+   return;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
@@ -729,12 +744,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
int gpio, int value)
 
 static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
 {
+   struct mtk_pinctrl *h

Re: [PATCH v5 1/5] pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()

2019-09-17 Thread Light Hsieh
Dear reviewer,

Due to my operation error, one file (pinctrl-paris.h) is missed in patch
seriers 5/5 of v4.
v5 is sent to correct this error.

On Wed, 2019-09-18 at 10:39 +0800, Light Hsieh wrote:
> 1. Check if gpio pin number is in valid range to prevent from get invalid
>pointer 'desc' in the following code:
>   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
> 
> 2. Use binary search in mtk_hw_pin_field_lookup()
>Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
>search.
> 
> ---
>  drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 24 
> +++-
>  drivers/pinctrl/mediatek/pinctrl-paris.c | 19 +++
>  2 files changed, 38 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
> b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> index 20e1c89..4687f63 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> @@ -68,7 +68,7 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
>  {
>   const struct mtk_pin_field_calc *c, *e;
>   const struct mtk_pin_reg_calc *rc;
> - u32 bits;
> + u32 bits, start = 0, end, found = 0, check;
>  
>   if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
>   rc = &hw->soc->reg_cal[field];
> @@ -79,21 +79,32 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
>   return -ENOTSUPP;
>   }
>  
> + end = rc->nranges - 1;
>   c = rc->range;
>   e = c + rc->nranges;
>  
> - while (c < e) {
> - if (desc->number >= c->s_pin && desc->number <= c->e_pin)
> + while (start <= end) {
> + check = (start + end) >> 1;
> + if (desc->number >= rc->range[check].s_pin
> +  && desc->number <= rc->range[check].e_pin) {
> + found = 1;
>   break;
> - c++;
> + } else if (start == end)
> + break;
> + else if (desc->number < rc->range[check].s_pin)
> + end = check - 1;
> + else
> + start = check + 1;
>   }
>  
> - if (c >= e) {
> + if (!found) {
>   dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
>   field, desc->number, desc->name);
>   return -ENOTSUPP;
>   }
>  
> + c = rc->range + check;
> +
>   if (c->i_base > hw->nbase - 1) {
>   dev_err(hw->dev,
>   "Invalid base for field %d for pin = %d (%s)\n",
> @@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
> mtk_pin_desc *desc,
>   if (err)
>   return err;
>  
> + if (value < 0 || value > pf.mask)
> + return -EINVAL;
> +
>   if (!pf.next)
>   mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
>   (value & pf.mask) << pf.bitpos);
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
> b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 923264d..28b4951 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -693,6 +693,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, 
> unsigned int gpio)
>   const struct mtk_pin_desc *desc;
>   int value, err;
>  
> + if (gpio > hw->soc->npins)
> + return -EINVAL;
> +
>   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
>  
>   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
> @@ -708,6 +711,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned 
> int gpio)
>   const struct mtk_pin_desc *desc;
>   int value, err;
>  
> + if (gpio > hw->soc->npins)
> + return -EINVAL;
> +
>   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
>  
>   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
> @@ -722,6 +728,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
> int gpio, int value)
>   struct mtk_pinctrl *hw = gpiochip_get_data(chip);
>   const struct mtk_pin_desc *desc;
>  
> + if (gpio > hw->soc->npins)
> + return;
> +
>   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
>  
>   mtk_hw_set_value(hw, des

[PATCH v5 5/5] pinctrl: mediatek: Add support for pin configuration dump via debugfs.

2019-09-17 Thread Light Hsieh
Add support for pin configuration dump via catting
/sys/kernel/debug/pinctrl/$platform_dependent_path/pinconf-pins.
pinctrl framework had already support such dump. This patch implement the
operation function pointer to fullfill this dump.

---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 88 
 drivers/pinctrl/mediatek/pinctrl-paris.h | 30 +++
 2 files changed, 118 insertions(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index e847867..6acbdc3 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -530,12 +530,99 @@ static int mtk_pctrl_get_group_pins(struct pinctrl_dev 
*pctldev,
return 0;
 }
 
+int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int field)
+{
+   const struct mtk_pin_desc *desc;
+   int value, err;
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
+   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+
+   err = mtk_hw_get_value(hw, desc, field, &value);
+   if (err)
+   return err;
+
+   return value;
+}
+
+ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
+   unsigned int gpio, char *buf, unsigned int bufLen)
+{
+   const struct mtk_pin_desc *desc;
+   int pinmux, pullup, pullen, r1 = -1, r0 = -1, len = 0;
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
+   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+   pinmux = mtk_pctrl_get_pinmux(hw, gpio);
+   if (pinmux >= hw->soc->nfuncs)
+   pinmux -= hw->soc->nfuncs;
+
+   mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
+   if (pullen == MTK_PUPD_SET_R1R0_00) {
+   pullen = 0;
+   r1 = 0;
+   r0 = 0;
+   } else if (pullen == MTK_PUPD_SET_R1R0_01) {
+   pullen = 1;
+   r1 = 0;
+   r0 = 1;
+   } else if (pullen == MTK_PUPD_SET_R1R0_10) {
+   pullen = 1;
+   r1 = 1;
+   r0 = 0;
+   } else if (pullen == MTK_PUPD_SET_R1R0_11) {
+   pullen = 1;
+   r1 = 1;
+   r0 = 1;
+   } else if (pullen != MTK_DISABLE && pullen != MTK_ENABLE) {
+   pullen = 0;
+   }
+   len += snprintf(buf + len, bufLen - len,
+   "%03d: %1d%1d%1d%1d%02d%1d%1d%1d%1d",
+   gpio,
+   pinmux,
+   mtk_pctrl_get_direction(hw, gpio),
+   mtk_pctrl_get_out(hw, gpio),
+   mtk_pctrl_get_in(hw, gpio),
+   mtk_pctrl_get_driving(hw, gpio),
+   mtk_pctrl_get_smt(hw, gpio),
+   mtk_pctrl_get_ies(hw, gpio),
+   pullen,
+   pullup);
+
+   if (r1 != -1) {
+   len += snprintf(buf + len, bufLen - len, " (%1d %1d)\n",
+   r1, r0);
+   } else {
+   len += snprintf(buf + len, bufLen - len, "\n");
+   }
+
+   return len;
+}
+
+#define PIN_DBG_BUF_SZ 96
+static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+ unsigned int gpio)
+{
+   struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+   char buf[PIN_DBG_BUF_SZ];
+
+   (void)mtk_pctrl_show_one_pin(hw, gpio, buf, PIN_DBG_BUF_SZ);
+
+   seq_printf(s, "%s", buf);
+}
+
 static const struct pinctrl_ops mtk_pctlops = {
.dt_node_to_map = mtk_pctrl_dt_node_to_map,
.dt_free_map= pinctrl_utils_free_map,
.get_groups_count   = mtk_pctrl_get_groups_count,
.get_group_name = mtk_pctrl_get_group_name,
.get_group_pins = mtk_pctrl_get_group_pins,
+   .pin_dbg_show   = mtk_pctrl_dbg_show,
 };
 
 static int mtk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
@@ -632,6 +719,7 @@ static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, 
unsigned group,
.pin_config_get = mtk_pinconf_get,
.pin_config_group_get   = mtk_pconf_group_get,
.pin_config_group_set   = mtk_pconf_group_set,
+   .is_generic = true,
 };
 
 static struct pinctrl_desc mtk_desc = {
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.h 
b/drivers/pinctrl/mediatek/pinctrl-paris.h
index 3d43771..d73f4b6 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.h
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.h
@@ -60,6 +60,36 @@
 int mtk_paris_pinctrl_probe(struct platform_device *pdev,
const struct mtk_pin_soc *soc);
 
+int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int 
field);
+
+#define mtk_pctrl_get_pinmux(hw, gpio) \
+   mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_MODE)
+
+/* MTK HW use 0 as input, 1 for output
+ * This interface is for get direct register value,
+ * so don't

[PATCH v5 1/5] pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()

2019-09-17 Thread Light Hsieh
1. Check if gpio pin number is in valid range to prevent from get invalid
   pointer 'desc' in the following code:
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];

2. Use binary search in mtk_hw_pin_field_lookup()
   Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
   search.

---
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 24 +++-
 drivers/pinctrl/mediatek/pinctrl-paris.c | 19 +++
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 20e1c89..4687f63 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -68,7 +68,7 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
 {
const struct mtk_pin_field_calc *c, *e;
const struct mtk_pin_reg_calc *rc;
-   u32 bits;
+   u32 bits, start = 0, end, found = 0, check;
 
if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
rc = &hw->soc->reg_cal[field];
@@ -79,21 +79,32 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
return -ENOTSUPP;
}
 
+   end = rc->nranges - 1;
c = rc->range;
e = c + rc->nranges;
 
-   while (c < e) {
-   if (desc->number >= c->s_pin && desc->number <= c->e_pin)
+   while (start <= end) {
+   check = (start + end) >> 1;
+   if (desc->number >= rc->range[check].s_pin
+&& desc->number <= rc->range[check].e_pin) {
+   found = 1;
break;
-   c++;
+   } else if (start == end)
+   break;
+   else if (desc->number < rc->range[check].s_pin)
+   end = check - 1;
+   else
+   start = check + 1;
}
 
-   if (c >= e) {
+   if (!found) {
dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
field, desc->number, desc->name);
return -ENOTSUPP;
}
 
+   c = rc->range + check;
+
if (c->i_base > hw->nbase - 1) {
dev_err(hw->dev,
"Invalid base for field %d for pin = %d (%s)\n",
@@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
if (err)
return err;
 
+   if (value < 0 || value > pf.mask)
+   return -EINVAL;
+
if (!pf.next)
mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
(value & pf.mask) << pf.bitpos);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 923264d..28b4951 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -693,6 +693,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, 
unsigned int gpio)
const struct mtk_pin_desc *desc;
int value, err;
 
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
@@ -708,6 +711,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned 
int gpio)
const struct mtk_pin_desc *desc;
int value, err;
 
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
@@ -722,6 +728,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
int gpio, int value)
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
 
+   if (gpio > hw->soc->npins)
+   return;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
@@ -729,12 +738,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
int gpio, int value)
 
 static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
 {
+   struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
return pinctrl_gpio_direction_input(chip->base + gpio);
 }
 
 static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
 int value)
 {
+   struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
mtk_gpio_set(chip, gpio, value);
 
return pinctrl_gpio_direction_output(chip->base + gpio);
-- 
1.8.1.1.dirty



[PATCH v5 3/5] pinctrl: mediatek: Refine mtk_pinconf_get() and mtk_pinconf_set()

2019-09-17 Thread Light Hsieh
1.Refine mtk_pinconf_get():
1.1 Use only one occurrence of return at end of this function.
1.2 Correct cases for PIN_CONFIG_SLEW_RATE, PIN_CONFIG_INPUT_SCHMITT_ENABLE,
and PIN_CONFIG_OUTPUT_ENABLE -
Use variable ret to receive value in mtk_hw_get_value() (instead of
variable val) since pinconf_to_config_packed() at end of this function
use variable ret to pack config value.

2.Refine mtk_pinconf_set():
2.1 Use only one occurrence of return at end of this function.
2.2 Modify case of PIN_CONFIG_INPUT_ENABLE -
Remove check of ies_present flag and always invoke mtk_hw_set_value()
since mtk_hw_pin_field_lookup() invoked inside mtk_hw_set_value() has
the same effect of checking if ies control is supported.
[The rationale is that: available of a control is always checked
 in mtk_hw_pin_field_lookup() and no need to add ies_present flag
 specially for ies control.]
2.3 Simply code logic for case of PIN_CONFIG_INPUT_SCHMITT.
2.4 Add case for PIN_CONFIG_INPUT_SCHMITT_ENABLE and process it with the
same code for case of PIN_CONFIG_INPUT_SCHMITT.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c |   1 -
 drivers/pinctrl/mediatek/pinctrl-paris.c  | 205 +++---
 2 files changed, 75 insertions(+), 131 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index e024ebc..bada37f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1070,7 +1070,6 @@
.ngrps = ARRAY_SIZE(mtk_pins_mt6765),
.eint_hw = &mt6765_eint_hw,
.gpio_m = 0,
-   .ies_present = true,
.base_names = mt6765_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 71c94b2..9433b72 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -78,93 +78,75 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 {
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
u32 param = pinconf_to_config_param(*config);
-   int val, val2, err, reg, ret = 1;
+   int err, reg, ret = 1;
const struct mtk_pin_desc *desc;
 
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
 
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
-   if (hw->soc->bias_disable_get) {
+   if (hw->soc->bias_disable_get)
err = hw->soc->bias_disable_get(hw, desc, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_UP:
-   if (hw->soc->bias_get) {
+   if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 1, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
-   if (hw->soc->bias_get) {
+   if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 0, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_SLEW_RATE:
-   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
-   if (err)
-   return err;
-
-   if (!val)
-   return -EINVAL;
-
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
break;
case PIN_CONFIG_INPUT_ENABLE:
case PIN_CONFIG_OUTPUT_ENABLE:
-   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
if (err)
-   return err;
-
-   /* HW takes input mode as zero; output mode as non-zero */
-   if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
-   (!val && param == PIN_CONFIG_OUTPUT_ENABLE))
-   return -EINVAL;
+   goto out;
+   /* CONFIG Current direction return value
+* -  - --
+* OUTPUT_ENABLE   output   1 (= HW value)
+* input0 (= HW value)
+ 

[PATCH v5 4/5] pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull usage

2019-09-17 Thread Light Hsieh
Refine mtk_pinconf_set()/mtk_pinconf_get() for backward compatibility to
previous Mediatek's bias-pull usage.
In PINCTRL_MTK that use pinctrl-mtk-common.c, bias-pull setting for pins
with 2 pull resistors can be specified as value for bias-pull-up and
bias-pull-down. For example:
bias-pull-up = ;
bias-pull-up = ;
bias-pull-up = ;
bias-pull-up = ;
bias-pull-down = ;
bias-pull-down = ;
bias-pull-down = ;
bias-pull-down = ;

On the other hand, PINCTRL_MTK_PARIS use customized properties
"mediatek,pull-up-adv" and "mediatek,pull-down-adv" to specify bias-pull
setting for pins with 2 pull resistors.
This introduce in-compatibility in device tree and increatse porting
effort to Mediatek's customer that had already used PINCTRL_MTK version.
Besides, if customers are not awared of this change and still write devicetree
for PINCTRL_MTK version, they may encounter runtime failure with pinctrl and
spent time to debug.

This patch add backward compatible to previous Mediatek's bias-pull usage
so that Mediatek's customer need not use a new devicetree property name.
The rationale is that: changing driver implemenation had better leave
interface unchanged.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c|   6 +-
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 285 +++
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  11 +
 drivers/pinctrl/mediatek/pinctrl-paris.c |  49 ++--
 4 files changed, 327 insertions(+), 24 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index bada37f..ae85fdc 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1072,10 +1072,8 @@
.gpio_m = 0,
.base_names = mt6765_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
-   .bias_disable_set = mtk_pinconf_bias_disable_set,
-   .bias_disable_get = mtk_pinconf_bias_disable_get,
-   .bias_set = mtk_pinconf_bias_set,
-   .bias_get = mtk_pinconf_bias_get,
+   .bias_set_combo = mtk_pinconf_bias_set_combo,
+   .bias_get_combo = mtk_pinconf_bias_get_combo,
.drive_set = mtk_pinconf_drive_set_direct_val,
.drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 23a9529..dab8418 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -13,6 +13,8 @@
 #include 
 #include 
 
+#include 
+
 #include "mtk-eint.h"
 #include "pinctrl-mtk-common-v2.h"
 
@@ -205,6 +207,20 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
return 0;
 }
 
+void mtk_hw_set_value_no_lookup(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   int value, struct mtk_pin_field *pf)
+{
+   if (value < 0 || value > pf->mask)
+   return;
+
+   if (!pf->next)
+   mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos,
+   (value & pf->mask) << pf->bitpos);
+   else
+   mtk_hw_write_cross_field(hw, pf, value);
+}
+
 int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 int field, int *value)
 {
@@ -224,6 +240,17 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
return 0;
 }
 
+void mtk_hw_get_value_no_lookup(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   int *value, struct mtk_pin_field *pf)
+{
+   if (!pf->next)
+   *value = (mtk_r32(hw, pf->index, pf->offset)
+ >> pf->bitpos) & pf->mask;
+   else
+   mtk_hw_read_cross_field(hw, pf, value);
+}
+
 static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
 {
const struct mtk_pin_desc *desc;
@@ -516,6 +543,264 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
return 0;
 }
 
+/* Combo for the following pull register type:
+ * 1. PU + PD
+ * 2. PULLSEL + PULLEN
+ * 3. PUPD + R0 + R1
+ */
+int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   u32 pullup, u32 arg)
+{
+   struct mtk_pin_field pf;
+   int err = -EINVAL;
+   int pu, pd;
+
+   err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PU, &pf);
+   if (err)
+   goto out;
+
+   if (arg == MTK_DISABLE) {
+   pu = 0;
+   pd = 0;
+   } else if ((arg == MTK_ENABLE) && pullup) {
+   pu = 1;
+   pd = 0;
+   } else if ((arg == MTK_ENABLE) && !pullup) {
+   pu = 0;
+  

[PATCH v5 2/5] pinctrl: mediatek: Supporting driving setting without mapping current to register value

2019-09-17 Thread Light Hsieh
Mediatek's smarphone project actual usage does need to know current value
(in mA) in procedure of finding the best driving setting.
The steps in the procedure is like as follow:

1. set driving setting field in setting register as 0, measure waveform,
   perform test, and etc.
2. set driving setting field in setting register as 1, measure waveform,
   perform test, and etc.
...
n. set driving setting field in setting register as n-1, measure
   waveform, perform test, and etc.
Check the results of steps 1~n and adopt the setting that get best result.

This procedure does need to know the mapping between current to register
value.
Therefore, setting driving without mapping current is more pratical for
Mediatek's smartphone usage.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c|  4 ++--
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 21 +
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  5 +
 drivers/pinctrl/mediatek/pinctrl-paris.c |  1 +
 4 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index 32451e8..e024ebc 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1077,8 +1077,8 @@
.bias_disable_get = mtk_pinconf_bias_disable_get,
.bias_set = mtk_pinconf_bias_set,
.bias_get = mtk_pinconf_bias_get,
-   .drive_set = mtk_pinconf_drive_set_rev1,
-   .drive_get = mtk_pinconf_drive_get_rev1,
+   .drive_set = mtk_pinconf_drive_set_direct_val,
+   .drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
.adv_pull_set = mtk_pinconf_adv_pull_set,
 };
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 4687f63..23a9529 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -607,6 +607,27 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
return 0;
 }
 
+/* Revision direct value */
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, u32 arg)
+{
+   int err;
+
+   err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
+
+   return err;
+}
+
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, int *val)
+{
+   int err;
+
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
+
+   return err;
+}
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 const struct mtk_pin_desc *desc, bool pullup,
 u32 arg)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 1b7da42..b3bada0 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -288,6 +288,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
 int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
   const struct mtk_pin_desc *desc, int *val);
 
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, u32 arg);
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, int *val);
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 const struct mtk_pin_desc *desc, bool pullup,
 u32 arg);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 28b4951..71c94b2 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -964,3 +964,4 @@ static int mtk_paris_pinctrl_resume(struct device *device)
.suspend_noirq = mtk_paris_pinctrl_suspend,
.resume_noirq = mtk_paris_pinctrl_resume,
 };
+
-- 
1.8.1.1.dirty



[PATCH v4 4/5] pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull usage

2019-09-17 Thread Light Hsieh
Refine mtk_pinconf_set()/mtk_pinconf_get() for backward compatibility to
previous Mediatek's bias-pull usage.
In PINCTRL_MTK that use pinctrl-mtk-common.c, bias-pull setting for pins
with 2 pull resistors can be specified as value for bias-pull-up and
bias-pull-down. For example:
bias-pull-up = ;
bias-pull-up = ;
bias-pull-up = ;
bias-pull-up = ;
bias-pull-down = ;
bias-pull-down = ;
bias-pull-down = ;
bias-pull-down = ;

On the other hand, PINCTRL_MTK_PARIS use customized properties
"mediatek,pull-up-adv" and "mediatek,pull-down-adv" to specify bias-pull
setting for pins with 2 pull resistors.
This introduce in-compatibility in device tree and increatse porting
effort to Mediatek's customer that had already used PINCTRL_MTK version.
Besides, if customers are not awared of this change and still write devicetree
for PINCTRL_MTK version, they may encounter runtime failure with pinctrl and
spent time to debug.

This patch add backward compatible to previous Mediatek's bias-pull usage
so that Mediatek's customer need not use a new devicetree property name.
The rationale is that: changing driver implemenation had better leave
interface unchanged.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c|   6 +-
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 285 +++
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  11 +
 drivers/pinctrl/mediatek/pinctrl-paris.c |  49 ++--
 4 files changed, 327 insertions(+), 24 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index bada37f..ae85fdc 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1072,10 +1072,8 @@
.gpio_m = 0,
.base_names = mt6765_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
-   .bias_disable_set = mtk_pinconf_bias_disable_set,
-   .bias_disable_get = mtk_pinconf_bias_disable_get,
-   .bias_set = mtk_pinconf_bias_set,
-   .bias_get = mtk_pinconf_bias_get,
+   .bias_set_combo = mtk_pinconf_bias_set_combo,
+   .bias_get_combo = mtk_pinconf_bias_get_combo,
.drive_set = mtk_pinconf_drive_set_direct_val,
.drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 23a9529..dab8418 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -13,6 +13,8 @@
 #include 
 #include 
 
+#include 
+
 #include "mtk-eint.h"
 #include "pinctrl-mtk-common-v2.h"
 
@@ -205,6 +207,20 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
return 0;
 }
 
+void mtk_hw_set_value_no_lookup(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   int value, struct mtk_pin_field *pf)
+{
+   if (value < 0 || value > pf->mask)
+   return;
+
+   if (!pf->next)
+   mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos,
+   (value & pf->mask) << pf->bitpos);
+   else
+   mtk_hw_write_cross_field(hw, pf, value);
+}
+
 int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 int field, int *value)
 {
@@ -224,6 +240,17 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
return 0;
 }
 
+void mtk_hw_get_value_no_lookup(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   int *value, struct mtk_pin_field *pf)
+{
+   if (!pf->next)
+   *value = (mtk_r32(hw, pf->index, pf->offset)
+ >> pf->bitpos) & pf->mask;
+   else
+   mtk_hw_read_cross_field(hw, pf, value);
+}
+
 static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
 {
const struct mtk_pin_desc *desc;
@@ -516,6 +543,264 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
return 0;
 }
 
+/* Combo for the following pull register type:
+ * 1. PU + PD
+ * 2. PULLSEL + PULLEN
+ * 3. PUPD + R0 + R1
+ */
+int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   u32 pullup, u32 arg)
+{
+   struct mtk_pin_field pf;
+   int err = -EINVAL;
+   int pu, pd;
+
+   err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PU, &pf);
+   if (err)
+   goto out;
+
+   if (arg == MTK_DISABLE) {
+   pu = 0;
+   pd = 0;
+   } else if ((arg == MTK_ENABLE) && pullup) {
+   pu = 1;
+   pd = 0;
+   } else if ((arg == MTK_ENABLE) && !pullup) {
+   pu = 0;
+  

[PATCH v4 2/5] pinctrl: mediatek: Supporting driving setting without mapping current to register value

2019-09-17 Thread Light Hsieh
Mediatek's smarphone project actual usage does need to know current value
(in mA) in procedure of finding the best driving setting.
The steps in the procedure is like as follow:

1. set driving setting field in setting register as 0, measure waveform,
   perform test, and etc.
2. set driving setting field in setting register as 1, measure waveform,
   perform test, and etc.
...
n. set driving setting field in setting register as n-1, measure
   waveform, perform test, and etc.
Check the results of steps 1~n and adopt the setting that get best result.

This procedure does need to know the mapping between current to register
value.
Therefore, setting driving without mapping current is more pratical for
Mediatek's smartphone usage.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c|  4 ++--
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 21 +
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  5 +
 drivers/pinctrl/mediatek/pinctrl-paris.c |  1 +
 4 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index 32451e8..e024ebc 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1077,8 +1077,8 @@
.bias_disable_get = mtk_pinconf_bias_disable_get,
.bias_set = mtk_pinconf_bias_set,
.bias_get = mtk_pinconf_bias_get,
-   .drive_set = mtk_pinconf_drive_set_rev1,
-   .drive_get = mtk_pinconf_drive_get_rev1,
+   .drive_set = mtk_pinconf_drive_set_direct_val,
+   .drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
.adv_pull_set = mtk_pinconf_adv_pull_set,
 };
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 4687f63..23a9529 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -607,6 +607,27 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
return 0;
 }
 
+/* Revision direct value */
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, u32 arg)
+{
+   int err;
+
+   err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
+
+   return err;
+}
+
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, int *val)
+{
+   int err;
+
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
+
+   return err;
+}
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 const struct mtk_pin_desc *desc, bool pullup,
 u32 arg)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 1b7da42..b3bada0 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -288,6 +288,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
 int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
   const struct mtk_pin_desc *desc, int *val);
 
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, u32 arg);
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, int *val);
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 const struct mtk_pin_desc *desc, bool pullup,
 u32 arg);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 28b4951..71c94b2 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -964,3 +964,4 @@ static int mtk_paris_pinctrl_resume(struct device *device)
.suspend_noirq = mtk_paris_pinctrl_suspend,
.resume_noirq = mtk_paris_pinctrl_resume,
 };
+
-- 
1.8.1.1.dirty



[PATCH v4 3/5] pinctrl: mediatek: Refine mtk_pinconf_get() and mtk_pinconf_set()

2019-09-17 Thread Light Hsieh
1.Refine mtk_pinconf_get():
1.1 Use only one occurrence of return at end of this function.
1.2 Correct cases for PIN_CONFIG_SLEW_RATE, PIN_CONFIG_INPUT_SCHMITT_ENABLE,
and PIN_CONFIG_OUTPUT_ENABLE -
Use variable ret to receive value in mtk_hw_get_value() (instead of
variable val) since pinconf_to_config_packed() at end of this function
use variable ret to pack config value.

2.Refine mtk_pinconf_set():
2.1 Use only one occurrence of return at end of this function.
2.2 Modify case of PIN_CONFIG_INPUT_ENABLE -
Remove check of ies_present flag and always invoke mtk_hw_set_value()
since mtk_hw_pin_field_lookup() invoked inside mtk_hw_set_value() has
the same effect of checking if ies control is supported.
[The rationale is that: available of a control is always checked
 in mtk_hw_pin_field_lookup() and no need to add ies_present flag
 specially for ies control.]
2.3 Simply code logic for case of PIN_CONFIG_INPUT_SCHMITT.
2.4 Add case for PIN_CONFIG_INPUT_SCHMITT_ENABLE and process it with the
same code for case of PIN_CONFIG_INPUT_SCHMITT.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c |   1 -
 drivers/pinctrl/mediatek/pinctrl-paris.c  | 205 +++---
 2 files changed, 75 insertions(+), 131 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index e024ebc..bada37f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1070,7 +1070,6 @@
.ngrps = ARRAY_SIZE(mtk_pins_mt6765),
.eint_hw = &mt6765_eint_hw,
.gpio_m = 0,
-   .ies_present = true,
.base_names = mt6765_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 71c94b2..9433b72 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -78,93 +78,75 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 {
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
u32 param = pinconf_to_config_param(*config);
-   int val, val2, err, reg, ret = 1;
+   int err, reg, ret = 1;
const struct mtk_pin_desc *desc;
 
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
 
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
-   if (hw->soc->bias_disable_get) {
+   if (hw->soc->bias_disable_get)
err = hw->soc->bias_disable_get(hw, desc, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_UP:
-   if (hw->soc->bias_get) {
+   if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 1, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
-   if (hw->soc->bias_get) {
+   if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 0, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_SLEW_RATE:
-   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
-   if (err)
-   return err;
-
-   if (!val)
-   return -EINVAL;
-
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
break;
case PIN_CONFIG_INPUT_ENABLE:
case PIN_CONFIG_OUTPUT_ENABLE:
-   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
if (err)
-   return err;
-
-   /* HW takes input mode as zero; output mode as non-zero */
-   if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
-   (!val && param == PIN_CONFIG_OUTPUT_ENABLE))
-   return -EINVAL;
+   goto out;
+   /* CONFIG Current direction return value
+* -  - --
+* OUTPUT_ENABLE   output   1 (= HW value)
+* input0 (= HW value)
+ 

[PATCH v4 1/5] pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()

2019-09-17 Thread Light Hsieh
1. Check if gpio pin number is in valid range to prevent from get invalid
   pointer 'desc' in the following code:
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];

2. Use binary search in mtk_hw_pin_field_lookup()
   Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
   search.

---
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 24 +++-
 drivers/pinctrl/mediatek/pinctrl-paris.c | 19 +++
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 20e1c89..4687f63 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -68,7 +68,7 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
 {
const struct mtk_pin_field_calc *c, *e;
const struct mtk_pin_reg_calc *rc;
-   u32 bits;
+   u32 bits, start = 0, end, found = 0, check;
 
if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
rc = &hw->soc->reg_cal[field];
@@ -79,21 +79,32 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
return -ENOTSUPP;
}
 
+   end = rc->nranges - 1;
c = rc->range;
e = c + rc->nranges;
 
-   while (c < e) {
-   if (desc->number >= c->s_pin && desc->number <= c->e_pin)
+   while (start <= end) {
+   check = (start + end) >> 1;
+   if (desc->number >= rc->range[check].s_pin
+&& desc->number <= rc->range[check].e_pin) {
+   found = 1;
break;
-   c++;
+   } else if (start == end)
+   break;
+   else if (desc->number < rc->range[check].s_pin)
+   end = check - 1;
+   else
+   start = check + 1;
}
 
-   if (c >= e) {
+   if (!found) {
dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
field, desc->number, desc->name);
return -ENOTSUPP;
}
 
+   c = rc->range + check;
+
if (c->i_base > hw->nbase - 1) {
dev_err(hw->dev,
"Invalid base for field %d for pin = %d (%s)\n",
@@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
if (err)
return err;
 
+   if (value < 0 || value > pf.mask)
+   return -EINVAL;
+
if (!pf.next)
mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
(value & pf.mask) << pf.bitpos);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 923264d..28b4951 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -693,6 +693,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, 
unsigned int gpio)
const struct mtk_pin_desc *desc;
int value, err;
 
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
@@ -708,6 +711,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned 
int gpio)
const struct mtk_pin_desc *desc;
int value, err;
 
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
@@ -722,6 +728,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
int gpio, int value)
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
 
+   if (gpio > hw->soc->npins)
+   return;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
@@ -729,12 +738,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
int gpio, int value)
 
 static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
 {
+   struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
return pinctrl_gpio_direction_input(chip->base + gpio);
 }
 
 static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
 int value)
 {
+   struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
mtk_gpio_set(chip, gpio, value);
 
return pinctrl_gpio_direction_output(chip->base + gpio);
-- 
1.8.1.1.dirty



[PATCH v4 5/5] pinctrl: mediatek: Add support for pin configuration dump via debugfs.

2019-09-17 Thread Light Hsieh
Add support for pin configuration dump via catting
/sys/kernel/debug/pinctrl/$platform_dependent_path/pinconf-pins.
pinctrl framework had already support such dump. This patch implement the
operation function pointer to fullfill this dump.

---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 88 
 1 file changed, 88 insertions(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index e847867..6acbdc3 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -530,12 +530,99 @@ static int mtk_pctrl_get_group_pins(struct pinctrl_dev 
*pctldev,
return 0;
 }
 
+int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int field)
+{
+   const struct mtk_pin_desc *desc;
+   int value, err;
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
+   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+
+   err = mtk_hw_get_value(hw, desc, field, &value);
+   if (err)
+   return err;
+
+   return value;
+}
+
+ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
+   unsigned int gpio, char *buf, unsigned int bufLen)
+{
+   const struct mtk_pin_desc *desc;
+   int pinmux, pullup, pullen, r1 = -1, r0 = -1, len = 0;
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
+   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+   pinmux = mtk_pctrl_get_pinmux(hw, gpio);
+   if (pinmux >= hw->soc->nfuncs)
+   pinmux -= hw->soc->nfuncs;
+
+   mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
+   if (pullen == MTK_PUPD_SET_R1R0_00) {
+   pullen = 0;
+   r1 = 0;
+   r0 = 0;
+   } else if (pullen == MTK_PUPD_SET_R1R0_01) {
+   pullen = 1;
+   r1 = 0;
+   r0 = 1;
+   } else if (pullen == MTK_PUPD_SET_R1R0_10) {
+   pullen = 1;
+   r1 = 1;
+   r0 = 0;
+   } else if (pullen == MTK_PUPD_SET_R1R0_11) {
+   pullen = 1;
+   r1 = 1;
+   r0 = 1;
+   } else if (pullen != MTK_DISABLE && pullen != MTK_ENABLE) {
+   pullen = 0;
+   }
+   len += snprintf(buf + len, bufLen - len,
+   "%03d: %1d%1d%1d%1d%02d%1d%1d%1d%1d",
+   gpio,
+   pinmux,
+   mtk_pctrl_get_direction(hw, gpio),
+   mtk_pctrl_get_out(hw, gpio),
+   mtk_pctrl_get_in(hw, gpio),
+   mtk_pctrl_get_driving(hw, gpio),
+   mtk_pctrl_get_smt(hw, gpio),
+   mtk_pctrl_get_ies(hw, gpio),
+   pullen,
+   pullup);
+
+   if (r1 != -1) {
+   len += snprintf(buf + len, bufLen - len, " (%1d %1d)\n",
+   r1, r0);
+   } else {
+   len += snprintf(buf + len, bufLen - len, "\n");
+   }
+
+   return len;
+}
+
+#define PIN_DBG_BUF_SZ 96
+static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+ unsigned int gpio)
+{
+   struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+   char buf[PIN_DBG_BUF_SZ];
+
+   (void)mtk_pctrl_show_one_pin(hw, gpio, buf, PIN_DBG_BUF_SZ);
+
+   seq_printf(s, "%s", buf);
+}
+
 static const struct pinctrl_ops mtk_pctlops = {
.dt_node_to_map = mtk_pctrl_dt_node_to_map,
.dt_free_map= pinctrl_utils_free_map,
.get_groups_count   = mtk_pctrl_get_groups_count,
.get_group_name = mtk_pctrl_get_group_name,
.get_group_pins = mtk_pctrl_get_group_pins,
+   .pin_dbg_show   = mtk_pctrl_dbg_show,
 };
 
 static int mtk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
@@ -632,6 +719,7 @@ static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, 
unsigned group,
.pin_config_get = mtk_pinconf_get,
.pin_config_group_get   = mtk_pconf_group_get,
.pin_config_group_set   = mtk_pconf_group_set,
+   .is_generic = true,
 };
 
 static struct pinctrl_desc mtk_desc = {
-- 
1.8.1.1.dirty



Re: [PATCH v3 1/5] pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()

2019-09-17 Thread Light Hsieh
Dear reviewers,

v3 fix build error in v2 as follows:

1.   In drivers/pinctrl/mediatek/pinctrl-paris.c of patch series 3/5:
-   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
-   if (err)
-   return err;
-
-   if (!val)
-   return -EINVAL;
-
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);

2.   In drivers/pinctrl/mediatek/pinctrl-mt6765.c of patch series 4/5:
-   .bias_disable_set = mtk_pinconf_bias_disable_set,
-   .bias_disable_get = mtk_pinconf_bias_disable_get,
-   .bias_set = mtk_pinconf_bias_set,
-   .bias_get = mtk_pinconf_bias_get,
+   .bias_set_combo = mtk_pinconf_bias_set_combo,
+   .bias_get_combo = mtk_pinconf_bias_get_combo,



On Tue, 2019-09-17 at 16:26 +0800, Light Hsieh wrote:
> 1. Check if gpio pin number is in valid range to prevent from get invalid
>pointer 'desc' in the following code:
>   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
> 
> 2. Use binary search in mtk_hw_pin_field_lookup()
>Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
>search.
> 
> ---
>  drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 24 
> +++-
>  drivers/pinctrl/mediatek/pinctrl-paris.c | 19 +++
>  2 files changed, 38 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
> b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> index 20e1c89..4687f63 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> @@ -68,7 +68,7 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
>  {
>   const struct mtk_pin_field_calc *c, *e;
>   const struct mtk_pin_reg_calc *rc;
> - u32 bits;
> + u32 bits, start = 0, end, found = 0, check;
>  
>   if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
>   rc = &hw->soc->reg_cal[field];
> @@ -79,21 +79,32 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
>   return -ENOTSUPP;
>   }
>  
> + end = rc->nranges - 1;
>   c = rc->range;
>   e = c + rc->nranges;
>  
> - while (c < e) {
> - if (desc->number >= c->s_pin && desc->number <= c->e_pin)
> + while (start <= end) {
> + check = (start + end) >> 1;
> + if (desc->number >= rc->range[check].s_pin
> +  && desc->number <= rc->range[check].e_pin) {
> + found = 1;
>   break;
> - c++;
> + } else if (start == end)
> + break;
> + else if (desc->number < rc->range[check].s_pin)
> + end = check - 1;
> + else
> + start = check + 1;
>   }
>  
> - if (c >= e) {
> + if (!found) {
>   dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
>   field, desc->number, desc->name);
>   return -ENOTSUPP;
>   }
>  
> + c = rc->range + check;
> +
>   if (c->i_base > hw->nbase - 1) {
>   dev_err(hw->dev,
>   "Invalid base for field %d for pin = %d (%s)\n",
> @@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
> mtk_pin_desc *desc,
>   if (err)
>   return err;
>  
> + if (value < 0 || value > pf.mask)
> + return -EINVAL;
> +
>   if (!pf.next)
>   mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
>   (value & pf.mask) << pf.bitpos);
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
> b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 923264d..28b4951 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -693,6 +693,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, 
> unsigned int gpio)
>   const struct mtk_pin_desc *desc;
>   int value, err;
>  
> + if (gpio > hw->soc->npins)
> + return -EINVAL;
> +
>   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
>  
>   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
> @@ -708,6 +711,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned 
> int gpio)
>   const struct mtk_pin_desc *desc;
>   int value, err;
>  
> + if (gpio > hw->soc->npins)
> +

[PATCH v3 2/5] pinctrl: mediatek: Supporting driving setting without mapping current to register value

2019-09-17 Thread Light Hsieh
Mediatek's smarphone project actual usage does need to know current value
(in mA) in procedure of finding the best driving setting.
The steps in the procedure is like as follow:

1. set driving setting field in setting register as 0, measure waveform,
   perform test, and etc.
2. set driving setting field in setting register as 1, measure waveform,
   perform test, and etc.
...
n. set driving setting field in setting register as n-1, measure
   waveform, perform test, and etc.
Check the results of steps 1~n and adopt the setting that get best result.

This procedure does need to know the mapping between current to register
value.
Therefore, setting driving without mapping current is more pratical for
Mediatek's smartphone usage.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c|  4 ++--
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 21 +
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  5 +
 drivers/pinctrl/mediatek/pinctrl-paris.c |  1 +
 4 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index 32451e8..e024ebc 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1077,8 +1077,8 @@
.bias_disable_get = mtk_pinconf_bias_disable_get,
.bias_set = mtk_pinconf_bias_set,
.bias_get = mtk_pinconf_bias_get,
-   .drive_set = mtk_pinconf_drive_set_rev1,
-   .drive_get = mtk_pinconf_drive_get_rev1,
+   .drive_set = mtk_pinconf_drive_set_direct_val,
+   .drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
.adv_pull_set = mtk_pinconf_adv_pull_set,
 };
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 4687f63..23a9529 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -607,6 +607,27 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
return 0;
 }
 
+/* Revision direct value */
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, u32 arg)
+{
+   int err;
+
+   err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
+
+   return err;
+}
+
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, int *val)
+{
+   int err;
+
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
+
+   return err;
+}
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 const struct mtk_pin_desc *desc, bool pullup,
 u32 arg)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 1b7da42..b3bada0 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -288,6 +288,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
 int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
   const struct mtk_pin_desc *desc, int *val);
 
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, u32 arg);
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, int *val);
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 const struct mtk_pin_desc *desc, bool pullup,
 u32 arg);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 28b4951..71c94b2 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -964,3 +964,4 @@ static int mtk_paris_pinctrl_resume(struct device *device)
.suspend_noirq = mtk_paris_pinctrl_suspend,
.resume_noirq = mtk_paris_pinctrl_resume,
 };
+
-- 
1.8.1.1.dirty



[PATCH v3 4/5] pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull usage

2019-09-17 Thread Light Hsieh
Refine mtk_pinconf_set()/mtk_pinconf_get() for backward compatibility to
previous Mediatek's bias-pull usage.
In PINCTRL_MTK that use pinctrl-mtk-common.c, bias-pull setting for pins
with 2 pull resistors can be specified as value for bias-pull-up and
bias-pull-down. For example:
bias-pull-up = ;
bias-pull-up = ;
bias-pull-up = ;
bias-pull-up = ;
bias-pull-down = ;
bias-pull-down = ;
bias-pull-down = ;
bias-pull-down = ;

On the other hand, PINCTRL_MTK_PARIS use customized properties
"mediatek,pull-up-adv" and "mediatek,pull-down-adv" to specify bias-pull
setting for pins with 2 pull resistors.
This introduce in-compatibility in device tree and increatse porting
effort to Mediatek's customer that had already used PINCTRL_MTK version.
Besides, if customers are not awared of this change and still write devicetree
for PINCTRL_MTK version, they may encounter runtime failure with pinctrl and
spent time to debug.

This patch add backward compatible to previous Mediatek's bias-pull usage
so that Mediatek's customer need not use a new devicetree property name.
The rationale is that: changing driver implemenation had better leave
interface unchanged.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c|   6 +-
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 285 +++
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  11 +
 drivers/pinctrl/mediatek/pinctrl-paris.c |  49 ++--
 4 files changed, 327 insertions(+), 24 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index bada37f..ae85fdc 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1072,10 +1072,8 @@
.gpio_m = 0,
.base_names = mt6765_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
-   .bias_disable_set = mtk_pinconf_bias_disable_set,
-   .bias_disable_get = mtk_pinconf_bias_disable_get,
-   .bias_set = mtk_pinconf_bias_set,
-   .bias_get = mtk_pinconf_bias_get,
+   .bias_set_combo = mtk_pinconf_bias_set_combo,
+   .bias_get_combo = mtk_pinconf_bias_get_combo,
.drive_set = mtk_pinconf_drive_set_direct_val,
.drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 23a9529..dab8418 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -13,6 +13,8 @@
 #include 
 #include 
 
+#include 
+
 #include "mtk-eint.h"
 #include "pinctrl-mtk-common-v2.h"
 
@@ -205,6 +207,20 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
return 0;
 }
 
+void mtk_hw_set_value_no_lookup(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   int value, struct mtk_pin_field *pf)
+{
+   if (value < 0 || value > pf->mask)
+   return;
+
+   if (!pf->next)
+   mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos,
+   (value & pf->mask) << pf->bitpos);
+   else
+   mtk_hw_write_cross_field(hw, pf, value);
+}
+
 int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 int field, int *value)
 {
@@ -224,6 +240,17 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
return 0;
 }
 
+void mtk_hw_get_value_no_lookup(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   int *value, struct mtk_pin_field *pf)
+{
+   if (!pf->next)
+   *value = (mtk_r32(hw, pf->index, pf->offset)
+ >> pf->bitpos) & pf->mask;
+   else
+   mtk_hw_read_cross_field(hw, pf, value);
+}
+
 static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
 {
const struct mtk_pin_desc *desc;
@@ -516,6 +543,264 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
return 0;
 }
 
+/* Combo for the following pull register type:
+ * 1. PU + PD
+ * 2. PULLSEL + PULLEN
+ * 3. PUPD + R0 + R1
+ */
+int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   u32 pullup, u32 arg)
+{
+   struct mtk_pin_field pf;
+   int err = -EINVAL;
+   int pu, pd;
+
+   err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PU, &pf);
+   if (err)
+   goto out;
+
+   if (arg == MTK_DISABLE) {
+   pu = 0;
+   pd = 0;
+   } else if ((arg == MTK_ENABLE) && pullup) {
+   pu = 1;
+   pd = 0;
+   } else if ((arg == MTK_ENABLE) && !pullup) {
+   pu = 0;
+  

[PATCH v3 1/5] pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()

2019-09-17 Thread Light Hsieh
1. Check if gpio pin number is in valid range to prevent from get invalid
   pointer 'desc' in the following code:
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];

2. Use binary search in mtk_hw_pin_field_lookup()
   Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
   search.

---
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 24 +++-
 drivers/pinctrl/mediatek/pinctrl-paris.c | 19 +++
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 20e1c89..4687f63 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -68,7 +68,7 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
 {
const struct mtk_pin_field_calc *c, *e;
const struct mtk_pin_reg_calc *rc;
-   u32 bits;
+   u32 bits, start = 0, end, found = 0, check;
 
if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
rc = &hw->soc->reg_cal[field];
@@ -79,21 +79,32 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
return -ENOTSUPP;
}
 
+   end = rc->nranges - 1;
c = rc->range;
e = c + rc->nranges;
 
-   while (c < e) {
-   if (desc->number >= c->s_pin && desc->number <= c->e_pin)
+   while (start <= end) {
+   check = (start + end) >> 1;
+   if (desc->number >= rc->range[check].s_pin
+&& desc->number <= rc->range[check].e_pin) {
+   found = 1;
break;
-   c++;
+   } else if (start == end)
+   break;
+   else if (desc->number < rc->range[check].s_pin)
+   end = check - 1;
+   else
+   start = check + 1;
}
 
-   if (c >= e) {
+   if (!found) {
dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
field, desc->number, desc->name);
return -ENOTSUPP;
}
 
+   c = rc->range + check;
+
if (c->i_base > hw->nbase - 1) {
dev_err(hw->dev,
"Invalid base for field %d for pin = %d (%s)\n",
@@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
if (err)
return err;
 
+   if (value < 0 || value > pf.mask)
+   return -EINVAL;
+
if (!pf.next)
mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
(value & pf.mask) << pf.bitpos);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 923264d..28b4951 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -693,6 +693,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, 
unsigned int gpio)
const struct mtk_pin_desc *desc;
int value, err;
 
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
@@ -708,6 +711,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned 
int gpio)
const struct mtk_pin_desc *desc;
int value, err;
 
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
@@ -722,6 +728,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
int gpio, int value)
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
 
+   if (gpio > hw->soc->npins)
+   return;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
@@ -729,12 +738,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
int gpio, int value)
 
 static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
 {
+   struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
return pinctrl_gpio_direction_input(chip->base + gpio);
 }
 
 static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
 int value)
 {
+   struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
mtk_gpio_set(chip, gpio, value);
 
return pinctrl_gpio_direction_output(chip->base + gpio);
-- 
1.8.1.1.dirty



[PATCH v3 3/5] pinctrl: mediatek: Refine mtk_pinconf_get() and mtk_pinconf_set()

2019-09-17 Thread Light Hsieh
1.Refine mtk_pinconf_get():
1.1 Use only one occurrence of return at end of this function.
1.2 Correct cases for PIN_CONFIG_SLEW_RATE, PIN_CONFIG_INPUT_SCHMITT_ENABLE,
and PIN_CONFIG_OUTPUT_ENABLE -
Use variable ret to receive value in mtk_hw_get_value() (instead of
variable val) since pinconf_to_config_packed() at end of this function
use variable ret to pack config value.

2.Refine mtk_pinconf_set():
2.1 Use only one occurrence of return at end of this function.
2.2 Modify case of PIN_CONFIG_INPUT_ENABLE -
Remove check of ies_present flag and always invoke mtk_hw_set_value()
since mtk_hw_pin_field_lookup() invoked inside mtk_hw_set_value() has
the same effect of checking if ies control is supported.
[The rationale is that: available of a control is always checked
 in mtk_hw_pin_field_lookup() and no need to add ies_present flag
 specially for ies control.]
2.3 Simply code logic for case of PIN_CONFIG_INPUT_SCHMITT.
2.4 Add case for PIN_CONFIG_INPUT_SCHMITT_ENABLE and process it with the
same code for case of PIN_CONFIG_INPUT_SCHMITT.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c |   1 -
 drivers/pinctrl/mediatek/pinctrl-paris.c  | 206 +++---
 2 files changed, 76 insertions(+), 131 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index e024ebc..bada37f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1070,7 +1070,6 @@
.ngrps = ARRAY_SIZE(mtk_pins_mt6765),
.eint_hw = &mt6765_eint_hw,
.gpio_m = 0,
-   .ies_present = true,
.base_names = mt6765_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 71c94b2..33d2340 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -78,93 +78,75 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 {
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
u32 param = pinconf_to_config_param(*config);
-   int val, val2, err, reg, ret = 1;
+   int err, reg, ret = 1;
const struct mtk_pin_desc *desc;
 
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
 
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
-   if (hw->soc->bias_disable_get) {
+   if (hw->soc->bias_disable_get)
err = hw->soc->bias_disable_get(hw, desc, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_UP:
-   if (hw->soc->bias_get) {
+   if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 1, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
-   if (hw->soc->bias_get) {
+   if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 0, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_SLEW_RATE:
-   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
-   if (err)
-   return err;
-
-   if (!val)
-   return -EINVAL;
-
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
break;
case PIN_CONFIG_INPUT_ENABLE:
case PIN_CONFIG_OUTPUT_ENABLE:
-   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
if (err)
-   return err;
-
-   /* HW takes input mode as zero; output mode as non-zero */
-   if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
-   (!val && param == PIN_CONFIG_OUTPUT_ENABLE))
-   return -EINVAL;
+   goto out;
+   /* CONFIG Current direction return value
+* -  - --
+* OUTPUT_ENABLE   output   1 (= HW value)
+* input0 (= HW value)
+ 

[PATCH v3 5/5] pinctrl: mediatek: Add support for pin configuration dump via debugfs.

2019-09-17 Thread Light Hsieh
Add support for pin configuration dump via catting
/sys/kernel/debug/pinctrl/$platform_dependent_path/pinconf-pins.
pinctrl framework had already support such dump. This patch implement the
operation function pointer to fullfill this dump.

---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 88 
 drivers/pinctrl/mediatek/pinctrl-paris.h | 30 +++
 2 files changed, 118 insertions(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 69d3554..6c3a9ba 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -531,12 +531,99 @@ static int mtk_pctrl_get_group_pins(struct pinctrl_dev 
*pctldev,
return 0;
 }
 
+int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int field)
+{
+   const struct mtk_pin_desc *desc;
+   int value, err;
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
+   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+
+   err = mtk_hw_get_value(hw, desc, field, &value);
+   if (err)
+   return err;
+
+   return value;
+}
+
+ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
+   unsigned int gpio, char *buf, unsigned int bufLen)
+{
+   const struct mtk_pin_desc *desc;
+   int pinmux, pullup, pullen, r1 = -1, r0 = -1, len = 0;
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
+   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+   pinmux = mtk_pctrl_get_pinmux(hw, gpio);
+   if (pinmux >= hw->soc->nfuncs)
+   pinmux -= hw->soc->nfuncs;
+
+   mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
+   if (pullen == MTK_PUPD_SET_R1R0_00) {
+   pullen = 0;
+   r1 = 0;
+   r0 = 0;
+   } else if (pullen == MTK_PUPD_SET_R1R0_01) {
+   pullen = 1;
+   r1 = 0;
+   r0 = 1;
+   } else if (pullen == MTK_PUPD_SET_R1R0_10) {
+   pullen = 1;
+   r1 = 1;
+   r0 = 0;
+   } else if (pullen == MTK_PUPD_SET_R1R0_11) {
+   pullen = 1;
+   r1 = 1;
+   r0 = 1;
+   } else if (pullen != MTK_DISABLE && pullen != MTK_ENABLE) {
+   pullen = 0;
+   }
+   len += snprintf(buf + len, bufLen - len,
+   "%03d: %1d%1d%1d%1d%02d%1d%1d%1d%1d",
+   gpio,
+   pinmux,
+   mtk_pctrl_get_direction(hw, gpio),
+   mtk_pctrl_get_out(hw, gpio),
+   mtk_pctrl_get_in(hw, gpio),
+   mtk_pctrl_get_driving(hw, gpio),
+   mtk_pctrl_get_smt(hw, gpio),
+   mtk_pctrl_get_ies(hw, gpio),
+   pullen,
+   pullup);
+
+   if (r1 != -1) {
+   len += snprintf(buf + len, bufLen - len, " (%1d %1d)\n",
+   r1, r0);
+   } else {
+   len += snprintf(buf + len, bufLen - len, "\n");
+   }
+
+   return len;
+}
+
+#define PIN_DBG_BUF_SZ 96
+static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+ unsigned int gpio)
+{
+   struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+   char buf[PIN_DBG_BUF_SZ];
+
+   (void)mtk_pctrl_show_one_pin(hw, gpio, buf, PIN_DBG_BUF_SZ);
+
+   seq_printf(s, "%s", buf);
+}
+
 static const struct pinctrl_ops mtk_pctlops = {
.dt_node_to_map = mtk_pctrl_dt_node_to_map,
.dt_free_map= pinctrl_utils_free_map,
.get_groups_count   = mtk_pctrl_get_groups_count,
.get_group_name = mtk_pctrl_get_group_name,
.get_group_pins = mtk_pctrl_get_group_pins,
+   .pin_dbg_show   = mtk_pctrl_dbg_show,
 };
 
 static int mtk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
@@ -633,6 +720,7 @@ static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, 
unsigned group,
.pin_config_get = mtk_pinconf_get,
.pin_config_group_get   = mtk_pconf_group_get,
.pin_config_group_set   = mtk_pconf_group_set,
+   .is_generic = true,
 };
 
 static struct pinctrl_desc mtk_desc = {
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.h 
b/drivers/pinctrl/mediatek/pinctrl-paris.h
index 3d43771..d73f4b6 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.h
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.h
@@ -60,6 +60,36 @@
 int mtk_paris_pinctrl_probe(struct platform_device *pdev,
const struct mtk_pin_soc *soc);
 
+int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int 
field);
+
+#define mtk_pctrl_get_pinmux(hw, gpio) \
+   mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_MODE)
+
+/* MTK HW use 0 as input, 1 for output
+ * This interface is for get direct register value,
+ * so don't

Re: [PATCH v2 1/5] pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()

2019-09-04 Thread Light Hsieh
Dear reviewers, 

v2 is the same as v1 except that commit message is corrected according
to Linus' comment for v1:

1. remove Change-Id lines
2. correct sysfs as debugfs

On Thu, 2019-09-05 at 13:53 +0800, Light Hsieh wrote:
> From: Light Hsieh 
> 
> 1. Check if gpio pin number is in valid range to prevent from get invalid
>pointer 'desc' in the following code:
>   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
> 
> 2. Use binary search in mtk_hw_pin_field_lookup()
>Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
>search.
> 
> ---
>  drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 24 
> +++-
>  drivers/pinctrl/mediatek/pinctrl-paris.c | 19 +++
>  2 files changed, 38 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
> b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> index 20e1c89..4687f63 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> @@ -68,7 +68,7 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
>  {
>   const struct mtk_pin_field_calc *c, *e;
>   const struct mtk_pin_reg_calc *rc;
> - u32 bits;
> + u32 bits, start = 0, end, found = 0, check;
>  
>   if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
>   rc = &hw->soc->reg_cal[field];
> @@ -79,21 +79,32 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
>   return -ENOTSUPP;
>   }
>  
> + end = rc->nranges - 1;
>   c = rc->range;
>   e = c + rc->nranges;
>  
> - while (c < e) {
> - if (desc->number >= c->s_pin && desc->number <= c->e_pin)
> + while (start <= end) {
> + check = (start + end) >> 1;
> + if (desc->number >= rc->range[check].s_pin
> +  && desc->number <= rc->range[check].e_pin) {
> + found = 1;
>   break;
> - c++;
> + } else if (start == end)
> + break;
> + else if (desc->number < rc->range[check].s_pin)
> + end = check - 1;
> + else
> + start = check + 1;
>   }
>  
> - if (c >= e) {
> + if (!found) {
>   dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
>   field, desc->number, desc->name);
>   return -ENOTSUPP;
>   }
>  
> + c = rc->range + check;
> +
>   if (c->i_base > hw->nbase - 1) {
>   dev_err(hw->dev,
>   "Invalid base for field %d for pin = %d (%s)\n",
> @@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
> mtk_pin_desc *desc,
>   if (err)
>   return err;
>  
> + if (value < 0 || value > pf.mask)
> + return -EINVAL;
> +
>   if (!pf.next)
>   mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
>   (value & pf.mask) << pf.bitpos);
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
> b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 923264d..28b4951 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -693,6 +693,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, 
> unsigned int gpio)
>   const struct mtk_pin_desc *desc;
>   int value, err;
>  
> + if (gpio > hw->soc->npins)
> + return -EINVAL;
> +
>   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
>  
>   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
> @@ -708,6 +711,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned 
> int gpio)
>   const struct mtk_pin_desc *desc;
>   int value, err;
>  
> + if (gpio > hw->soc->npins)
> + return -EINVAL;
> +
>   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
>  
>   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
> @@ -722,6 +728,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
> int gpio, int value)
>   struct mtk_pinctrl *hw = gpiochip_get_data(chip);
>   const struct mtk_pin_desc *desc;
>  
> + if (gpio > hw->soc->npins)
> + return;
> +
>   desc = (const struct mtk_pin_desc *)&hw->soc->

[PATCH v2 3/5] pinctrl: mediatek: Refine mtk_pinconf_get() and mtk_pinconf_set()

2019-09-04 Thread Light Hsieh
From: Light Hsieh 

1.Refine mtk_pinconf_get():
1.1 Use only one occurrence of return at end of this function.
1.2 Correct cases for PIN_CONFIG_SLEW_RATE, PIN_CONFIG_INPUT_SCHMITT_ENABLE,
and PIN_CONFIG_OUTPUT_ENABLE -
Use variable ret to receive value in mtk_hw_get_value() (instead of
variable val) since pinconf_to_config_packed() at end of this function
use variable ret to pack config value.

2.Refine mtk_pinconf_set():
2.1 Use only one occurrence of return at end of this function.
2.2 Modify case of PIN_CONFIG_INPUT_ENABLE -
Remove check of ies_present flag and always invoke mtk_hw_set_value()
since mtk_hw_pin_field_lookup() invoked inside mtk_hw_set_value() has
the same effect of checking if ies control is supported.
[The rationale is that: available of a control is always checked
 in mtk_hw_pin_field_lookup() and no need to add ies_present flag
 specially for ies control.]
2.3 Simply code logic for case of PIN_CONFIG_INPUT_SCHMITT.
2.4 Add case for PIN_CONFIG_INPUT_SCHMITT_ENABLE and process it with the
same code for case of PIN_CONFIG_INPUT_SCHMITT.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c |   1 -
 drivers/pinctrl/mediatek/pinctrl-paris.c  | 204 +++---
 2 files changed, 75 insertions(+), 130 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index e024ebc..bada37f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1070,7 +1070,6 @@
.ngrps = ARRAY_SIZE(mtk_pins_mt6765),
.eint_hw = &mt6765_eint_hw,
.gpio_m = 0,
-   .ies_present = true,
.base_names = mt6765_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 71c94b2..bbe3f8a 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -78,93 +78,75 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 {
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
u32 param = pinconf_to_config_param(*config);
-   int val, val2, err, reg, ret = 1;
+   int err, reg, ret = 1;
const struct mtk_pin_desc *desc;
 
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
 
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
-   if (hw->soc->bias_disable_get) {
+   if (hw->soc->bias_disable_get)
err = hw->soc->bias_disable_get(hw, desc, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_UP:
-   if (hw->soc->bias_get) {
+   if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 1, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
-   if (hw->soc->bias_get) {
+   if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 0, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_SLEW_RATE:
-   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
-   if (err)
-   return err;
-
-   if (!val)
-   return -EINVAL;
-
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
break;
case PIN_CONFIG_INPUT_ENABLE:
case PIN_CONFIG_OUTPUT_ENABLE:
-   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
if (err)
-   return err;
-
-   /* HW takes input mode as zero; output mode as non-zero */
-   if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
-   (!val && param == PIN_CONFIG_OUTPUT_ENABLE))
-   return -EINVAL;
+   goto out;
+   /* CONFIG Current direction return value
+* -  - --

[PATCH v2 1/5] pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()

2019-09-04 Thread Light Hsieh
From: Light Hsieh 

1. Check if gpio pin number is in valid range to prevent from get invalid
   pointer 'desc' in the following code:
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];

2. Use binary search in mtk_hw_pin_field_lookup()
   Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
   search.

---
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 24 +++-
 drivers/pinctrl/mediatek/pinctrl-paris.c | 19 +++
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 20e1c89..4687f63 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -68,7 +68,7 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
 {
const struct mtk_pin_field_calc *c, *e;
const struct mtk_pin_reg_calc *rc;
-   u32 bits;
+   u32 bits, start = 0, end, found = 0, check;
 
if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
rc = &hw->soc->reg_cal[field];
@@ -79,21 +79,32 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
return -ENOTSUPP;
}
 
+   end = rc->nranges - 1;
c = rc->range;
e = c + rc->nranges;
 
-   while (c < e) {
-   if (desc->number >= c->s_pin && desc->number <= c->e_pin)
+   while (start <= end) {
+   check = (start + end) >> 1;
+   if (desc->number >= rc->range[check].s_pin
+&& desc->number <= rc->range[check].e_pin) {
+   found = 1;
break;
-   c++;
+   } else if (start == end)
+   break;
+   else if (desc->number < rc->range[check].s_pin)
+   end = check - 1;
+   else
+   start = check + 1;
}
 
-   if (c >= e) {
+   if (!found) {
dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
field, desc->number, desc->name);
return -ENOTSUPP;
}
 
+   c = rc->range + check;
+
if (c->i_base > hw->nbase - 1) {
dev_err(hw->dev,
"Invalid base for field %d for pin = %d (%s)\n",
@@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
if (err)
return err;
 
+   if (value < 0 || value > pf.mask)
+   return -EINVAL;
+
if (!pf.next)
mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
(value & pf.mask) << pf.bitpos);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 923264d..28b4951 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -693,6 +693,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, 
unsigned int gpio)
const struct mtk_pin_desc *desc;
int value, err;
 
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
@@ -708,6 +711,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned 
int gpio)
const struct mtk_pin_desc *desc;
int value, err;
 
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
@@ -722,6 +728,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
int gpio, int value)
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
 
+   if (gpio > hw->soc->npins)
+   return;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
@@ -729,12 +738,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
int gpio, int value)
 
 static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
 {
+   struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
return pinctrl_gpio_direction_input(chip->base + gpio);
 }
 
 static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
 int value)
 {
+   struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
mtk_gpio_set(chip, gpio, value);
 
return pinctrl_gpio_direction_output(chip->base + gpio);
-- 
1.8.1.1.dirty



[PATCH v2 4/5] pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull usage

2019-09-04 Thread Light Hsieh
From: Light Hsieh 

Refine mtk_pinconf_set()/mtk_pinconf_get() for backward compatibility to
previous Mediatek's bias-pull usage.
In PINCTRL_MTK that use pinctrl-mtk-common.c, bias-pull setting for pins
with 2 pull resistors can be specified as value for bias-pull-up and
bias-pull-down. For example:
bias-pull-up = ;
bias-pull-up = ;
bias-pull-up = ;
bias-pull-up = ;
bias-pull-down = ;
bias-pull-down = ;
bias-pull-down = ;
bias-pull-down = ;

On the other hand, PINCTRL_MTK_PARIS use customized properties
"mediatek,pull-up-adv" and "mediatek,pull-down-adv" to specify bias-pull
setting for pins with 2 pull resistors.
This introduce in-compatibility in device tree and increatse porting
effort to Mediatek's customer that had already used PINCTRL_MTK version.
Besides, if customers are not awared of this change and still write devicetree
for PINCTRL_MTK version, they may encounter runtime failure with pinctrl and
spent time to debug.

This patch add backward compatible to previous Mediatek's bias-pull usage
so that Mediatek's customer need not use a new devicetree property name.
The rationale is that: changing driver implemenation had better leave
interface unchanged.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c|   4 +-
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 285 +++
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  11 +
 drivers/pinctrl/mediatek/pinctrl-paris.c |  49 ++--
 4 files changed, 327 insertions(+), 22 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index bada37f..315aebd 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1074,8 +1074,8 @@
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,
.bias_disable_get = mtk_pinconf_bias_disable_get,
-   .bias_set = mtk_pinconf_bias_set,
-   .bias_get = mtk_pinconf_bias_get,
+   .bias_set = mtk_pinconf_bias_set_combo,
+   .bias_get = mtk_pinconf_bias_get_combo,
.drive_set = mtk_pinconf_drive_set_direct_val,
.drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 23a9529..dab8418 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -13,6 +13,8 @@
 #include 
 #include 
 
+#include 
+
 #include "mtk-eint.h"
 #include "pinctrl-mtk-common-v2.h"
 
@@ -205,6 +207,20 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
return 0;
 }
 
+void mtk_hw_set_value_no_lookup(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   int value, struct mtk_pin_field *pf)
+{
+   if (value < 0 || value > pf->mask)
+   return;
+
+   if (!pf->next)
+   mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos,
+   (value & pf->mask) << pf->bitpos);
+   else
+   mtk_hw_write_cross_field(hw, pf, value);
+}
+
 int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 int field, int *value)
 {
@@ -224,6 +240,17 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
return 0;
 }
 
+void mtk_hw_get_value_no_lookup(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   int *value, struct mtk_pin_field *pf)
+{
+   if (!pf->next)
+   *value = (mtk_r32(hw, pf->index, pf->offset)
+ >> pf->bitpos) & pf->mask;
+   else
+   mtk_hw_read_cross_field(hw, pf, value);
+}
+
 static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
 {
const struct mtk_pin_desc *desc;
@@ -516,6 +543,264 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
return 0;
 }
 
+/* Combo for the following pull register type:
+ * 1. PU + PD
+ * 2. PULLSEL + PULLEN
+ * 3. PUPD + R0 + R1
+ */
+int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   u32 pullup, u32 arg)
+{
+   struct mtk_pin_field pf;
+   int err = -EINVAL;
+   int pu, pd;
+
+   err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PU, &pf);
+   if (err)
+   goto out;
+
+   if (arg == MTK_DISABLE) {
+   pu = 0;
+   pd = 0;
+   } else if ((arg == MTK_ENABLE) && pullup) {
+   pu = 1;
+   pd = 0;

[PATCH v2 2/5] pinctrl: mediatek: Supporting driving setting without mapping current to register value

2019-09-04 Thread Light Hsieh
From: Light Hsieh 

Mediatek's smarphone project actual usage does need to know current value
(in mA) in procedure of finding the best driving setting.
The steps in the procedure is like as follow:

1. set driving setting field in setting register as 0, measure waveform,
   perform test, and etc.
2. set driving setting field in setting register as 1, measure waveform,
   perform test, and etc.
...
n. set driving setting field in setting register as n-1, measure
   waveform, perform test, and etc.
Check the results of steps 1~n and adopt the setting that get best result.

This procedure does need to know the mapping between current to register
value.
Therefore, setting driving without mapping current is more pratical for
Mediatek's smartphone usage.

---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c|  4 ++--
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 21 +
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  5 +
 drivers/pinctrl/mediatek/pinctrl-paris.c |  1 +
 4 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index 32451e8..e024ebc 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1077,8 +1077,8 @@
.bias_disable_get = mtk_pinconf_bias_disable_get,
.bias_set = mtk_pinconf_bias_set,
.bias_get = mtk_pinconf_bias_get,
-   .drive_set = mtk_pinconf_drive_set_rev1,
-   .drive_get = mtk_pinconf_drive_get_rev1,
+   .drive_set = mtk_pinconf_drive_set_direct_val,
+   .drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
.adv_pull_set = mtk_pinconf_adv_pull_set,
 };
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 4687f63..23a9529 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -607,6 +607,27 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
return 0;
 }
 
+/* Revision direct value */
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, u32 arg)
+{
+   int err;
+
+   err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
+
+   return err;
+}
+
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, int *val)
+{
+   int err;
+
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
+
+   return err;
+}
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 const struct mtk_pin_desc *desc, bool pullup,
 u32 arg)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 1b7da42..b3bada0 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -288,6 +288,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
 int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
   const struct mtk_pin_desc *desc, int *val);
 
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, u32 arg);
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, int *val);
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 const struct mtk_pin_desc *desc, bool pullup,
 u32 arg);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 28b4951..71c94b2 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -964,3 +964,4 @@ static int mtk_paris_pinctrl_resume(struct device *device)
.suspend_noirq = mtk_paris_pinctrl_suspend,
.resume_noirq = mtk_paris_pinctrl_resume,
 };
+
-- 
1.8.1.1.dirty



[PATCH v2 5/5] pinctrl: mediatek: Add support for pin configuration dump via debugfs.

2019-09-04 Thread Light Hsieh
From: Light Hsieh 

Add support for pin configuration dump via catting
/sys/kernel/debug/pinctrl/$platform_dependent_path/pinconf-pins.
pinctrl framework had already support such dump. This patch implement the
operation function pointer to fullfill this dump.

---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 88 
 drivers/pinctrl/mediatek/pinctrl-paris.h | 30 +++
 2 files changed, 118 insertions(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 0a9440a..91d6e72 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -531,12 +531,99 @@ static int mtk_pctrl_get_group_pins(struct pinctrl_dev 
*pctldev,
return 0;
 }
 
+int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int field)
+{
+   const struct mtk_pin_desc *desc;
+   int value, err;
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
+   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+
+   err = mtk_hw_get_value(hw, desc, field, &value);
+   if (err)
+   return err;
+
+   return value;
+}
+
+ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
+   unsigned int gpio, char *buf, unsigned int bufLen)
+{
+   const struct mtk_pin_desc *desc;
+   int pinmux, pullup, pullen, r1 = -1, r0 = -1, len = 0;
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
+   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+   pinmux = mtk_pctrl_get_pinmux(hw, gpio);
+   if (pinmux >= hw->soc->nfuncs)
+   pinmux -= hw->soc->nfuncs;
+
+   mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
+   if (pullen == MTK_PUPD_SET_R1R0_00) {
+   pullen = 0;
+   r1 = 0;
+   r0 = 0;
+   } else if (pullen == MTK_PUPD_SET_R1R0_01) {
+   pullen = 1;
+   r1 = 0;
+   r0 = 1;
+   } else if (pullen == MTK_PUPD_SET_R1R0_10) {
+   pullen = 1;
+   r1 = 1;
+   r0 = 0;
+   } else if (pullen == MTK_PUPD_SET_R1R0_11) {
+   pullen = 1;
+   r1 = 1;
+   r0 = 1;
+   } else if (pullen != MTK_DISABLE && pullen != MTK_ENABLE) {
+   pullen = 0;
+   }
+   len += snprintf(buf + len, bufLen - len,
+   "%03d: %1d%1d%1d%1d%02d%1d%1d%1d%1d",
+   gpio,
+   pinmux,
+   mtk_pctrl_get_direction(hw, gpio),
+   mtk_pctrl_get_out(hw, gpio),
+   mtk_pctrl_get_in(hw, gpio),
+   mtk_pctrl_get_driving(hw, gpio),
+   mtk_pctrl_get_smt(hw, gpio),
+   mtk_pctrl_get_ies(hw, gpio),
+   pullen,
+   pullup);
+
+   if (r1 != -1) {
+   len += snprintf(buf + len, bufLen - len, " (%1d %1d)\n",
+   r1, r0);
+   } else {
+   len += snprintf(buf + len, bufLen - len, "\n");
+   }
+
+   return len;
+}
+
+#define PIN_DBG_BUF_SZ 96
+static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+ unsigned int gpio)
+{
+   struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+   char buf[PIN_DBG_BUF_SZ];
+
+   (void)mtk_pctrl_show_one_pin(hw, gpio, buf, PIN_DBG_BUF_SZ);
+
+   seq_printf(s, "%s", buf);
+}
+
 static const struct pinctrl_ops mtk_pctlops = {
.dt_node_to_map = mtk_pctrl_dt_node_to_map,
.dt_free_map= pinctrl_utils_free_map,
.get_groups_count   = mtk_pctrl_get_groups_count,
.get_group_name = mtk_pctrl_get_group_name,
.get_group_pins = mtk_pctrl_get_group_pins,
+   .pin_dbg_show   = mtk_pctrl_dbg_show,
 };
 
 static int mtk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
@@ -633,6 +720,7 @@ static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, 
unsigned group,
.pin_config_get = mtk_pinconf_get,
.pin_config_group_get   = mtk_pconf_group_get,
.pin_config_group_set   = mtk_pconf_group_set,
+   .is_generic = true,
 };
 
 static struct pinctrl_desc mtk_desc = {
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.h 
b/drivers/pinctrl/mediatek/pinctrl-paris.h
index 3d43771..d73f4b6 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.h
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.h
@@ -60,6 +60,36 @@
 int mtk_paris_pinctrl_probe(struct platform_device *pdev,
const struct mtk_pin_soc *soc);
 
+int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int 
field);
+
+#define mtk_pctrl_get_pinmux(hw, gpio) \
+   mtk_hw_get_value_wr

[PATCH v1 5/5] pinctrl: mediatek: Add support for pin configuration dump via sysfs.

2019-08-13 Thread Light Hsieh
From: Light Hsieh 

Add support for pin configuration dump via catting
/sys/kernel/debug/pinctrl/$platform_dependent_path/pinconf-pins.
pinctrl framework had already support such dump. This patch implement the
operation function pointer to fullfill this dump.

Change-Id: Ib59212eb47febcd84140cbf84e1bd7286769beb0
---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 88 
 drivers/pinctrl/mediatek/pinctrl-paris.h | 30 +++
 2 files changed, 118 insertions(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 0a9440a..91d6e72 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -531,12 +531,99 @@ static int mtk_pctrl_get_group_pins(struct pinctrl_dev 
*pctldev,
return 0;
 }
 
+int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int field)
+{
+   const struct mtk_pin_desc *desc;
+   int value, err;
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
+   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+
+   err = mtk_hw_get_value(hw, desc, field, &value);
+   if (err)
+   return err;
+
+   return value;
+}
+
+ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
+   unsigned int gpio, char *buf, unsigned int bufLen)
+{
+   const struct mtk_pin_desc *desc;
+   int pinmux, pullup, pullen, r1 = -1, r0 = -1, len = 0;
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
+   desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+   pinmux = mtk_pctrl_get_pinmux(hw, gpio);
+   if (pinmux >= hw->soc->nfuncs)
+   pinmux -= hw->soc->nfuncs;
+
+   mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
+   if (pullen == MTK_PUPD_SET_R1R0_00) {
+   pullen = 0;
+   r1 = 0;
+   r0 = 0;
+   } else if (pullen == MTK_PUPD_SET_R1R0_01) {
+   pullen = 1;
+   r1 = 0;
+   r0 = 1;
+   } else if (pullen == MTK_PUPD_SET_R1R0_10) {
+   pullen = 1;
+   r1 = 1;
+   r0 = 0;
+   } else if (pullen == MTK_PUPD_SET_R1R0_11) {
+   pullen = 1;
+   r1 = 1;
+   r0 = 1;
+   } else if (pullen != MTK_DISABLE && pullen != MTK_ENABLE) {
+   pullen = 0;
+   }
+   len += snprintf(buf + len, bufLen - len,
+   "%03d: %1d%1d%1d%1d%02d%1d%1d%1d%1d",
+   gpio,
+   pinmux,
+   mtk_pctrl_get_direction(hw, gpio),
+   mtk_pctrl_get_out(hw, gpio),
+   mtk_pctrl_get_in(hw, gpio),
+   mtk_pctrl_get_driving(hw, gpio),
+   mtk_pctrl_get_smt(hw, gpio),
+   mtk_pctrl_get_ies(hw, gpio),
+   pullen,
+   pullup);
+
+   if (r1 != -1) {
+   len += snprintf(buf + len, bufLen - len, " (%1d %1d)\n",
+   r1, r0);
+   } else {
+   len += snprintf(buf + len, bufLen - len, "\n");
+   }
+
+   return len;
+}
+
+#define PIN_DBG_BUF_SZ 96
+static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+ unsigned int gpio)
+{
+   struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+   char buf[PIN_DBG_BUF_SZ];
+
+   (void)mtk_pctrl_show_one_pin(hw, gpio, buf, PIN_DBG_BUF_SZ);
+
+   seq_printf(s, "%s", buf);
+}
+
 static const struct pinctrl_ops mtk_pctlops = {
.dt_node_to_map = mtk_pctrl_dt_node_to_map,
.dt_free_map= pinctrl_utils_free_map,
.get_groups_count   = mtk_pctrl_get_groups_count,
.get_group_name = mtk_pctrl_get_group_name,
.get_group_pins = mtk_pctrl_get_group_pins,
+   .pin_dbg_show   = mtk_pctrl_dbg_show,
 };
 
 static int mtk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
@@ -633,6 +720,7 @@ static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, 
unsigned group,
.pin_config_get = mtk_pinconf_get,
.pin_config_group_get   = mtk_pconf_group_get,
.pin_config_group_set   = mtk_pconf_group_set,
+   .is_generic = true,
 };
 
 static struct pinctrl_desc mtk_desc = {
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.h 
b/drivers/pinctrl/mediatek/pinctrl-paris.h
index 3d43771..d73f4b6 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.h
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.h
@@ -60,6 +60,36 @@
 int mtk_paris_pinctrl_probe(struct platform_device *pdev,
const struct mtk_pin_soc *soc);
 
+int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int 
field);
+
+#define mtk_pctrl_get_pinmux(hw, gpi

[PATCH v1 2/5] pinctrl: mediatek: Supporting driving setting without mapping current to register value

2019-08-13 Thread Light Hsieh
From: Light Hsieh 

Mediatek's smarphone project actual usage does need to know current value
(in mA) in procedure of finding the best driving setting.
The steps in the procedure is like as follow:

1. set driving setting field in setting register as 0, measure waveform,
   perform test, and etc.
2. set driving setting field in setting register as 1, measure waveform,
   perform test, and etc.
...
n. set driving setting field in setting register as n-1, measure
   waveform, perform test, and etc.
Check the results of steps 1~n and adopt the setting that get best result.

This procedure does need to know the mapping between current to register
value.
Therefore, setting driving without mapping current is more pratical for
Mediatek's smartphone usage.

Change-Id: Iacdabf0cada230fc5acad96673810c12a6c4556d
---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c|  4 ++--
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 21 +
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  5 +
 drivers/pinctrl/mediatek/pinctrl-paris.c |  1 +
 4 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index 32451e8..e024ebc 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1077,8 +1077,8 @@
.bias_disable_get = mtk_pinconf_bias_disable_get,
.bias_set = mtk_pinconf_bias_set,
.bias_get = mtk_pinconf_bias_get,
-   .drive_set = mtk_pinconf_drive_set_rev1,
-   .drive_get = mtk_pinconf_drive_get_rev1,
+   .drive_set = mtk_pinconf_drive_set_direct_val,
+   .drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
.adv_pull_set = mtk_pinconf_adv_pull_set,
 };
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 4687f63..23a9529 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -607,6 +607,27 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
return 0;
 }
 
+/* Revision direct value */
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, u32 arg)
+{
+   int err;
+
+   err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
+
+   return err;
+}
+
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, int *val)
+{
+   int err;
+
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
+
+   return err;
+}
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 const struct mtk_pin_desc *desc, bool pullup,
 u32 arg)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 1b7da42..b3bada0 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -288,6 +288,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
 int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
   const struct mtk_pin_desc *desc, int *val);
 
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, u32 arg);
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+  const struct mtk_pin_desc *desc, int *val);
+
 int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
 const struct mtk_pin_desc *desc, bool pullup,
 u32 arg);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 28b4951..71c94b2 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -964,3 +964,4 @@ static int mtk_paris_pinctrl_resume(struct device *device)
.suspend_noirq = mtk_paris_pinctrl_suspend,
.resume_noirq = mtk_paris_pinctrl_resume,
 };
+
-- 
1.8.1.1.dirty



[PATCH v1 0/5] Improve MediaTek pinctrl v2 and make backward compatible to smartphone mass production usage

2019-08-13 Thread Light Hsieh
This patch improves MediaTek pinctrl v2 and makes backward compatible to
current smartphone mass production usage by:
1.Check gpio pin number and use binary search in control address lookup
2.Supporting driving setting without mapping current to register value
3.Correct usage of PIN_CONFIG get/set implementation
4.Backward compatible to previous Mediatek's bias-pull usage
5.Add support for pin configuration dump via sysfs




[PATCH v1 4/5] pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull usage

2019-08-13 Thread Light Hsieh
From: Light Hsieh 

Refine mtk_pinconf_set()/mtk_pinconf_get() for backward compatibility to
previous Mediatek's bias-pull usage.
In PINCTRL_MTK that use pinctrl-mtk-common.c, bias-pull setting for pins
with 2 pull resistors can be specified as value for bias-pull-up and
bias-pull-down. For example:
bias-pull-up = ;
bias-pull-up = ;
bias-pull-up = ;
bias-pull-up = ;
bias-pull-down = ;
bias-pull-down = ;
bias-pull-down = ;
bias-pull-down = ;

On the other hand, PINCTRL_MTK_PARIS use customized properties
"mediatek,pull-up-adv" and "mediatek,pull-down-adv" to specify bias-pull
setting for pins with 2 pull resistors.
This introduce in-compatibility in device tree and increatse porting
effort to Mediatek's customer that had already used PINCTRL_MTK version.
Besides, if customers are not awared of this change and still write devicetree
for PINCTRL_MTK version, they may encounter runtime failure with pinctrl and
spent time to debug.

This patch add backward compatible to previous Mediatek's bias-pull usage
so that Mediatek's customer need not use a new devicetree property name.
The rationale is that: changing driver implemenation had better leave
interface unchanged.

Change-Id: I8ea8f09278acc492ba04771826eaadb70224cd51
---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c|   4 +-
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 285 +++
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  11 +
 drivers/pinctrl/mediatek/pinctrl-paris.c |  49 ++--
 4 files changed, 327 insertions(+), 22 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index bada37f..315aebd 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1074,8 +1074,8 @@
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,
.bias_disable_get = mtk_pinconf_bias_disable_get,
-   .bias_set = mtk_pinconf_bias_set,
-   .bias_get = mtk_pinconf_bias_get,
+   .bias_set = mtk_pinconf_bias_set_combo,
+   .bias_get = mtk_pinconf_bias_get_combo,
.drive_set = mtk_pinconf_drive_set_direct_val,
.drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 23a9529..dab8418 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -13,6 +13,8 @@
 #include 
 #include 
 
+#include 
+
 #include "mtk-eint.h"
 #include "pinctrl-mtk-common-v2.h"
 
@@ -205,6 +207,20 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
return 0;
 }
 
+void mtk_hw_set_value_no_lookup(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   int value, struct mtk_pin_field *pf)
+{
+   if (value < 0 || value > pf->mask)
+   return;
+
+   if (!pf->next)
+   mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos,
+   (value & pf->mask) << pf->bitpos);
+   else
+   mtk_hw_write_cross_field(hw, pf, value);
+}
+
 int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 int field, int *value)
 {
@@ -224,6 +240,17 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
return 0;
 }
 
+void mtk_hw_get_value_no_lookup(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   int *value, struct mtk_pin_field *pf)
+{
+   if (!pf->next)
+   *value = (mtk_r32(hw, pf->index, pf->offset)
+ >> pf->bitpos) & pf->mask;
+   else
+   mtk_hw_read_cross_field(hw, pf, value);
+}
+
 static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
 {
const struct mtk_pin_desc *desc;
@@ -516,6 +543,264 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
return 0;
 }
 
+/* Combo for the following pull register type:
+ * 1. PU + PD
+ * 2. PULLSEL + PULLEN
+ * 3. PUPD + R0 + R1
+ */
+int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
+   const struct mtk_pin_desc *desc,
+   u32 pullup, u32 arg)
+{
+   struct mtk_pin_field pf;
+   int err = -EINVAL;
+   int pu, pd;
+
+   err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PU, &pf);
+   if (err)
+   goto out;
+
+   if (arg == MTK_DISABLE) {
+   pu = 0;
+   pd = 0;
+   } else if ((arg == MTK_ENABLE) && pullup) {
+   

[PATCH v1 1/5] pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()

2019-08-13 Thread Light Hsieh
From: Light Hsieh 

1. Check if gpio pin number is in valid range to prevent from get invalid
   pointer 'desc' in the following code:
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];

2. Use binary search in mtk_hw_pin_field_lookup()
   Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
   search.

Change-Id: I22b4644ec216b90dd9dd5e223cc41d43761701b0
---
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 24 +++-
 drivers/pinctrl/mediatek/pinctrl-paris.c | 19 +++
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 20e1c89..4687f63 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -68,7 +68,7 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
 {
const struct mtk_pin_field_calc *c, *e;
const struct mtk_pin_reg_calc *rc;
-   u32 bits;
+   u32 bits, start = 0, end, found = 0, check;
 
if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
rc = &hw->soc->reg_cal[field];
@@ -79,21 +79,32 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
return -ENOTSUPP;
}
 
+   end = rc->nranges - 1;
c = rc->range;
e = c + rc->nranges;
 
-   while (c < e) {
-   if (desc->number >= c->s_pin && desc->number <= c->e_pin)
+   while (start <= end) {
+   check = (start + end) >> 1;
+   if (desc->number >= rc->range[check].s_pin
+&& desc->number <= rc->range[check].e_pin) {
+   found = 1;
break;
-   c++;
+   } else if (start == end)
+   break;
+   else if (desc->number < rc->range[check].s_pin)
+   end = check - 1;
+   else
+   start = check + 1;
}
 
-   if (c >= e) {
+   if (!found) {
dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
field, desc->number, desc->name);
return -ENOTSUPP;
}
 
+   c = rc->range + check;
+
if (c->i_base > hw->nbase - 1) {
dev_err(hw->dev,
"Invalid base for field %d for pin = %d (%s)\n",
@@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct 
mtk_pin_desc *desc,
if (err)
return err;
 
+   if (value < 0 || value > pf.mask)
+   return -EINVAL;
+
if (!pf.next)
mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
(value & pf.mask) << pf.bitpos);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 923264d..28b4951 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -693,6 +693,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, 
unsigned int gpio)
const struct mtk_pin_desc *desc;
int value, err;
 
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
@@ -708,6 +711,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned 
int gpio)
const struct mtk_pin_desc *desc;
int value, err;
 
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
@@ -722,6 +728,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
int gpio, int value)
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
 
+   if (gpio > hw->soc->npins)
+   return;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
@@ -729,12 +738,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned 
int gpio, int value)
 
 static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
 {
+   struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
return pinctrl_gpio_direction_input(chip->base + gpio);
 }
 
 static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
 int value)
 {
+   struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+   if (gpio > hw->soc->npins)
+   return -EINVAL;
+
mtk_gpio_set(chip, gpio, value);
 
return pinctrl_gpio_direction_output(chip->base + gpio);
-- 
1.8.1.1.dirty



[PATCH v1 3/5] pinctrl: mediatek: Refine mtk_pinconf_get() and mtk_pinconf_set()

2019-08-13 Thread Light Hsieh
From: Light Hsieh 

1.Refine mtk_pinconf_get():
1.1 Use only one occurrence of return at end of this function.
1.2 Correct cases for PIN_CONFIG_SLEW_RATE, PIN_CONFIG_INPUT_SCHMITT_ENABLE,
and PIN_CONFIG_OUTPUT_ENABLE -
Use variable ret to receive value in mtk_hw_get_value() (instead of
variable val) since pinconf_to_config_packed() at end of this function
use variable ret to pack config value.

2.Refine mtk_pinconf_set():
2.1 Use only one occurrence of return at end of this function.
2.2 Modify case of PIN_CONFIG_INPUT_ENABLE -
Remove check of ies_present flag and always invoke mtk_hw_set_value()
since mtk_hw_pin_field_lookup() invoked inside mtk_hw_set_value() has
the same effect of checking if ies control is supported.
[The rationale is that: available of a control is always checked
 in mtk_hw_pin_field_lookup() and no need to add ies_present flag
 specially for ies control.]
2.3 Simply code logic for case of PIN_CONFIG_INPUT_SCHMITT.
2.4 Add case for PIN_CONFIG_INPUT_SCHMITT_ENABLE and process it with the
same code for case of PIN_CONFIG_INPUT_SCHMITT.

Change-Id: Ia82ca7e2516839554feaad6f1aabd9f1bd3b5222
---
 drivers/pinctrl/mediatek/pinctrl-mt6765.c |   1 -
 drivers/pinctrl/mediatek/pinctrl-paris.c  | 204 +++---
 2 files changed, 75 insertions(+), 130 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c 
b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index e024ebc..bada37f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1070,7 +1070,6 @@
.ngrps = ARRAY_SIZE(mtk_pins_mt6765),
.eint_hw = &mt6765_eint_hw,
.gpio_m = 0,
-   .ies_present = true,
.base_names = mt6765_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 71c94b2..bbe3f8a 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -78,93 +78,75 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 {
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
u32 param = pinconf_to_config_param(*config);
-   int val, val2, err, reg, ret = 1;
+   int err, reg, ret = 1;
const struct mtk_pin_desc *desc;
 
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
 
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
-   if (hw->soc->bias_disable_get) {
+   if (hw->soc->bias_disable_get)
err = hw->soc->bias_disable_get(hw, desc, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_UP:
-   if (hw->soc->bias_get) {
+   if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 1, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
-   if (hw->soc->bias_get) {
+   if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 0, &ret);
-   if (err)
-   return err;
-   } else {
-   return -ENOTSUPP;
-   }
+   else
+   err = -ENOTSUPP;
break;
case PIN_CONFIG_SLEW_RATE:
-   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
-   if (err)
-   return err;
-
-   if (!val)
-   return -EINVAL;
-
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
break;
case PIN_CONFIG_INPUT_ENABLE:
case PIN_CONFIG_OUTPUT_ENABLE:
-   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
+   err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
if (err)
-   return err;
-
-   /* HW takes input mode as zero; output mode as non-zero */
-   if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
-   (!val && param == PIN_CONFIG_OUTPUT_ENABLE))
-   return -EINVAL;
+   goto out;
+   /* CONFIG Current direction return value
+* -

Re: [PATCH 1/1] pinctrl: Add alternative way for specifying register bases

2019-04-15 Thread Light Hsieh
Hi, Sean:

On Sun, 2019-04-14 at 16:01 -0700, Sean Wang wrote:
> Hi, Light
> 
> On Thu, Apr 11, 2019 at 8:15 PM Light Hsieh  wrote:
> >
> > The orginal PINCTRL_MTK_PARIS/PINCTRL_MTK_MOORE need more effort for
> > specifying register bases when porting platform driver:
> > 1. Write mt_pinctrl_register_base_name[] array in pinctrl-mt.c
> >to specify names of register bases, for exmaple:
> >
> > static const char * const mt6765_pinctrl_register_base_names[] = {
> > "iocfg0", "iocfg1", "iocfg2", "iocfg3", "iocfg4", "iocfg5",
> > "iocfg6", "iocfg7",
> > };
> > 2. Write reg = <...>, ..., <...>; in mt.dts to specify register
> >bases. Each member of reg contain address range cloned from
> >pre-generated devicetree node.
> > 3. Write reg-names = "...", ..., "..."; in mt.dts to specify
> >names of register bases. The sequence of names in reg-names shall match
> >sequence of names that specified in pinctrl-mt.c.
> >Besides, the seqeunce of names in reg-names shall also match sequence of
> >address range in reg, for exmaple:
> >
> > pio: pinctrl {
> > compatible = "mediatek,mt6765-pinctrl";
> > reg = <0 0x10005000 0 0x1000>,
> >   <0 0x10002C00 0 0x200>,
> >   <0 0x10002800 0 0x200>,
> >   <0 0x10002A00 0 0x200>,
> >   <0 0x10002000 0 0x200>,
> >   <0 0x10002200 0 0x200>,
> >   <0 0x10002400 0 0x200>,
> >   <0 0x10002600 0 0x200>,
> >   <0 0x1000b000 0 0x1000>;
> > reg-names = "iocfg0", "iocfg1", "iocfg2", "iocfg3",
> > "iocfg4", "iocfg5", "iocfg6", "iocfg7",
> > "eint";
> >
> > To reduce porting effort, this patch add an alternative way for specifying
> > register bases:
> > 1. Write reg_bases = <...>, ..., <...>; and reg_base_eint = <&eint>;
> >in mt.dtsi where members in reg_bases and &eint are labels for
> >pre-generated devicetree nodes, for example:
> > pio: pinctrl {
> > compatible = "mediatek,mt6765-pinctrl";
> > reg_bases = <&gpio0>,
> > <&iocfg0>,
> > <&iocfg1>,
> > <&iocfg2>,
> > <&iocfg3>,
> > <&iocfg4>,
> > <&iocfg5>,
> > <&iocfg6>,
> > <&iocfg7>;
> > reg_base_eint = <&eint>;
> 
> reg and reg-names both are generic properties used in all of DT-based
> device and driver, described in
> Documentation/devicetree/bindings/resource-names.txt, but reg_based
> and reg_base_eint aren't.
> 
> If these properties are not hardware specific related, I personally
> will encourage reusing those generic properties and relevant helpers
> because those generic properties handling in the base driver are
> almost bug-free, well maintained and even keep be extended in the
> future. This way can help driver people put more concentration on
> hardware specific stuff in the driver.
> 

This modification is somewhat like mtk pinctrl driver V1. In V1,
you may have the following devicetree (refer to
Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt):
:
syscfg_pctl_a: syscfg-pctl-a@10005000 {
compatible = "mediatek,mt8135-pctl-a-syscfg", "syscon";
reg = <0 0x10005000 0 0x1000>;
};

syscfg_pctl_b: syscfg-pctl-b@1020c020 {
compatible = "mediatek,mt8135-pctl-b-syscfg", "syscon";
reg = <0 0x1020C020 0 0x1000>;
};

pinctrl@1c20800 {
compatible = "mediatek,mt8135-pinctrl";
mediatek,pctl-regmap = <&syscfg_pctl_a &syscfg_pctl_b>;


and have following code in pinctrl-mtk-common.c:
node = of_parse_phandle(np, "mediatek,pctl-regmap", 0);
node = of_parse_phandle(np, "mediatek,pctl-regmap", 1)

[PATCH 1/1] pinctrl: Add alternative way for specifying register bases

2019-04-11 Thread Light Hsieh
The orginal PINCTRL_MTK_PARIS/PINCTRL_MTK_MOORE need more effort for
specifying register bases when porting platform driver:
1. Write mt_pinctrl_register_base_name[] array in pinctrl-mt.c
   to specify names of register bases, for exmaple:

static const char * const mt6765_pinctrl_register_base_names[] = {
"iocfg0", "iocfg1", "iocfg2", "iocfg3", "iocfg4", "iocfg5",
"iocfg6", "iocfg7",
};
2. Write reg = <...>, ..., <...>; in mt.dts to specify register
   bases. Each member of reg contain address range cloned from
   pre-generated devicetree node.
3. Write reg-names = "...", ..., "..."; in mt.dts to specify
   names of register bases. The sequence of names in reg-names shall match
   sequence of names that specified in pinctrl-mt.c.
   Besides, the seqeunce of names in reg-names shall also match sequence of
   address range in reg, for exmaple:

pio: pinctrl {
compatible = "mediatek,mt6765-pinctrl";
reg = <0 0x10005000 0 0x1000>,
  <0 0x10002C00 0 0x200>,
  <0 0x10002800 0 0x200>,
  <0 0x10002A00 0 0x200>,
  <0 0x10002000 0 0x200>,
  <0 0x10002200 0 0x200>,
  <0 0x10002400 0 0x200>,
  <0 0x10002600 0 0x200>,
  <0 0x1000b000 0 0x1000>;
reg-names = "iocfg0", "iocfg1", "iocfg2", "iocfg3",
"iocfg4", "iocfg5", "iocfg6", "iocfg7",
"eint";

To reduce porting effort, this patch add an alternative way for specifying
register bases:
1. Write reg_bases = <...>, ..., <...>; and reg_base_eint = <&eint>;
   in mt.dtsi where members in reg_bases and &eint are labels for
   pre-generated devicetree nodes, for example:
pio: pinctrl {
compatible = "mediatek,mt6765-pinctrl";
reg_bases = <&gpio0>,
<&iocfg0>,
<&iocfg1>,
<&iocfg2>,
<&iocfg3>,
<&iocfg4>,
<&iocfg5>,
<&iocfg6>,
<&iocfg7>;
reg_base_eint = <&eint>;

   Since this pre-generated nodes had already specify address range,
   it is not necessary to specify address range again in pinctrl node.

Using this way, porting effort is reduced and therefore typo can occur with
less chance.

Change-Id: I55f5e328919f4f736ca4b9f8d1593e069f179637
---
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 19 +---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 62 
 2 files changed, 54 insertions(+), 27 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c 
b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index b1c3684..16b4863 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "mtk-eint.h"
 #include "pinctrl-mtk-common-v2.h"
@@ -310,7 +311,7 @@ static int mtk_xt_set_gpio_as_eint(void *data, unsigned 
long eint_n)
 
 int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
 {
-   struct device_node *np = pdev->dev.of_node;
+   struct device_node *np = pdev->dev.of_node, *node;
struct resource *res;
 
if (!IS_ENABLED(CONFIG_EINT_MTK))
@@ -323,13 +324,19 @@ int mtk_build_eint(struct mtk_pinctrl *hw, struct 
platform_device *pdev)
if (!hw->eint)
return -ENOMEM;
 
-   res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "eint");
-   if (!res) {
-   dev_err(&pdev->dev, "Unable to get eint resource\n");
-   return -ENODEV;
+   node = of_parse_phandle(np, "reg_base_eint", 0);
+   if (node) {
+   hw->eint->base = of_iomap(node, 0);
+   } else {
+   res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+   "eint");
+   if (!res) {
+   dev_err(&pdev->dev, "Unable to get eint resource\n");
+   return -ENODEV;
+   }
+   hw->eint->base = devm_ioremap_resource(&pdev->dev, res);
}
 
-   hw->eint->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(hw->eint->base))
return PTR_ERR(hw->eint->base);
 
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c 
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index b59e108..8ddb995 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -9,6 +9,7 @@
  *Hongzhou.Yang 
  */
 
+#include 
 #include 
 #include 
 #include "pinctrl-paris.h"
@@ -815,10 +816,11 @@ static int mtk_pctrl_build_state(struct platform_device 
*pdev)
 int mtk_paris_pinctrl_

Re: [PATCH] pinctrl: Add kernel config PINCTRL_MTK_V2

2019-04-11 Thread Light Hsieh
Dear reviewer,

The points of  Sean are right. Please forget this patch proposal.


On Thu, 2019-04-11 at 15:04 -0700, Sean Wang wrote:
> Hi, Light
> 
> On Thu, Apr 11, 2019 at 2:32 AM Light Hsieh  wrote:
> >
> > Since no single Mediatek chip use code for PINCTRL_MTK and code for
> > PINCTRL_MTK_MOORE/PINCTRL_MTK_PARIS simultaneously, it is better to use
> > different config to determine if related code will be built or not on
> > building non-generic kernel.
> >
> > Add kernel config PINCTRL_MTK_V2 selected by either PINCTRL_MTK_MOORE
> > or PINCTRL_MTK_PARIS.
> > Use PINCTRL_MTK and PINCTRL_MTK_V2 to control building of
> > drivers/pinctrl/medaitek/.
> > Remove selection of EINT_MTK from PINCTRL_MTK since code for EINT_MTK is
> > only related to PINCTRL_MTK_MOORE/PINCTRL_MTK_PARIS, i.e. PINCTL_MTK_V2.
> >
> 
> PINCTRL_MTK also depends on EINT_MTK such as the symbol
> mtk_eint_do_init, it is a commonlibrary for the two kinds of the
> pinctrl core.
> 

Yes, you are right. 
It is my fault that I don't see some mtk_eint_* functions originally in
pinctrl-mtk-common.c had been moved to mtk-eint.c since kernel-4.18 and
now pinctrl-mtk-common.c depends on mtk-eint.c.

> > ---
> >  drivers/pinctrl/Makefile |  3 ++-
> >  drivers/pinctrl/mediatek/Kconfig | 15 ---
> >  2 files changed, 14 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> > index 712184b..fcee0e0 100644
> > --- a/drivers/pinctrl/Makefile
> > +++ b/drivers/pinctrl/Makefile
> > @@ -65,6 +65,7 @@ obj-$(CONFIG_PINCTRL_SUNXI)   += sunxi/
> >  obj-y  += ti/
> >  obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
> >  obj-$(CONFIG_ARCH_VT8500)  += vt8500/
> > -obj-y  += mediatek/
> > +obj-$(CONFIG_PINCTRL_MTK)  += mediatek/
> > +obj-$(CONFIG_PINCTRL_MTK_V2)   += mediatek/
> 
> I would think it is good if deciding V1 or not should be done inside
> the vendor directory and the change also would cause COMPILE_TEST not
> be applied to

Agree.

> >  obj-$(CONFIG_PINCTRL_ZX)   += zte/
> >  obj-y  += cirrus/
> > diff --git a/drivers/pinctrl/mediatek/Kconfig 
> > b/drivers/pinctrl/mediatek/Kconfig
> > index a005cbc..5e26462 100644
> > --- a/drivers/pinctrl/mediatek/Kconfig
> > +++ b/drivers/pinctrl/mediatek/Kconfig
> > @@ -2,10 +2,15 @@ menu "MediaTek pinctrl drivers"
> > depends on ARCH_MEDIATEK || COMPILE_TEST
> >
> >  config EINT_MTK
> > -   bool "MediaTek External Interrupt Support"
> > -   depends on PINCTRL_MTK || PINCTRL_MTK_MOORE || PINCTRL_MTK_PARIS || 
> > COMPILE_TEST
> > +   bool "MediaTek External Interrupt driver that is based on 
> > PINCTRL_MTK_V2"
> > +   depends on PINCTRL_MTK_MOORE || PINCTRL_MTK_PARIS || COMPILE_TEST
> > select GPIOLIB
> > select IRQ_DOMAIN
> > +   help
> > + Say yes here to enable support for MediaTek External Interrupt
> > + (EINT) driver based on PINCTRL_MTK version 2.
> > + This driver is combined with MediaTek Pinctrl driver version 2
> > + so PINCTRL_MTK_V2 shall be set first.
> >
> >  config PINCTRL_MTK
> > bool
> > @@ -13,9 +18,11 @@ config PINCTRL_MTK
> > select PINMUX
> > select GENERIC_PINCONF
> > select GPIOLIB
> > -   select EINT_MTK
> > select OF_GPIO
> >
> > +config PINCTRL_MTK_V2
> > +   bool "MediaTek Pinctrl Support V2"
> > +
> >  config PINCTRL_MTK_MOORE
> > bool
> > depends on OF
> > @@ -24,6 +31,7 @@ config PINCTRL_MTK_MOORE
> > select GENERIC_PINMUX_FUNCTIONS
> > select GPIOLIB
> > select OF_GPIO
> > +   select PINCTRL_MTK_V2
> >
> >  config PINCTRL_MTK_PARIS
> > bool
> > @@ -33,6 +41,7 @@ config PINCTRL_MTK_PARIS
> > select GPIOLIB
> > select EINT_MTK
> > select OF_GPIO
> > +   select PINCTRL_MTK_V2
> >
> >  # For ARMv7 SoCs
> >  config PINCTRL_MT2701
> > --
> > 1.8.1.1.dirty
> >




[PATCH] pinctrl: Add kernel config PINCTRL_MTK_V2

2019-04-11 Thread Light Hsieh
Since no single Mediatek chip use code for PINCTRL_MTK and code for
PINCTRL_MTK_MOORE/PINCTRL_MTK_PARIS simultaneously, it is better to use
different config to determine if related code will be built or not on
building non-generic kernel.

Add kernel config PINCTRL_MTK_V2 selected by either PINCTRL_MTK_MOORE
or PINCTRL_MTK_PARIS.
Use PINCTRL_MTK and PINCTRL_MTK_V2 to control building of
drivers/pinctrl/medaitek/.
Remove selection of EINT_MTK from PINCTRL_MTK since code for EINT_MTK is
only related to PINCTRL_MTK_MOORE/PINCTRL_MTK_PARIS, i.e. PINCTL_MTK_V2.

---
 drivers/pinctrl/Makefile |  3 ++-
 drivers/pinctrl/mediatek/Kconfig | 15 ---
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 712184b..fcee0e0 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_PINCTRL_SUNXI)   += sunxi/
 obj-y  += ti/
 obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
 obj-$(CONFIG_ARCH_VT8500)  += vt8500/
-obj-y  += mediatek/
+obj-$(CONFIG_PINCTRL_MTK)  += mediatek/
+obj-$(CONFIG_PINCTRL_MTK_V2)   += mediatek/
 obj-$(CONFIG_PINCTRL_ZX)   += zte/
 obj-y  += cirrus/
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index a005cbc..5e26462 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -2,10 +2,15 @@ menu "MediaTek pinctrl drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
 
 config EINT_MTK
-   bool "MediaTek External Interrupt Support"
-   depends on PINCTRL_MTK || PINCTRL_MTK_MOORE || PINCTRL_MTK_PARIS || 
COMPILE_TEST
+   bool "MediaTek External Interrupt driver that is based on 
PINCTRL_MTK_V2"
+   depends on PINCTRL_MTK_MOORE || PINCTRL_MTK_PARIS || COMPILE_TEST
select GPIOLIB
select IRQ_DOMAIN
+   help
+ Say yes here to enable support for MediaTek External Interrupt
+ (EINT) driver based on PINCTRL_MTK version 2.
+ This driver is combined with MediaTek Pinctrl driver version 2
+ so PINCTRL_MTK_V2 shall be set first.
 
 config PINCTRL_MTK
bool
@@ -13,9 +18,11 @@ config PINCTRL_MTK
select PINMUX
select GENERIC_PINCONF
select GPIOLIB
-   select EINT_MTK
select OF_GPIO
 
+config PINCTRL_MTK_V2
+   bool "MediaTek Pinctrl Support V2"
+
 config PINCTRL_MTK_MOORE
bool
depends on OF
@@ -24,6 +31,7 @@ config PINCTRL_MTK_MOORE
select GENERIC_PINMUX_FUNCTIONS
select GPIOLIB
select OF_GPIO
+   select PINCTRL_MTK_V2
 
 config PINCTRL_MTK_PARIS
bool
@@ -33,6 +41,7 @@ config PINCTRL_MTK_PARIS
select GPIOLIB
select EINT_MTK
select OF_GPIO
+   select PINCTRL_MTK_V2
 
 # For ARMv7 SoCs
 config PINCTRL_MT2701
-- 
1.8.1.1.dirty