pinctrl: mediatek: Add support for pin configuration dump via debugfs.
authorLight Hsieh <light.hsieh@mediatek.com>
Wed, 22 Jan 2020 06:53:14 +0000 (14:53 +0800)
committerLinus Walleij <linus.walleij@linaro.org>
Fri, 14 Feb 2020 10:38:26 +0000 (11:38 +0100)
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.

Signed-off-by: Light Hsieh <light.hsieh@mediatek.com>
Link: https://lore.kernel.org/r/1579675994-7001-6-git-send-email-light.hsieh@mediatek.com
Acked-by: Sean Wang <sean.wang@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/mediatek/pinctrl-paris.c
drivers/pinctrl/mediatek/pinctrl-paris.h

index 115ebc1..83bf29c 100644 (file)
@@ -539,12 +539,120 @@ static int mtk_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
        return 0;
 }
 
+static 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;
+}
+
+#define mtk_pctrl_get_pinmux(hw, gpio)                 \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_MODE)
+
+#define mtk_pctrl_get_direction(hw, gpio)              \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DIR)
+
+#define mtk_pctrl_get_out(hw, gpio)                    \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DO)
+
+#define mtk_pctrl_get_in(hw, gpio)                     \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DI)
+
+#define mtk_pctrl_get_smt(hw, gpio)                    \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_SMT)
+
+#define mtk_pctrl_get_ies(hw, gpio)                    \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_IES)
+
+#define mtk_pctrl_get_driving(hw, gpio)                        \
+       mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DRV)
+
+ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
+       unsigned int gpio, char *buf, unsigned int bufLen)
+{
+       int pinmux, pullup, pullen, len = 0, r1 = -1, r0 = -1;
+       const struct mtk_pin_desc *desc;
+
+       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)
@@ -641,6 +749,7 @@ static const struct pinconf_ops mtk_confops = {
        .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 = {
index 3d43771..afb7650 100644 (file)
@@ -60,6 +60,9 @@
 int mtk_paris_pinctrl_probe(struct platform_device *pdev,
                            const struct mtk_pin_soc *soc);
 
+ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
+       unsigned int gpio, char *buf, unsigned int bufLen);
+
 extern const struct dev_pm_ops mtk_paris_pinctrl_pm_ops;
 
 #endif /* __PINCTRL_PARIS_H */