On MT8365, the SET/CLR of the mode is broken and some pin modes won't be set correctly. Add a quirk for such SoCs, so that instead of using the SET/CLR register use the main R/W register to read/update/write the modes. Signed-off-by: Fabien Parent <fparent@xxxxxxxxxxxx> --- drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 46 ++++++++++++------- drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 3 ++ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c index f25b3e09386b..156627d9c552 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c @@ -330,23 +330,37 @@ static int mtk_pconf_set_pull_select(struct mtk_pinctrl *pctl, return -EINVAL; } - bit = BIT(pin & pctl->devdata->mode_mask); - if (enable) - reg_pullen = SET_ADDR(mtk_get_port(pctl, pin) + - pctl->devdata->pullen_offset, pctl); - else - reg_pullen = CLR_ADDR(mtk_get_port(pctl, pin) + - pctl->devdata->pullen_offset, pctl); - - if (isup) - reg_pullsel = SET_ADDR(mtk_get_port(pctl, pin) + - pctl->devdata->pullsel_offset, pctl); - else - reg_pullsel = CLR_ADDR(mtk_get_port(pctl, pin) + - pctl->devdata->pullsel_offset, pctl); + if (pctl->devdata->quirks & MTK_PINCTRL_MODE_SET_CLR_BROKEN) { + bit = pin & pctl->devdata->mode_mask; + reg_pullen = mtk_get_port(pctl, pin) + + pctl->devdata->pullen_offset; + reg_pullsel = mtk_get_port(pctl, pin) + + pctl->devdata->pullsel_offset; + + regmap_update_bits(mtk_get_regmap(pctl, pin), reg_pullen, + BIT(bit), enable << bit); + regmap_update_bits(mtk_get_regmap(pctl, pin), reg_pullsel, + BIT(bit), isup << bit); + } else { + bit = BIT(pin & pctl->devdata->mode_mask); + if (enable) + reg_pullen = SET_ADDR(mtk_get_port(pctl, pin) + + pctl->devdata->pullen_offset, pctl); + else + reg_pullen = CLR_ADDR(mtk_get_port(pctl, pin) + + pctl->devdata->pullen_offset, pctl); + + if (isup) + reg_pullsel = SET_ADDR(mtk_get_port(pctl, pin) + + pctl->devdata->pullsel_offset, pctl); + else + reg_pullsel = CLR_ADDR(mtk_get_port(pctl, pin) + + pctl->devdata->pullsel_offset, pctl); + + regmap_write(mtk_get_regmap(pctl, pin), reg_pullen, bit); + regmap_write(mtk_get_regmap(pctl, pin), reg_pullsel, bit); + } - regmap_write(mtk_get_regmap(pctl, pin), reg_pullen, bit); - regmap_write(mtk_get_regmap(pctl, pin), reg_pullsel, bit); return 0; } diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h index 6fe8564334c9..cc0dce8818c6 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h @@ -22,6 +22,8 @@ #define MTK_PINCTRL_NOT_SUPPORT (0xffff) +#define MTK_PINCTRL_MODE_SET_CLR_BROKEN BIT(0) + struct mtk_desc_function { const char *name; unsigned char muxval; @@ -271,6 +273,7 @@ struct mtk_pinctrl_devdata { unsigned int mode_mask; unsigned int mode_per_reg; unsigned int mode_shf; + unsigned long quirks; }; struct mtk_pinctrl { -- 2.36.1