aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>2019-05-20 11:02:07 +0530
committerManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>2019-05-20 11:02:07 +0530
commitc9b369fbd316062a0bdf4d8a2845751ed2bdc5f8 (patch)
tree9108468c2b89a76cf4a749a75f09fdc519790558
parent9ea244dab0e4590d9b1f4da21316f157a88f429b (diff)
pinctrl: Add pinconf support for BM1880 SoCbm1880-pinconf
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-rw-r--r--drivers/pinctrl/pinctrl-bm1880.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl-bm1880.c b/drivers/pinctrl/pinctrl-bm1880.c
index 9de170b6480d..351de3d36025 100644
--- a/drivers/pinctrl/pinctrl-bm1880.c
+++ b/drivers/pinctrl/pinctrl-bm1880.c
@@ -871,6 +871,139 @@ static int bm1880_pinmux_set_mux(struct pinctrl_dev *pctldev,
return 0;
}
+#define BM1880_PINCONF(pin, idx) ((!((pin + 1) & 1) << 4) + idx);
+#define BM1880_PINCONF_PULLCTRL(pin) BM1880_PINCONF(pin, 0)
+#define BM1880_PINCONF_PULLUP(pin) BM1880_PINCONF(pin, 1)
+#define BM1880_PINCONF_PULLDOWN(pin) BM1880_PINCONF(pin, 2)
+#define BM1880_PINCONF_SCHMITT(pin) BM1880_PINCONF(pin, 9)
+#define BM1880_PINCONF_SLEW(pin) BM1880_PINCONF(pin, 10)
+
+static int bm1880_pinconf_cfg_get(struct pinctrl_dev *pctldev,
+ unsigned int pin,
+ unsigned long *config)
+{
+ struct bm1880_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ unsigned int param = pinconf_to_config_param(*config);
+ unsigned int arg = 0;
+ u32 regval, offset, bit_offset;
+ int ret;
+
+ offset = (pin >> 1) << 2;
+ regval = readl_relaxed(pctrl->base + BM1880_REG_MUX + offset);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_PULL_UP:
+ bit_offset = BM1880_PINCONF_PULLUP(pin);
+ arg = !!(regval & BIT(bit_offset));
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ bit_offset = BM1880_PINCONF_PULLDOWN(pin);
+ arg = !!(regval & BIT(bit_offset));
+ break;
+ case PIN_CONFIG_BIAS_DISABLE:
+ bit_offset = BM1880_PINCONF_PULLCTRL(pin);
+ arg = !!(regval & BIT(bit_offset));
+ break;
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ bit_offset = BM1880_PINCONF_SCHMITT(pin);
+ arg = !!(regval & BIT(bit_offset));
+ break;
+ case PIN_CONFIG_SLEW_RATE:
+ bit_offset = BM1880_PINCONF_SLEW(pin);
+ arg = !!(regval & BIT(bit_offset));
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+
+ return 0;
+}
+
+static int bm1880_pinconf_cfg_set(struct pinctrl_dev *pctldev,
+ unsigned int pin,
+ unsigned long *configs,
+ unsigned int num_configs)
+{
+ struct bm1880_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ u32 regval, offset, bit_offset;
+ int i, ret;
+
+ offset = (pin >> 1) << 2;
+ regval = readl_relaxed(pctrl->base + BM1880_REG_MUX + offset);
+
+ for (i = 0; i < num_configs; i++) {
+ unsigned int param = pinconf_to_config_param(configs[i]);
+ unsigned int arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_PULL_UP:
+ bit_offset = BM1880_PINCONF_PULLUP(pin);
+ regval |= BIT(bit_offset);
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ bit_offset = BM1880_PINCONF_PULLDOWN(pin);
+ regval |= BIT(bit_offset);
+ break;
+ case PIN_CONFIG_BIAS_DISABLE:
+ bit_offset = BM1880_PINCONF_PULLCTRL(pin);
+ regval |= BIT(bit_offset);
+ break;
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ bit_offset = BM1880_PINCONF_SCHMITT(pin);
+ if (arg)
+ regval |= BIT(bit_offset);
+ else
+ regval &= ~BIT(bit_offset);
+ break;
+ case PIN_CONFIG_SLEW_RATE:
+ bit_offset = BM1880_PINCONF_SLEW(pin);
+ if (arg)
+ regval |= BIT(bit_offset);
+ else
+ regval &= ~BIT(bit_offset);
+ break;
+ default:
+ dev_warn(pctldev->dev,
+ "unsupported configuration parameter '%u'\n",
+ param);
+ continue;
+ }
+
+ writel(regval, pctrl->base + BM1880_REG_MUX + offset);
+ }
+
+
+ return 0;
+}
+
+static int bm1880_pinconf_group_set(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ unsigned long *configs,
+ unsigned int num_configs)
+{
+ int i, ret;
+ struct bm1880_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ const struct bm1880_pctrl_group *pgrp = &pctrl->groups[selector];
+
+ for (i = 0; i < pgrp->npins; i++) {
+ ret = bm1880_pinconf_cfg_set(pctldev, pgrp->pins[i], configs,
+ num_configs);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct pinconf_ops bm1880_pinconf_ops = {
+ .is_generic = true,
+ .pin_config_get = bm1880_pinconf_cfg_get,
+ .pin_config_set = bm1880_pinconf_cfg_set,
+ .pin_config_group_set = bm1880_pinconf_group_set,
+};
+
static const struct pinmux_ops bm1880_pinmux_ops = {
.get_functions_count = bm1880_pmux_get_functions_count,
.get_function_name = bm1880_pmux_get_function_name,
@@ -884,6 +1017,7 @@ static struct pinctrl_desc bm1880_desc = {
.npins = ARRAY_SIZE(bm1880_pins),
.pctlops = &bm1880_pctrl_ops,
.pmxops = &bm1880_pinmux_ops,
+ .confops = &bm1880_pinconf_ops,
.owner = THIS_MODULE,
};