From: Light Hsieh <[email protected]>
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. Improve mtk_hw_pin_field_lookup()
2.1 Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
search.
2.2 Correct message after the following check fail:
if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
rc = &hw->soc->reg_cal[field];
The original message is:
"Not support field %d for pin %d (%s)\n"
However, the check is on soc chip level, not on pin level yet.
So the message is corrected as:
"Not support field %d for this soc\n"
Signed-off-by: Light Hsieh <[email protected]>
---
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 27 ++++++++++++++++++------
drivers/pinctrl/mediatek/pinctrl-paris.c | 25 ++++++++++++++++++++++
2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 20e1c89..d63e05e 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -68,32 +68,44 @@ 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;
+ int start = 0, end, check;
+ bool found = false;
u32 bits;
if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
rc = &hw->soc->reg_cal[field];
} else {
dev_dbg(hw->dev,
- "Not support field %d for pin %d (%s)\n",
- field, desc->number, desc->name);
+ "Not support field %d for this soc\n", field);
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 = true;
+ break;
+ } else if (start == end)
break;
- c++;
+ 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 *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
From: Light Hsieh <[email protected]>
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 <[email protected]>
---
drivers/pinctrl/mediatek/pinctrl-paris.c | 109 +++++++++++++++++++++++++++++++
drivers/pinctrl/mediatek/pinctrl-paris.h | 3 +
2 files changed, 112 insertions(+)
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 115ebc1..83bf29c 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -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 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..afb7650 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.h
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.h
@@ -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 */
--
1.8.1.1.dirty
From: Light Hsieh <[email protected]>
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 = <MTK_PUPD_SET_R1R0_00>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
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 increase porting
effort to MediaTek's customer that had already used PINCTRL_MTK version.
Besides, if customers are not aware 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 adds 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 implementation had better leave
interface unchanged.
Signed-off-by: Light Hsieh <[email protected]>
---
drivers/pinctrl/mediatek/pinctrl-mt6765.c | 6 +-
drivers/pinctrl/mediatek/pinctrl-mt8183.c | 6 +-
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 221 +++++++++++++++++++++++
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 11 ++
drivers/pinctrl/mediatek/pinctrl-paris.c | 49 +++--
5 files changed, 265 insertions(+), 28 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index 7fae397..905dae8c 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_raw,
.drive_get = mtk_pinconf_drive_get_raw,
.adv_pull_get = mtk_pinconf_adv_pull_get,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8183.c b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
index 4eca818..6031833 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8183.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
@@ -556,10 +556,8 @@
.gpio_m = 0,
.base_names = mt8183_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names),
- .bias_disable_set = mtk_pinconf_bias_disable_set_rev1,
- .bias_disable_get = mtk_pinconf_bias_disable_get_rev1,
- .bias_set = mtk_pinconf_bias_set_rev1,
- .bias_get = mtk_pinconf_bias_get_rev1,
+ .bias_set_combo = mtk_pinconf_bias_set_combo,
+ .bias_get_combo = mtk_pinconf_bias_get_combo,
.drive_set = mtk_pinconf_drive_set_rev1,
.drive_get = mtk_pinconf_drive_get_rev1,
.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 2247eae..1da9425 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -6,6 +6,7 @@
*
*/
+#include <dt-bindings/pinctrl/mt65xx.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
@@ -517,6 +518,226 @@ 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
+ */
+static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 pullup, u32 arg)
+{
+ int err, pu, pd;
+
+ 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;
+ pd = 1;
+ } else {
+ err = -EINVAL;
+ goto out;
+ }
+
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
+ if (err)
+ goto out;
+
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
+
+out:
+ return err;
+}
+
+static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 pullup, u32 arg)
+{
+ int err, enable;
+
+ if (arg == MTK_DISABLE)
+ enable = 0;
+ else if (arg == MTK_ENABLE)
+ enable = 1;
+ else {
+ err = -EINVAL;
+ goto out;
+ }
+
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
+ if (err)
+ goto out;
+
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
+
+out:
+ return err;
+}
+
+static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 pullup, u32 arg)
+{
+ int err, r0, r1;
+
+ if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) {
+ pullup = 0;
+ r0 = 0;
+ r1 = 0;
+ } else if (arg == MTK_PUPD_SET_R1R0_01) {
+ r0 = 1;
+ r1 = 0;
+ } else if (arg == MTK_PUPD_SET_R1R0_10) {
+ r0 = 0;
+ r1 = 1;
+ } else if (arg == MTK_PUPD_SET_R1R0_11) {
+ r0 = 1;
+ r1 = 1;
+ } else {
+ err = -EINVAL;
+ goto out;
+ }
+
+ /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup);
+ if (err)
+ goto out;
+
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0);
+ if (err)
+ goto out;
+
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1);
+
+out:
+ return err;
+}
+
+static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 *pullup, u32 *enable)
+{
+ int err, pu, pd;
+
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
+ if (err)
+ goto out;
+
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
+ if (err)
+ goto out;
+
+ if (pu == 0 && pd == 0) {
+ *pullup = 0;
+ *enable = MTK_DISABLE;
+ } else if (pu == 1 && pd == 0) {
+ *pullup = 1;
+ *enable = MTK_ENABLE;
+ } else if (pu == 0 && pd == 1) {
+ *pullup = 0;
+ *enable = MTK_ENABLE;
+ } else
+ err = -EINVAL;
+
+out:
+ return err;
+}
+
+static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 *pullup, u32 *enable)
+{
+ int err;
+
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
+ if (err)
+ goto out;
+
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
+
+out:
+ return err;
+}
+
+static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 *pullup, u32 *enable)
+{
+ int err, r0, r1;
+
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup);
+ if (err)
+ goto out;
+ /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
+ *pullup = !(*pullup);
+
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0);
+ if (err)
+ goto out;
+
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1);
+ if (err)
+ goto out;
+
+ if ((r1 == 0) && (r0 == 0))
+ *enable = MTK_PUPD_SET_R1R0_00;
+ else if ((r1 == 0) && (r0 == 1))
+ *enable = MTK_PUPD_SET_R1R0_01;
+ else if ((r1 == 1) && (r0 == 0))
+ *enable = MTK_PUPD_SET_R1R0_10;
+ else if ((r1 == 1) && (r0 == 1))
+ *enable = MTK_PUPD_SET_R1R0_11;
+ else
+ err = -EINVAL;
+
+out:
+ return err;
+}
+
+int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 pullup, u32 arg)
+{
+ int err;
+
+ err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
+ if (!err)
+ goto out;
+
+ err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
+ if (!err)
+ goto out;
+
+ err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
+
+out:
+ return err;
+}
+
+int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 *pullup, u32 *enable)
+{
+ int err;
+
+ err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
+ if (!err)
+ goto out;
+
+ err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
+ if (!err)
+ goto out;
+
+ err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
+
+out:
+ return err;
+}
+
/* Revision 0 */
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 75d0e07..27df087 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -216,6 +216,11 @@ struct mtk_pin_soc {
int (*bias_get)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup, int *res);
+ int (*bias_set_combo)(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, u32 pullup, u32 arg);
+ int (*bias_get_combo)(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg);
+
int (*drive_set)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg);
int (*drive_get)(struct mtk_pinctrl *hw,
@@ -277,6 +282,12 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
int *res);
+int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 pullup, u32 enable);
+int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 *pullup, u32 *enable);
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index d09a726..115ebc1 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -78,7 +78,7 @@ 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 err, reg, ret = 1;
+ int pullup, err, reg, ret = 1;
const struct mtk_pin_desc *desc;
if (pin >= hw->soc->npins) {
@@ -89,22 +89,31 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
- if (hw->soc->bias_disable_get)
- err = hw->soc->bias_disable_get(hw, desc, &ret);
- else
- err = -ENOTSUPP;
- break;
case PIN_CONFIG_BIAS_PULL_UP:
- if (hw->soc->bias_get)
- err = hw->soc->bias_get(hw, desc, 1, &ret);
- else
- err = -ENOTSUPP;
- break;
case PIN_CONFIG_BIAS_PULL_DOWN:
- if (hw->soc->bias_get)
- err = hw->soc->bias_get(hw, desc, 0, &ret);
- else
+ if (hw->soc->bias_get_combo) {
+ err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
+ if (err)
+ goto out;
+ if (param == PIN_CONFIG_BIAS_DISABLE) {
+ if (ret == MTK_PUPD_SET_R1R0_00)
+ ret = MTK_DISABLE;
+ } else if (param == PIN_CONFIG_BIAS_PULL_UP) {
+ /* When desire to get pull-up value, return
+ * error if current setting is pull-down
+ */
+ if (!pullup)
+ err = -EINVAL;
+ } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) {
+ /* When desire to get pull-down value, return
+ * error if current setting is pull-up
+ */
+ if (pullup)
+ err = -EINVAL;
+ }
+ } else {
err = -ENOTSUPP;
+ }
break;
case PIN_CONFIG_SLEW_RATE:
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
@@ -196,20 +205,20 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
switch ((u32)param) {
case PIN_CONFIG_BIAS_DISABLE:
- if (hw->soc->bias_disable_set)
- err = hw->soc->bias_disable_set(hw, desc);
+ if (hw->soc->bias_set_combo)
+ err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
else
err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_UP:
- if (hw->soc->bias_set)
- err = hw->soc->bias_set(hw, desc, 1);
+ if (hw->soc->bias_set_combo)
+ err = hw->soc->bias_set_combo(hw, desc, 1, arg);
else
err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
- if (hw->soc->bias_set)
- err = hw->soc->bias_set(hw, desc, 0);
+ if (hw->soc->bias_set_combo)
+ err = hw->soc->bias_set_combo(hw, desc, 0, arg);
else
err = -ENOTSUPP;
break;
--
1.8.1.1.dirty
From: Light Hsieh <[email protected]>
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.
Signed-off-by: Light Hsieh <[email protected]>
---
drivers/pinctrl/mediatek/pinctrl-paris.c | 40 ++++++++++++--------------------
1 file changed, 15 insertions(+), 25 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 2f07500..d09a726 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -78,7 +78,7 @@ 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) {
@@ -107,17 +107,11 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
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)
goto out;
/* CONFIG Current direction return value
@@ -128,20 +122,22 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
* input 1 (= reverse HW value)
*/
if (param == PIN_CONFIG_INPUT_ENABLE)
- val = !val;
+ ret = !ret;
break;
case PIN_CONFIG_INPUT_SCHMITT_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;
-
- err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2);
- if (err)
- return err;
+ goto out;
+ /* return error when in output mode
+ * because schmitt trigger only work in input mode
+ */
+ if (ret) {
+ err = -EINVAL;
+ goto out;
+ }
- if (val || !val2)
- return -EINVAL;
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
@@ -154,13 +150,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
case MTK_PIN_CONFIG_RDSEL:
reg = (param == MTK_PIN_CONFIG_TDSEL) ?
PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
-
- err = mtk_hw_get_value(hw, desc, reg, &val);
- if (err)
- return err;
-
- ret = val;
-
+ err = mtk_hw_get_value(hw, desc, reg, &ret);
break;
case MTK_PIN_CONFIG_PU_ADV:
case MTK_PIN_CONFIG_PD_ADV:
--
1.8.1.1.dirty
From: Light Hsieh <[email protected]>
MediaTek's smartphone 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 practical for
MediaTek's smartphone usage.
Signed-off-by: Light Hsieh <[email protected]>
---
drivers/pinctrl/mediatek/pinctrl-mt6765.c | 4 ++--
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 12 ++++++++++++
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 5 +++++
3 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index 32451e8..1212264 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_raw,
+ .drive_get = mtk_pinconf_drive_get_raw,
.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 d63e05e..2247eae 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -608,6 +608,18 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
return 0;
}
+int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, u32 arg)
+{
+ return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
+}
+
+int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, int *val)
+{
+ return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, 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-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 1b7da42..75d0e07 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_raw(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, u32 arg);
+int mtk_pinconf_drive_get_raw(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);
--
1.8.1.1.dirty
From: Light Hsieh <[email protected]>
1.Refine mtk_pinconf_get():
Use only one occurrence of return at end of this function.
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 -
2.2.1
Regard all non-zero setting value as enable, instead of always enable.
2.2.2
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.
Signed-off-by: Light Hsieh <[email protected]>
---
drivers/pinctrl/mediatek/pinctrl-mt6765.c | 1 -
drivers/pinctrl/mediatek/pinctrl-mt8183.c | 1 -
drivers/pinctrl/mediatek/pinctrl-paris.c | 171 ++++++++++++------------------
3 files changed, 65 insertions(+), 108 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index 1212264..7fae397 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-mt8183.c b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
index 9a74d50..4eca818 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8183.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
@@ -554,7 +554,6 @@
.ngrps = ARRAY_SIZE(mtk_pins_mt8183),
.eint_hw = &mt8183_eint_hw,
.gpio_m = 0,
- .ies_present = true,
.base_names = mt8183_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set_rev1,
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 3e13ae7..2f07500 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -81,37 +81,30 @@ 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;
+ 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);
@@ -126,12 +119,16 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
case PIN_CONFIG_OUTPUT_ENABLE:
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
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)
+ * input 0 (= HW value)
+ * INPUT_ENABLE output 0 (= reverse HW value)
+ * input 1 (= reverse HW value)
+ */
+ if (param == PIN_CONFIG_INPUT_ENABLE)
+ val = !val;
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
@@ -148,13 +145,10 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
break;
case PIN_CONFIG_DRIVE_STRENGTH:
- if (hw->soc->drive_get) {
+ if (hw->soc->drive_get)
err = hw->soc->drive_get(hw, desc, &ret);
- if (err)
- return err;
- } else {
+ else
err = -ENOTSUPP;
- }
break;
case MTK_PIN_CONFIG_TDSEL:
case MTK_PIN_CONFIG_RDSEL:
@@ -175,28 +169,24 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
pullup = param == MTK_PIN_CONFIG_PU_ADV;
err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ } else
+ err = -ENOTSUPP;
break;
case MTK_PIN_CONFIG_DRV_ADV:
- if (hw->soc->adv_drive_get) {
+ if (hw->soc->adv_drive_get)
err = hw->soc->adv_drive_get(hw, desc, &ret);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
default:
- return -ENOTSUPP;
+ err = -ENOTSUPP;
}
- *config = pinconf_to_config_packed(param, ret);
+out:
+ if (!err)
+ *config = pinconf_to_config_packed(param, ret);
- return 0;
+ return err;
}
static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
@@ -216,60 +206,47 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
switch ((u32)param) {
case PIN_CONFIG_BIAS_DISABLE:
- if (hw->soc->bias_disable_set) {
+ if (hw->soc->bias_disable_set)
err = hw->soc->bias_disable_set(hw, desc);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_UP:
- if (hw->soc->bias_set) {
+ if (hw->soc->bias_set)
err = hw->soc->bias_set(hw, desc, 1);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
- if (hw->soc->bias_set) {
+ if (hw->soc->bias_set)
err = hw->soc->bias_set(hw, desc, 0);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
case PIN_CONFIG_OUTPUT_ENABLE:
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
MTK_DISABLE);
- if (err)
+ /* Keep set direction to consider the case that a GPIO pin
+ * does not have SMT control
+ */
+ if (err != -ENOTSUPP)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
MTK_OUTPUT);
- if (err)
- goto err;
break;
case PIN_CONFIG_INPUT_ENABLE:
- if (hw->soc->ies_present) {
- mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES,
- MTK_ENABLE);
- }
+ /* regard all non-zero value as enable */
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
+ if (err)
+ goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
MTK_INPUT);
- if (err)
- goto err;
break;
case PIN_CONFIG_SLEW_RATE:
- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR,
- arg);
- if (err)
- goto err;
-
+ /* regard all non-zero value as enable */
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, !!arg);
break;
case PIN_CONFIG_OUTPUT:
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
@@ -279,41 +256,29 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,
arg);
- if (err)
- goto err;
break;
+ case PIN_CONFIG_INPUT_SCHMITT:
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
/* arg = 1: Input mode & SMT enable ;
* arg = 0: Output mode & SMT disable
*/
- arg = arg ? 2 : 1;
- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
- arg & 1);
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg);
if (err)
goto err;
- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
- !!(arg & 2));
- if (err)
- goto err;
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
- if (hw->soc->drive_set) {
+ if (hw->soc->drive_set)
err = hw->soc->drive_set(hw, desc, arg);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
case MTK_PIN_CONFIG_TDSEL:
case MTK_PIN_CONFIG_RDSEL:
reg = (param == MTK_PIN_CONFIG_TDSEL) ?
PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
-
err = mtk_hw_set_value(hw, desc, reg, arg);
- if (err)
- goto err;
break;
case MTK_PIN_CONFIG_PU_ADV:
case MTK_PIN_CONFIG_PD_ADV:
@@ -323,20 +288,14 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
pullup = param == MTK_PIN_CONFIG_PU_ADV;
err = hw->soc->adv_pull_set(hw, desc, pullup,
arg);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ } else
+ err = -ENOTSUPP;
break;
case MTK_PIN_CONFIG_DRV_ADV:
- if (hw->soc->adv_drive_set) {
+ if (hw->soc->adv_drive_set)
err = hw->soc->adv_drive_set(hw, desc, arg);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
default:
err = -ENOTSUPP;
--
1.8.1.1.dirty
Dear Sean,
V8 uploaded according to your review comment on V7.
Please take time to review. Thanks.
Light
On Wed, 2020-01-22 at 14:53 +0800, [email protected] wrote:
> From: Light Hsieh <[email protected]>
>
> 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. Improve mtk_hw_pin_field_lookup()
> 2.1 Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
> search.
> 2.2 Correct message after the following check fail:
> if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
> rc = &hw->soc->reg_cal[field];
> The original message is:
> "Not support field %d for pin %d (%s)\n"
> However, the check is on soc chip level, not on pin level yet.
> So the message is corrected as:
> "Not support field %d for this soc\n"
>
> Signed-off-by: Light Hsieh <[email protected]>
> ---
> drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 27 ++++++++++++++++++------
> drivers/pinctrl/mediatek/pinctrl-paris.c | 25 ++++++++++++++++++++++
> 2 files changed, 46 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> index 20e1c89..d63e05e 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> @@ -68,32 +68,44 @@ 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;
> + int start = 0, end, check;
> + bool found = false;
> u32 bits;
>
> if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
> rc = &hw->soc->reg_cal[field];
> } else {
> dev_dbg(hw->dev,
> - "Not support field %d for pin %d (%s)\n",
> - field, desc->number, desc->name);
> + "Not support field %d for this soc\n", field);
> 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 = true;
> + break;
> + } else if (start == end)
> break;
> - c++;
> + 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 *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);
On Tue, Jan 21, 2020 at 10:53 PM <[email protected]> wrote:
>
> From: Light Hsieh <[email protected]>
>
> 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. Improve mtk_hw_pin_field_lookup()
> 2.1 Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
> search.
> 2.2 Correct message after the following check fail:
> if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
> rc = &hw->soc->reg_cal[field];
> The original message is:
> "Not support field %d for pin %d (%s)\n"
> However, the check is on soc chip level, not on pin level yet.
> So the message is corrected as:
> "Not support field %d for this soc\n"
>
> Signed-off-by: Light Hsieh <[email protected]>
Acked-by: Sean Wang <[email protected]>
> ---
> drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 27 ++++++++++++++++++------
> drivers/pinctrl/mediatek/pinctrl-paris.c | 25 ++++++++++++++++++++++
> 2 files changed, 46 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> index 20e1c89..d63e05e 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> @@ -68,32 +68,44 @@ 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;
> + int start = 0, end, check;
> + bool found = false;
> u32 bits;
>
> if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
> rc = &hw->soc->reg_cal[field];
> } else {
> dev_dbg(hw->dev,
> - "Not support field %d for pin %d (%s)\n",
> - field, desc->number, desc->name);
> + "Not support field %d for this soc\n", field);
> 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 = true;
> + break;
> + } else if (start == end)
> break;
> - c++;
> + 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 *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
On Tue, Jan 21, 2020 at 10:53 PM <[email protected]> wrote:
>
> From: Light Hsieh <[email protected]>
>
> MediaTek's smartphone 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 practical for
> MediaTek's smartphone usage.
>
> Signed-off-by: Light Hsieh <[email protected]>
Acked-by: Sean Wang <[email protected]>
> ---
> drivers/pinctrl/mediatek/pinctrl-mt6765.c | 4 ++--
> drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 12 ++++++++++++
> drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 5 +++++
> 3 files changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
> index 32451e8..1212264 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_raw,
> + .drive_get = mtk_pinconf_drive_get_raw,
> .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 d63e05e..2247eae 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> @@ -608,6 +608,18 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
> return 0;
> }
>
> +int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc, u32 arg)
> +{
> + return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
> +}
> +
> +int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc, int *val)
> +{
> + return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, 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-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
> index 1b7da42..75d0e07 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_raw(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc, u32 arg);
> +int mtk_pinconf_drive_get_raw(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);
> --
> 1.8.1.1.dirty
On Tue, Jan 21, 2020 at 10:53 PM <[email protected]> wrote:
>
> From: Light Hsieh <[email protected]>
>
> 1.Refine mtk_pinconf_get():
> Use only one occurrence of return at end of this function.
>
> 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 -
> 2.2.1
> Regard all non-zero setting value as enable, instead of always enable.
> 2.2.2
> 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.
>
> Signed-off-by: Light Hsieh <[email protected]>
Acked-by: Sean Wang <[email protected]>
> ---
> drivers/pinctrl/mediatek/pinctrl-mt6765.c | 1 -
> drivers/pinctrl/mediatek/pinctrl-mt8183.c | 1 -
> drivers/pinctrl/mediatek/pinctrl-paris.c | 171 ++++++++++++------------------
> 3 files changed, 65 insertions(+), 108 deletions(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
> index 1212264..7fae397 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-mt8183.c b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
> index 9a74d50..4eca818 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mt8183.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
> @@ -554,7 +554,6 @@
> .ngrps = ARRAY_SIZE(mtk_pins_mt8183),
> .eint_hw = &mt8183_eint_hw,
> .gpio_m = 0,
> - .ies_present = true,
> .base_names = mt8183_pinctrl_register_base_names,
> .nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names),
> .bias_disable_set = mtk_pinconf_bias_disable_set_rev1,
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 3e13ae7..2f07500 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -81,37 +81,30 @@ 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;
> + 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);
> @@ -126,12 +119,16 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
> case PIN_CONFIG_OUTPUT_ENABLE:
> err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
> 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)
> + * input 0 (= HW value)
> + * INPUT_ENABLE output 0 (= reverse HW value)
> + * input 1 (= reverse HW value)
> + */
> + if (param == PIN_CONFIG_INPUT_ENABLE)
> + val = !val;
>
> break;
> case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
> @@ -148,13 +145,10 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
>
> break;
> case PIN_CONFIG_DRIVE_STRENGTH:
> - if (hw->soc->drive_get) {
> + if (hw->soc->drive_get)
> err = hw->soc->drive_get(hw, desc, &ret);
> - if (err)
> - return err;
> - } else {
> + else
> err = -ENOTSUPP;
> - }
> break;
> case MTK_PIN_CONFIG_TDSEL:
> case MTK_PIN_CONFIG_RDSEL:
> @@ -175,28 +169,24 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
>
> pullup = param == MTK_PIN_CONFIG_PU_ADV;
> err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
> - if (err)
> - return err;
> - } else {
> - return -ENOTSUPP;
> - }
> + } else
> + err = -ENOTSUPP;
> break;
> case MTK_PIN_CONFIG_DRV_ADV:
> - if (hw->soc->adv_drive_get) {
> + if (hw->soc->adv_drive_get)
> err = hw->soc->adv_drive_get(hw, desc, &ret);
> - if (err)
> - return err;
> - } else {
> - return -ENOTSUPP;
> - }
> + else
> + err = -ENOTSUPP;
> break;
> default:
> - return -ENOTSUPP;
> + err = -ENOTSUPP;
> }
>
> - *config = pinconf_to_config_packed(param, ret);
> +out:
> + if (!err)
> + *config = pinconf_to_config_packed(param, ret);
>
> - return 0;
> + return err;
> }
>
> static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
> @@ -216,60 +206,47 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
>
> switch ((u32)param) {
> case PIN_CONFIG_BIAS_DISABLE:
> - if (hw->soc->bias_disable_set) {
> + if (hw->soc->bias_disable_set)
> err = hw->soc->bias_disable_set(hw, desc);
> - if (err)
> - return err;
> - } else {
> - return -ENOTSUPP;
> - }
> + else
> + err = -ENOTSUPP;
> break;
> case PIN_CONFIG_BIAS_PULL_UP:
> - if (hw->soc->bias_set) {
> + if (hw->soc->bias_set)
> err = hw->soc->bias_set(hw, desc, 1);
> - if (err)
> - return err;
> - } else {
> - return -ENOTSUPP;
> - }
> + else
> + err = -ENOTSUPP;
> break;
> case PIN_CONFIG_BIAS_PULL_DOWN:
> - if (hw->soc->bias_set) {
> + if (hw->soc->bias_set)
> err = hw->soc->bias_set(hw, desc, 0);
> - if (err)
> - return err;
> - } else {
> - return -ENOTSUPP;
> - }
> + else
> + err = -ENOTSUPP;
> break;
> case PIN_CONFIG_OUTPUT_ENABLE:
> err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
> MTK_DISABLE);
> - if (err)
> + /* Keep set direction to consider the case that a GPIO pin
> + * does not have SMT control
> + */
> + if (err != -ENOTSUPP)
> goto err;
>
> err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
> MTK_OUTPUT);
> - if (err)
> - goto err;
> break;
> case PIN_CONFIG_INPUT_ENABLE:
> - if (hw->soc->ies_present) {
> - mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES,
> - MTK_ENABLE);
> - }
> + /* regard all non-zero value as enable */
> + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
> + if (err)
> + goto err;
>
> err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
> MTK_INPUT);
> - if (err)
> - goto err;
> break;
> case PIN_CONFIG_SLEW_RATE:
> - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR,
> - arg);
> - if (err)
> - goto err;
> -
> + /* regard all non-zero value as enable */
> + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, !!arg);
> break;
> case PIN_CONFIG_OUTPUT:
> err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
> @@ -279,41 +256,29 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
>
> err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,
> arg);
> - if (err)
> - goto err;
> break;
> + case PIN_CONFIG_INPUT_SCHMITT:
> case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
> /* arg = 1: Input mode & SMT enable ;
> * arg = 0: Output mode & SMT disable
> */
> - arg = arg ? 2 : 1;
> - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
> - arg & 1);
> + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg);
> if (err)
> goto err;
>
> - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
> - !!(arg & 2));
> - if (err)
> - goto err;
> + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg);
> break;
> case PIN_CONFIG_DRIVE_STRENGTH:
> - if (hw->soc->drive_set) {
> + if (hw->soc->drive_set)
> err = hw->soc->drive_set(hw, desc, arg);
> - if (err)
> - return err;
> - } else {
> - return -ENOTSUPP;
> - }
> + else
> + err = -ENOTSUPP;
> break;
> case MTK_PIN_CONFIG_TDSEL:
> case MTK_PIN_CONFIG_RDSEL:
> reg = (param == MTK_PIN_CONFIG_TDSEL) ?
> PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
> -
> err = mtk_hw_set_value(hw, desc, reg, arg);
> - if (err)
> - goto err;
> break;
> case MTK_PIN_CONFIG_PU_ADV:
> case MTK_PIN_CONFIG_PD_ADV:
> @@ -323,20 +288,14 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
> pullup = param == MTK_PIN_CONFIG_PU_ADV;
> err = hw->soc->adv_pull_set(hw, desc, pullup,
> arg);
> - if (err)
> - return err;
> - } else {
> - return -ENOTSUPP;
> - }
> + } else
> + err = -ENOTSUPP;
> break;
> case MTK_PIN_CONFIG_DRV_ADV:
> - if (hw->soc->adv_drive_set) {
> + if (hw->soc->adv_drive_set)
> err = hw->soc->adv_drive_set(hw, desc, arg);
> - if (err)
> - return err;
> - } else {
> - return -ENOTSUPP;
> - }
> + else
> + err = -ENOTSUPP;
> break;
> default:
> err = -ENOTSUPP;
> --
> 1.8.1.1.dirty
On Tue, Jan 21, 2020 at 10:53 PM <[email protected]> wrote:
>
> From: Light Hsieh <[email protected]>
>
> 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 = <MTK_PUPD_SET_R1R0_00>;
> bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
> bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
> bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
> bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
> bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
> bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
> bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
>
> 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 increase porting
> effort to MediaTek's customer that had already used PINCTRL_MTK version.
> Besides, if customers are not aware 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 adds 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 implementation had better leave
> interface unchanged.
>
> Signed-off-by: Light Hsieh <[email protected]>
Acked-by: Sean Wang <[email protected]>
> ---
> drivers/pinctrl/mediatek/pinctrl-mt6765.c | 6 +-
> drivers/pinctrl/mediatek/pinctrl-mt8183.c | 6 +-
> drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 221 +++++++++++++++++++++++
> drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 11 ++
> drivers/pinctrl/mediatek/pinctrl-paris.c | 49 +++--
> 5 files changed, 265 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
> index 7fae397..905dae8c 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_raw,
> .drive_get = mtk_pinconf_drive_get_raw,
> .adv_pull_get = mtk_pinconf_adv_pull_get,
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8183.c b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
> index 4eca818..6031833 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mt8183.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
> @@ -556,10 +556,8 @@
> .gpio_m = 0,
> .base_names = mt8183_pinctrl_register_base_names,
> .nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names),
> - .bias_disable_set = mtk_pinconf_bias_disable_set_rev1,
> - .bias_disable_get = mtk_pinconf_bias_disable_get_rev1,
> - .bias_set = mtk_pinconf_bias_set_rev1,
> - .bias_get = mtk_pinconf_bias_get_rev1,
> + .bias_set_combo = mtk_pinconf_bias_set_combo,
> + .bias_get_combo = mtk_pinconf_bias_get_combo,
> .drive_set = mtk_pinconf_drive_set_rev1,
> .drive_get = mtk_pinconf_drive_get_rev1,
> .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 2247eae..1da9425 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> @@ -6,6 +6,7 @@
> *
> */
>
> +#include <dt-bindings/pinctrl/mt65xx.h>
> #include <linux/device.h>
> #include <linux/err.h>
> #include <linux/gpio/driver.h>
> @@ -517,6 +518,226 @@ 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
> + */
> +static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 pullup, u32 arg)
> +{
> + int err, pu, pd;
> +
> + 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;
> + pd = 1;
> + } else {
> + err = -EINVAL;
> + goto out;
> + }
> +
> + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
> + if (err)
> + goto out;
> +
> + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
> +
> +out:
> + return err;
> +}
> +
> +static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 pullup, u32 arg)
> +{
> + int err, enable;
> +
> + if (arg == MTK_DISABLE)
> + enable = 0;
> + else if (arg == MTK_ENABLE)
> + enable = 1;
> + else {
> + err = -EINVAL;
> + goto out;
> + }
> +
> + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
> + if (err)
> + goto out;
> +
> + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
> +
> +out:
> + return err;
> +}
> +
> +static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 pullup, u32 arg)
> +{
> + int err, r0, r1;
> +
> + if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) {
> + pullup = 0;
> + r0 = 0;
> + r1 = 0;
> + } else if (arg == MTK_PUPD_SET_R1R0_01) {
> + r0 = 1;
> + r1 = 0;
> + } else if (arg == MTK_PUPD_SET_R1R0_10) {
> + r0 = 0;
> + r1 = 1;
> + } else if (arg == MTK_PUPD_SET_R1R0_11) {
> + r0 = 1;
> + r1 = 1;
> + } else {
> + err = -EINVAL;
> + goto out;
> + }
> +
> + /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
> + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup);
> + if (err)
> + goto out;
> +
> + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0);
> + if (err)
> + goto out;
> +
> + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1);
> +
> +out:
> + return err;
> +}
> +
> +static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 *pullup, u32 *enable)
> +{
> + int err, pu, pd;
> +
> + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
> + if (err)
> + goto out;
> +
> + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
> + if (err)
> + goto out;
> +
> + if (pu == 0 && pd == 0) {
> + *pullup = 0;
> + *enable = MTK_DISABLE;
> + } else if (pu == 1 && pd == 0) {
> + *pullup = 1;
> + *enable = MTK_ENABLE;
> + } else if (pu == 0 && pd == 1) {
> + *pullup = 0;
> + *enable = MTK_ENABLE;
> + } else
> + err = -EINVAL;
> +
> +out:
> + return err;
> +}
> +
> +static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 *pullup, u32 *enable)
> +{
> + int err;
> +
> + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
> + if (err)
> + goto out;
> +
> + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
> +
> +out:
> + return err;
> +}
> +
> +static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 *pullup, u32 *enable)
> +{
> + int err, r0, r1;
> +
> + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup);
> + if (err)
> + goto out;
> + /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
> + *pullup = !(*pullup);
> +
> + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0);
> + if (err)
> + goto out;
> +
> + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1);
> + if (err)
> + goto out;
> +
> + if ((r1 == 0) && (r0 == 0))
> + *enable = MTK_PUPD_SET_R1R0_00;
> + else if ((r1 == 0) && (r0 == 1))
> + *enable = MTK_PUPD_SET_R1R0_01;
> + else if ((r1 == 1) && (r0 == 0))
> + *enable = MTK_PUPD_SET_R1R0_10;
> + else if ((r1 == 1) && (r0 == 1))
> + *enable = MTK_PUPD_SET_R1R0_11;
> + else
> + err = -EINVAL;
> +
> +out:
> + return err;
> +}
> +
> +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 pullup, u32 arg)
> +{
> + int err;
> +
> + err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
> + if (!err)
> + goto out;
> +
> + err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
> + if (!err)
> + goto out;
> +
> + err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
> +
> +out:
> + return err;
> +}
> +
> +int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 *pullup, u32 *enable)
> +{
> + int err;
> +
> + err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
> + if (!err)
> + goto out;
> +
> + err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
> + if (!err)
> + goto out;
> +
> + err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
> +
> +out:
> + return err;
> +}
> +
> /* Revision 0 */
> int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
> const struct mtk_pin_desc *desc, u32 arg)
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
> index 75d0e07..27df087 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
> @@ -216,6 +216,11 @@ struct mtk_pin_soc {
> int (*bias_get)(struct mtk_pinctrl *hw,
> const struct mtk_pin_desc *desc, bool pullup, int *res);
>
> + int (*bias_set_combo)(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc, u32 pullup, u32 arg);
> + int (*bias_get_combo)(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg);
> +
> int (*drive_set)(struct mtk_pinctrl *hw,
> const struct mtk_pin_desc *desc, u32 arg);
> int (*drive_get)(struct mtk_pinctrl *hw,
> @@ -277,6 +282,12 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
> int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
> const struct mtk_pin_desc *desc, bool pullup,
> int *res);
> +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 pullup, u32 enable);
> +int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 *pullup, u32 *enable);
>
> int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
> const struct mtk_pin_desc *desc, u32 arg);
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index d09a726..115ebc1 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -78,7 +78,7 @@ 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 err, reg, ret = 1;
> + int pullup, err, reg, ret = 1;
> const struct mtk_pin_desc *desc;
>
> if (pin >= hw->soc->npins) {
> @@ -89,22 +89,31 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
>
> switch (param) {
> case PIN_CONFIG_BIAS_DISABLE:
> - if (hw->soc->bias_disable_get)
> - err = hw->soc->bias_disable_get(hw, desc, &ret);
> - else
> - err = -ENOTSUPP;
> - break;
> case PIN_CONFIG_BIAS_PULL_UP:
> - if (hw->soc->bias_get)
> - err = hw->soc->bias_get(hw, desc, 1, &ret);
> - else
> - err = -ENOTSUPP;
> - break;
> case PIN_CONFIG_BIAS_PULL_DOWN:
> - if (hw->soc->bias_get)
> - err = hw->soc->bias_get(hw, desc, 0, &ret);
> - else
> + if (hw->soc->bias_get_combo) {
> + err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
> + if (err)
> + goto out;
> + if (param == PIN_CONFIG_BIAS_DISABLE) {
> + if (ret == MTK_PUPD_SET_R1R0_00)
> + ret = MTK_DISABLE;
> + } else if (param == PIN_CONFIG_BIAS_PULL_UP) {
> + /* When desire to get pull-up value, return
> + * error if current setting is pull-down
> + */
> + if (!pullup)
> + err = -EINVAL;
> + } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) {
> + /* When desire to get pull-down value, return
> + * error if current setting is pull-up
> + */
> + if (pullup)
> + err = -EINVAL;
> + }
> + } else {
> err = -ENOTSUPP;
> + }
> break;
> case PIN_CONFIG_SLEW_RATE:
> err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
> @@ -196,20 +205,20 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
>
> switch ((u32)param) {
> case PIN_CONFIG_BIAS_DISABLE:
> - if (hw->soc->bias_disable_set)
> - err = hw->soc->bias_disable_set(hw, desc);
> + if (hw->soc->bias_set_combo)
> + err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
> else
> err = -ENOTSUPP;
> break;
> case PIN_CONFIG_BIAS_PULL_UP:
> - if (hw->soc->bias_set)
> - err = hw->soc->bias_set(hw, desc, 1);
> + if (hw->soc->bias_set_combo)
> + err = hw->soc->bias_set_combo(hw, desc, 1, arg);
> else
> err = -ENOTSUPP;
> break;
> case PIN_CONFIG_BIAS_PULL_DOWN:
> - if (hw->soc->bias_set)
> - err = hw->soc->bias_set(hw, desc, 0);
> + if (hw->soc->bias_set_combo)
> + err = hw->soc->bias_set_combo(hw, desc, 0, arg);
> else
> err = -ENOTSUPP;
> break;
> --
> 1.8.1.1.dirty
On Tue, Jan 21, 2020 at 10:53 PM <[email protected]> wrote:
>
> From: Light Hsieh <[email protected]>
>
> 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.
>
> Signed-off-by: Light Hsieh <[email protected]>
Acked-by: Sean Wang <[email protected]>
> ---
> drivers/pinctrl/mediatek/pinctrl-paris.c | 40 ++++++++++++--------------------
> 1 file changed, 15 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 2f07500..d09a726 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -78,7 +78,7 @@ 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) {
> @@ -107,17 +107,11 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
> 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)
> goto out;
> /* CONFIG Current direction return value
> @@ -128,20 +122,22 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
> * input 1 (= reverse HW value)
> */
> if (param == PIN_CONFIG_INPUT_ENABLE)
> - val = !val;
> + ret = !ret;
>
> break;
> case PIN_CONFIG_INPUT_SCHMITT_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;
> -
> - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2);
> - if (err)
> - return err;
> + goto out;
> + /* return error when in output mode
> + * because schmitt trigger only work in input mode
> + */
> + if (ret) {
> + err = -EINVAL;
> + goto out;
> + }
>
> - if (val || !val2)
> - return -EINVAL;
> + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
>
> break;
> case PIN_CONFIG_DRIVE_STRENGTH:
> @@ -154,13 +150,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
> case MTK_PIN_CONFIG_RDSEL:
> reg = (param == MTK_PIN_CONFIG_TDSEL) ?
> PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
> -
> - err = mtk_hw_get_value(hw, desc, reg, &val);
> - if (err)
> - return err;
> -
> - ret = val;
> -
> + err = mtk_hw_get_value(hw, desc, reg, &ret);
> break;
> case MTK_PIN_CONFIG_PU_ADV:
> case MTK_PIN_CONFIG_PD_ADV:
> --
> 1.8.1.1.dirty
On Tue, Jan 21, 2020 at 10:53 PM <[email protected]> wrote:
>
> From: Light Hsieh <[email protected]>
>
> 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 <[email protected]>
Acked-by: Sean Wang <[email protected]>
> ---
> drivers/pinctrl/mediatek/pinctrl-paris.c | 109 +++++++++++++++++++++++++++++++
> drivers/pinctrl/mediatek/pinctrl-paris.h | 3 +
> 2 files changed, 112 insertions(+)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 115ebc1..83bf29c 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -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 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..afb7650 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.h
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.h
> @@ -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 */
> --
> 1.8.1.1.dirty
On Wed, Jan 22, 2020 at 7:53 AM <[email protected]> wrote:
> From: Light Hsieh <[email protected]>
>
> 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. Improve mtk_hw_pin_field_lookup()
> 2.1 Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
> search.
> 2.2 Correct message after the following check fail:
> if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
> rc = &hw->soc->reg_cal[field];
> The original message is:
> "Not support field %d for pin %d (%s)\n"
> However, the check is on soc chip level, not on pin level yet.
> So the message is corrected as:
> "Not support field %d for this soc\n"
>
> Signed-off-by: Light Hsieh <[email protected]>
I managed to apply all 6 patches now for v5.7.
I had a big problem extracting the patches since they get base64
encoded and for some reason git am cannot deal with this. I thought
it would but it doesn't possibly because of custom headers in the
message.
I have to save out the base64 part of the message, decode separately,
then paste back the result removing the transfer-encoding line
of the original message.
cat mtk65.txt | base64 -d -i > scratch.patch
Any tips on how to handle this more efficiently?
Yours,
Linus Walleij