aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/mediatek
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/mediatek')
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mt6765.c11
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mt8183.c7
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c264
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h16
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common.c5
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-paris.c363
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-paris.h3
7 files changed, 513 insertions, 156 deletions
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index 32451e8693be..905dae8c3fd8 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1070,15 +1070,12 @@ static const struct mtk_pin_soc mt6765_data = {
.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,
- .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,
+ .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,
.adv_pull_set = mtk_pinconf_adv_pull_set,
};
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8183.c b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
index 9a74d5025be6..60318339b618 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8183.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
@@ -554,13 +554,10 @@ static const struct mtk_pin_soc mt8183_data = {
.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,
- .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 20e1c890e73b..d3169a87e1b3 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>
@@ -66,34 +67,44 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
int field, struct mtk_pin_field *pfd)
{
- const struct mtk_pin_field_calc *c, *e;
+ const struct mtk_pin_field_calc *c;
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;
}
- c = rc->range;
- e = c + rc->nranges;
+ end = rc->nranges - 1;
- 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 +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);
@@ -502,6 +516,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)
@@ -593,6 +827,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 1b7da42aa1d5..27df08736396 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);
@@ -288,6 +299,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);
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index 67f8444f7a0c..a02ad10ec6fa 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -804,7 +804,10 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
pctl->devdata->spec_dir_set(&reg_addr, offset);
regmap_read(pctl->regmap1, reg_addr, &read_val);
- return !(read_val & bit);
+ if (read_val & bit)
+ return GPIO_LINE_DIRECTION_OUT;
+
+ return GPIO_LINE_DIRECTION_IN;
}
static int mtk_gpio_get(struct gpio_chip *chip, unsigned offset)
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 923264d0e9ef..3853ec3a2a8e 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -78,93 +78,88 @@ 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 pullup, err, reg, ret = 1;
const struct mtk_pin_desc *desc;
+ 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) {
- err = hw->soc->bias_disable_get(hw, desc, &ret);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
- break;
case PIN_CONFIG_BIAS_PULL_UP:
- if (hw->soc->bias_get) {
- err = hw->soc->bias_get(hw, desc, 1, &ret);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
- break;
case PIN_CONFIG_BIAS_PULL_DOWN:
- if (hw->soc->bias_get) {
- err = hw->soc->bias_get(hw, desc, 0, &ret);
+ if (hw->soc->bias_get_combo) {
+ err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
if (err)
- return 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 {
- return -ENOTSUPP;
+ 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)
+ * input 0 (= HW value)
+ * INPUT_ENABLE output 0 (= reverse HW value)
+ * input 1 (= reverse HW value)
+ */
+ if (param == PIN_CONFIG_INPUT_ENABLE)
+ 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:
- 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:
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:
@@ -173,28 +168,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,
@@ -206,64 +197,55 @@ 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) {
case PIN_CONFIG_BIAS_DISABLE:
- if (hw->soc->bias_disable_set) {
- err = hw->soc->bias_disable_set(hw, desc);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ 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 (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ 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 (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ if (hw->soc->bias_set_combo)
+ err = hw->soc->bias_set_combo(hw, desc, 0, arg);
+ 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,
@@ -273,41 +255,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:
@@ -317,20 +287,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;
@@ -575,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 += scnprintf(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 += scnprintf(buf + len, bufLen - len, " (%1d %1d)\n",
+ r1, r0);
+ } else {
+ len += scnprintf(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)
@@ -677,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 = {
@@ -693,13 +766,19 @@ 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);
if (err)
return err;
- return !value;
+ if (value)
+ return GPIO_LINE_DIRECTION_OUT;
+
+ return GPIO_LINE_DIRECTION_IN;
}
static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
@@ -708,6 +787,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 +804,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 +814,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);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.h b/drivers/pinctrl/mediatek/pinctrl-paris.h
index 3d43771074e6..afb7650fd25b 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 */