The previous patch introduced constants to combine pinconfig settings
into one value for easier devicetree handling.

Therefore also add a function, that can separate these bitmaps into
regular generic pinconfig options for handling inside pinctrl drivers.

Signed-off-by: Heiko Stuebner <he...@sntech.de>
---
 .../bindings/pinctrl/pinctrl-bindings.txt          |    3 +
 drivers/pinctrl/pinconf-generic.c                  |   61 ++++++++++++++++++++
 drivers/pinctrl/pinconf.h                          |    6 ++
 3 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt 
b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
index d206da0..55141af 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
@@ -132,3 +132,6 @@ controller device.
 dt-bindings/pinctrl/pinconfig.h defines a set of constants to combine basic
 generic pinconfig settings, like pulls, into one value, that can be used
 in pinctrl bindings like <bank pin mux CONFIG>.
+
+This value can then be split into individual generic pinconfig values in the
+driver using pinconf_generic_parse_dt_bitmap.
diff --git a/drivers/pinctrl/pinconf-generic.c 
b/drivers/pinctrl/pinconf-generic.c
index 9a6812b..90896fe 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -139,3 +139,64 @@ void pinconf_generic_dump_config(struct pinctrl_dev 
*pctldev,
 }
 EXPORT_SYMBOL_GPL(pinconf_generic_dump_config);
 #endif
+
+/*
+ * Maps the devicetree config bits to actual pinconf values.
+ * The array indizes match the bits set in dt-bindings/pinctrl/pinconf.h
+ * and the array should contain an entry for each bit defined there
+ */
+static unsigned long conf_map[] = {
+       PIN_CONF_PACKED(PIN_CONFIG_BIAS_DISABLE, 0),
+       PIN_CONF_PACKED(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0),
+       PIN_CONF_PACKED(PIN_CONFIG_BIAS_BUS_HOLD, 0),
+       PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 0),
+       PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 0),
+       PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_DOWN, 0),
+       PIN_CONF_PACKED(PIN_CONFIG_DRIVE_PUSH_PULL, 0),
+       PIN_CONF_PACKED(PIN_CONFIG_DRIVE_OPEN_DRAIN, 0),
+       PIN_CONF_PACKED(PIN_CONFIG_DRIVE_OPEN_SOURCE, 0),
+       PIN_CONF_PACKED(PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1),
+       PIN_CONF_PACKED(PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0),
+       PIN_CONF_PACKED(PIN_CONFIG_LOW_POWER_MODE, 0),
+       PIN_CONF_PACKED(PIN_CONFIG_OUTPUT, 0),
+       PIN_CONF_PACKED(PIN_CONFIG_OUTPUT, 1),
+};
+
+/*
+ * Parse a pinconf bitmap from a devicetree entry into individual pin configs.
+ * @pinconf: the bitmap containing config bits
+ * @configs: after the function returns contains a pointer to an array of
+ *          pin configs
+ * @nconfigs: number of entries of configs
+ */
+int pinconf_generic_parse_dt_bitmap(unsigned long pinconf,
+                                   unsigned long **configs,
+                                   unsigned int *nconfigs)
+{
+       int bit;
+       int i;
+       unsigned long *cnf;
+       unsigned int ncnf;
+
+       ncnf = hweight_long(pinconf);
+       cnf = kzalloc(ncnf * sizeof(unsigned long), GFP_KERNEL);
+
+       i = 0;
+       while (pinconf && i < ncnf) {
+               bit = __ffs(pinconf);
+               pinconf &= ~BIT(i);
+
+               if (bit > ARRAY_SIZE(conf_map)) {
+                       pr_err("%s: unknown bit %d\n", __func__, bit);
+                       kfree(cnf);
+                       return -EINVAL;
+               }
+
+               cnf[i] = conf_map[bit];
+               i++;
+       }
+
+       *configs = cnf;
+       *nconfigs = ncnf;
+       return 0;
+}
diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h
index 92c7267..ae7480c 100644
--- a/drivers/pinctrl/pinconf.h
+++ b/drivers/pinctrl/pinconf.h
@@ -123,3 +123,9 @@ static inline void pinconf_generic_dump_config(struct 
pinctrl_dev *pctldev,
        return;
 }
 #endif
+
+#ifdef CONFIG_GENERIC_PINCONF
+int pinconf_generic_parse_dt_bitmap(unsigned long pinconf,
+                                   unsigned long **configs,
+                                   unsigned int *nconfigs);
+#endif
-- 
1.7.2.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to